diff options
author | Better Together Rust Devs <no-reply@google.com> | 2024-01-09 22:36:41 +0000 |
---|---|---|
committer | Maurice Lam <yukl@google.com> | 2024-01-09 22:50:41 +0000 |
commit | 45cc9975196e343faec1c131b490acb797af39d3 (patch) | |
tree | 130a48b0d282dd0c937e3a60bbc796ba57d12073 | |
parent | 446c795a7e4abd244689c36254ccac649663ba1f (diff) | |
download | beto-rust-45cc9975196e343faec1c131b490acb797af39d3.tar.gz |
Project import generated by Copybara.
GitOrigin-RevId: 5116cbcfd3d5b52276ad72a24b49f0405c517601
Change-Id: I29829ec1280d711b8cbbaf028e3cdfbc5edf09d9
81 files changed, 4301 insertions, 1594 deletions
diff --git a/nearby/Cargo.lock b/nearby/Cargo.lock index dd4f6ff..3a3934a 100644 --- a/nearby/Cargo.lock +++ b/nearby/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -97,58 +97,57 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.3.2" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "array_ref" @@ -159,17 +158,6 @@ name = "array_view" version = "0.1.0" [[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -183,15 +171,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - -[[package]] -name = "base64" -version = "0.21.2" +version = "0.21.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "c79fed4cdb43e993fcdadc7e58a09fd0e3e649c4436fa11da71c9f1f3ee7feb9" [[package]] name = "base64ct" @@ -207,9 +189,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "blake2" @@ -257,9 +239,9 @@ checksum = "312d12393c060384f2e6ed14c7b4be37b3dd90249857485613c1a91b9a1abb5c" [[package]] name = "bstr" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" dependencies = [ "memchr", "serde", @@ -271,7 +253,7 @@ version = "0.1.0" dependencies = [ "anyhow", "chrono", - "clap 4.3.19", + "clap", "cmd-runner", "crossbeam", "env_logger", @@ -291,21 +273,21 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[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.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cast" @@ -324,9 +306,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cesu8" @@ -342,14 +327,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "winapi", + "windows-targets 0.48.5", ] [[package]] @@ -391,65 +376,43 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "bitflags 1.3.2", - "clap_lex 0.2.4", - "indexmap", - "textwrap", -] - -[[package]] -name = "clap" -version = "4.3.19" +version = "4.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.19" +version = "4.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" dependencies = [ "anstream", "anstyle", - "clap_lex 0.5.0", + "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.3.12" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.48", ] [[package]] name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "clap_lex" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "cmd-runner" @@ -477,26 +440,22 @@ dependencies = [ ] [[package]] -name = "connections_adv" -version = "0.1.0" - -[[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", ] @@ -512,19 +471,19 @@ dependencies = [ [[package]] name = "criterion" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" dependencies = [ "anes", - "atty", "cast", "ciborium", - "clap 3.2.25", + "clap", "criterion-plot", + "is-terminal", "itertools", - "lazy_static", "num-traits", + "once_cell", "oorandom", "plotters", "rayon", @@ -548,11 +507,10 @@ dependencies = [ [[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", @@ -562,62 +520,52 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" 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 = "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", @@ -760,20 +708,20 @@ dependencies = [ [[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.28", + "syn 2.0.48", ] [[package]] name = "der" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -798,9 +746,9 @@ dependencies = [ [[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", @@ -808,15 +756,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core 0.6.4", "serde", "sha2", + "subtle", "zeroize", ] @@ -828,9 +777,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[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", @@ -847,9 +796,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ "humantime", "is-terminal", @@ -860,30 +809,19 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "ff" @@ -897,9 +835,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a481586acf778f1b1455424c343f71124b048ffa5f4fc3f8f6ae9dc432dcb3c7" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" [[package]] name = "file-header" @@ -916,21 +854,15 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" 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 = "foreign-types" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -958,9 +890,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -978,16 +910,22 @@ dependencies = [ ] [[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[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]] @@ -1024,11 +962,11 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hdrhistogram" -version = "7.5.2" +version = "7.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" dependencies = [ - "base64 0.13.1", + "base64", "byteorder", "crossbeam-channel", "flate2", @@ -1044,18 +982,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -1071,9 +1000,9 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[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", ] @@ -1088,6 +1017,15 @@ dependencies = [ ] [[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" @@ -1095,16 +1033,16 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -1138,13 +1076,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1158,9 +1096,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jni" @@ -1186,9 +1124,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -1208,9 +1146,9 @@ version = "0.1.0" dependencies = [ "aes", "anyhow", - "base64 0.21.2", + "base64", "blake2", - "clap 4.3.19", + "clap", "criterion", "crypto_provider", "crypto_provider_default", @@ -1235,7 +1173,7 @@ version = "0.1.0" dependencies = [ "anyhow", "array_view", - "base64 0.21.2", + "base64", "criterion", "crypto_provider", "crypto_provider_default", @@ -1275,9 +1213,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "license" @@ -1292,9 +1230,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lock_adapter" @@ -1305,9 +1243,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1315,24 +1253,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" 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 = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "minimal-lexical" @@ -1377,7 +1306,6 @@ dependencies = [ "np_hkdf", "rand", "rand_ext", - "rmp-serde", "serde", "serde_json", "sink", @@ -1421,6 +1349,7 @@ dependencies = [ "ldt_np_adv", "lock_adapter", "np_adv", + "np_adv_dynamic", "np_hkdf", ] @@ -1443,9 +1372,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -1464,28 +1393,18 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 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" @@ -1501,11 +1420,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "cfg-if", "foreign-types", "libc", @@ -1522,14 +1441,14 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.48", ] [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" dependencies = [ "bssl-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "cc", @@ -1539,12 +1458,6 @@ dependencies = [ ] [[package]] -name = "os_str_bytes" -version = "6.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" - -[[package]] name = "ouroboros" version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1565,7 +1478,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.48", ] [[package]] @@ -1585,12 +1498,6 @@ dependencies = [ ] [[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1602,15 +1509,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" [[package]] name = "platforms" -version = "3.0.2" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "plotters" @@ -1660,9 +1567,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[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", ] @@ -1693,9 +1600,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] @@ -1753,9 +1660,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1825,9 +1732,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1835,21 +1742,19 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] @@ -1884,6 +1789,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] +name = "relative-path" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" + +[[package]] name = "reword" version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1893,32 +1804,10 @@ dependencies = [ ] [[package]] -name = "rmp" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - -[[package]] -name = "rmp-serde" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a" -dependencies = [ - "byteorder", - "rmp", - "serde", -] - -[[package]] name = "rstest" -version = "0.17.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de1bb486a691878cd320c2f0d319ba91eeaa2e894066d8b5f8f117c000e9d962" +checksum = "97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199" dependencies = [ "rstest_macros", "rustc_version", @@ -1926,15 +1815,18 @@ dependencies = [ [[package]] name = "rstest_macros" -version = "0.17.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290ca1a1c8ca7edb7c3283bd44dc35dd54fdec6253a3912e201ba1072018fca8" +checksum = "d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605" dependencies = [ "cfg-if", + "glob", "proc-macro2", "quote", + "regex", + "relative-path", "rustc_version", - "syn 1.0.109", + "syn 2.0.48", "unicode-ident", ] @@ -1947,7 +1839,7 @@ dependencies = [ "quote", "rand", "rustc_version", - "syn 2.0.28", + "syn 2.0.48", ] [[package]] @@ -1961,15 +1853,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1980,9 +1872,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -2014,35 +1906,35 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.192" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -2051,9 +1943,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -2068,9 +1960,12 @@ checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" [[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 0.6.4", +] [[package]] name = "sink" @@ -2096,9 +1991,9 @@ dependencies = [ [[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", @@ -2132,7 +2027,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.28", + "syn 2.0.48", ] [[package]] @@ -2148,15 +2043,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", - "quote", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.28" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -2165,22 +2059,22 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", "fastrand", "redox_syscall", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" dependencies = [ "winapi-util", ] @@ -2194,29 +2088,23 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - -[[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.48", ] [[package]] @@ -2237,9 +2125,9 @@ checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" [[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" @@ -2313,7 +2201,7 @@ dependencies = [ name = "ukey2_shell" version = "0.1.0" dependencies = [ - "clap 4.3.19", + "clap", "crypto_provider_rustcrypto", "ukey2_connections", "ukey2_rs", @@ -2321,9 +2209,9 @@ dependencies = [ [[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" @@ -2361,9 +2249,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -2377,9 +2265,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2387,24 +2275,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2412,28 +2300,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -2441,13 +2329,14 @@ dependencies = [ [[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]] @@ -2468,9 +2357,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -2482,12 +2371,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" 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.0", ] [[package]] @@ -2501,11 +2390,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.52.0", ] [[package]] @@ -2525,17 +2414,32 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 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", + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -2546,9 +2450,15 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" [[package]] name = "windows_aarch64_msvc" @@ -2558,9 +2468,15 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" [[package]] name = "windows_i686_gnu" @@ -2570,9 +2486,15 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" [[package]] name = "windows_i686_msvc" @@ -2582,9 +2504,15 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" [[package]] name = "windows_x86_64_gnu" @@ -2594,9 +2522,15 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" [[package]] name = "windows_x86_64_gnullvm" @@ -2606,9 +2540,15 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" [[package]] name = "windows_x86_64_msvc" @@ -2618,9 +2558,15 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "wycheproof" @@ -2628,7 +2574,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e639f57253b80c6584b378011aec0fed61c4c21d7a4b97c4d9d7eaf35ca77d12" dependencies = [ - "base64 0.21.2", + "base64", "hex", "serde", "serde_json", @@ -2661,7 +2607,7 @@ dependencies = [ "aes", "anyhow", "array_ref", - "base64 0.21.2", + "base64", "crypto_provider", "crypto_provider_default", "hex", @@ -2677,6 +2623,6 @@ dependencies = [ [[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/Cargo.toml b/nearby/Cargo.toml index 8cd01cc..236b74f 100644 --- a/nearby/Cargo.toml +++ b/nearby/Cargo.toml @@ -1,6 +1,5 @@ [workspace] members = [ - "connections/connections_adv/connections_adv", "connections/ukey2/ukey2", "connections/ukey2/ukey2_connections", "connections/ukey2/ukey2_c_ffi", @@ -89,54 +88,54 @@ sink = { path = "presence/sink" } rand = { version = "0.8.5", default-features = false } rand_core = { version = "0.6.4", features = ["getrandom"] } rand_pcg = "0.3.1" -sha2 = { version = "0.10.6", default-features = false } -aes = "0.8.2" +sha2 = { version = "0.10.8", default-features = false } +aes = "0.8.3" cbc = { version = "0.1.2", features = ["block-padding"] } -ctr = "0.9.1" +ctr = "0.9.2" hkdf = "0.12.3" hmac = "0.12.1" -ed25519-dalek = { version = "2.0.0", default-features = false } -ed25519 = "2.2.0" +ed25519-dalek = { version = "2.1.0", default-features = false } +ed25519 = "2.2.3" aes-gcm = "0.10.3" hex = "0.4.3" -serde = { version = "1.0.189" } -serde_json = { version = "1.0.96", features = [ +serde = { version = "1.0.193" } +serde_json = { version = "1.0.108", features = [ "alloc", ], default-features = false } -base64 = "0.21.0" +base64 = "0.21.5" x25519-dalek = { version = "2.0.0", default-features = false } subtle = { version = "2.5.0", default-features = false } rand_chacha = { version = "0.3.1", default-features = false } p256 = { version = "0.13.2", default-features = false } -sec1 = "0.7.2" -protobuf = "3.2.0" -protobuf-codegen = "3.2.0" -reqwest = { version = "0.11.19", default-features = false, features = ["blocking", "rustls-tls"] } +sec1 = "0.7.3" +protobuf = "=3.2.0" +protobuf-codegen = "=3.2.0" +reqwest = { version = "0.11.22", default-features = false, features = ["blocking", "rustls-tls"] } jni = "0.20.0" lock_api = "0.4.11" spin = { version = "0.9.8", features = ["once", "lock_api", "rwlock"] } -anyhow = "1.0.64" -log = "0.4.17" -env_logger = "0.10.0" -criterion = { version = "0.4.0", features = ["html_reports"] } -clap = { version = "4.0.25", features = ["derive"] } +anyhow = "1.0.75" +log = "0.4.20" +env_logger = "0.10.1" +criterion = { version = "0.5.1", features = ["html_reports"] } +clap = { version = "4.4.11", features = ["derive"] } lazy_static = { version = "1.4.0", features = ["spin_no_std"] } hex-literal = "0.4.1" -openssl = "0.10.48" +openssl = "0.10.61" cfg-if = "1.0.0" -blake2 = "0.10.4" -hdrhistogram = "7.5.0" -regex = "1.7.0" -tokio = { version = "1.32.0", features = ["full"] } +blake2 = "0.10.6" +hdrhistogram = "7.5.4" +regex = "1.10.2" +tokio = { version = "1.35.0", features = ["full"] } xts-mode = "0.5.1" -rstest = { version = "0.17.0", default-features = false } +rstest = { version = "0.18.2", default-features = false } rstest_reuse = "0.6.0" wycheproof = "0.5.1" -chrono = { version = "0.4.26", default-features = false, features = ["clock"] } -tempfile = "3.5.0" -thiserror = "1.0.40" +chrono = { version = "0.4.31", default-features = false, features = ["clock"] } +tempfile = "3.8.1" +thiserror = "1.0.51" tinyvec = { version = "1.6.0", features = ["rustc_1_55"] } -mlua = "0.8.8" +mlua = "0.9.2" strum = { version = "0.25.0", default-features=false } strum_macros = { version = "0.25.3", default-features=false } owo-colors = "3.5.0" diff --git a/nearby/connections/connections_adv/connections_adv/Cargo.toml b/nearby/connections/connections_adv/connections_adv/Cargo.toml deleted file mode 100644 index 2b0710d..0000000 --- a/nearby/connections/connections_adv/connections_adv/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "connections_adv" -version.workspace = true -edition.workspace = true -publish.workspace = true - -[lints] -workspace = true
\ No newline at end of file diff --git a/nearby/connections/connections_adv/connections_adv/src/lib.rs b/nearby/connections/connections_adv/connections_adv/src/lib.rs deleted file mode 100644 index 4cfcdfa..0000000 --- a/nearby/connections/connections_adv/connections_adv/src/lib.rs +++ /dev/null @@ -1,31 +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. - -//! Placeholder crate for connections advertisements - -/// placeholder -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/nearby/connections/ukey2/ukey2/Cargo.toml b/nearby/connections/ukey2/ukey2/Cargo.toml index 161c5b4..2ac6f3a 100644 --- a/nearby/connections/ukey2/ukey2/Cargo.toml +++ b/nearby/connections/ukey2/ukey2/Cargo.toml @@ -19,7 +19,7 @@ rand.workspace = true ukey2_proto.workspace = true log.workspace = true -num-bigint = "0.4.3" +num-bigint = "0.4.4" [dev-dependencies] rand = { workspace = true, features = ["std_rng", "getrandom"] } diff --git a/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt b/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt index 165d861..a8b7b9d 100644 --- a/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt +++ b/nearby/connections/ukey2/ukey2_c_ffi/cpp/CMakeLists.txt @@ -21,7 +21,9 @@ 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) ExternalProject_Add( ukey2_c_ffi @@ -35,11 +37,9 @@ ExternalProject_Add( set(CMAKE_CXX_STANDARD 20) if(UNIX) - add_compile_options(-Wall -Werror -Wextra -Wimplicit-fallthrough -Wextra-semi + add_compile_options(-Wall -Wextra -Wimplicit-fallthrough -Wextra-semi -Wno-missing-field-initializers -Wno-unused-parameter -Wno-psabi - -Wno-unneeded-internal-declaration - -Wno-ignored-pragma-optimize - -Wno-bitfield-constant-conversion -Wno-deprecated-this-capture -Wshadow + -Wshadow -Wsign-compare) elseif(MSVC) add_compile_options(-W4 -MD) @@ -83,5 +83,4 @@ elseif(MSVC) ) endif() -include(GoogleTest) gtest_discover_tests(ffi_test) diff --git a/nearby/connections/ukey2/ukey2_connections/Cargo.toml b/nearby/connections/ukey2/ukey2_connections/Cargo.toml index e7884c4..b1c34a1 100644 --- a/nearby/connections/ukey2/ukey2_connections/Cargo.toml +++ b/nearby/connections/ukey2/ukey2_connections/Cargo.toml @@ -19,8 +19,8 @@ ukey2_rs = { path = "../ukey2" } crypto_provider.workspace = true rand = { workspace = true, features = ["std", "std_rng"] } ukey2_proto.workspace = true -nom = { version = "7.1.1", features = ["alloc"] } -bytes = "1.2.1" +nom = { version = "7.1.3", features = ["alloc"] } +bytes = "1.5.0" criterion.workspace = true [dev-dependencies] diff --git a/nearby/connections/ukey2/ukey2_connections/fuzz/Cargo.lock b/nearby/connections/ukey2/ukey2_connections/fuzz/Cargo.lock index 3f72ae0..167e0de 100644 --- a/nearby/connections/ukey2/ukey2_connections/fuzz/Cargo.lock +++ b/nearby/connections/ukey2/ukey2_connections/fuzz/Cargo.lock @@ -69,6 +69,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] name = "anyhow" version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -84,17 +90,6 @@ dependencies = [ ] [[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -113,6 +108,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -138,9 +139,9 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cast" @@ -211,26 +212,30 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.25" +version = "4.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" dependencies = [ - "bitflags", - "clap_lex", - "indexmap", - "textwrap", + "clap_builder", ] [[package]] -name = "clap_lex" -version = "0.2.4" +name = "clap_builder" +version = "4.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" dependencies = [ - "os_str_bytes", + "anstyle", + "clap_lex", ] [[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] name = "const-oid" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -247,19 +252,19 @@ dependencies = [ [[package]] name = "criterion" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" dependencies = [ "anes", - "atty", "cast", "ciborium", "clap", "criterion-plot", + "is-terminal", "itertools", - "lazy_static", "num-traits", + "once_cell", "oorandom", "plotters", "rayon", @@ -412,7 +417,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", ] [[package]] @@ -426,17 +431,6 @@ dependencies = [ ] [[package]] -name = "derive-getters" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0122f262bf9c9a367829da84f808d9fb128c10ef283bbe7b0922a77cf07b2747" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] name = "derive_arbitrary" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -444,7 +438,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", ] [[package]] @@ -469,14 +463,15 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "sha2", + "subtle", ] [[package]] @@ -512,7 +507,7 @@ checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -607,15 +602,6 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" @@ -673,9 +659,20 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +dependencies = [ + "hermit-abi", + "rustix 0.38.13", + "windows-sys 0.52.0", ] [[package]] @@ -712,12 +709,6 @@ dependencies = [ ] [[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] name = "libc" version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -741,10 +732,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + +[[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" @@ -779,9 +776,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -800,9 +797,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -813,7 +810,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi", "libc", ] @@ -836,12 +833,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "os_str_bytes" -version = "6.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" - -[[package]] name = "p256" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1039,7 +1030,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1086,12 +1077,25 @@ version = "0.37.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys 0.4.12", + "windows-sys 0.48.0", ] [[package]] @@ -1151,7 +1155,7 @@ checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", ] [[package]] @@ -1167,9 +1171,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -1190,17 +1194,6 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" @@ -1220,17 +1213,11 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall", - "rustix", - "windows-sys", + "rustix 0.37.23", + "windows-sys 0.48.0", ] [[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - -[[package]] name = "thiserror" version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1247,7 +1234,7 @@ checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", ] [[package]] @@ -1310,7 +1297,6 @@ name = "ukey2_rs" version = "0.1.0" dependencies = [ "crypto_provider", - "derive-getters", "log", "num-bigint", "rand", @@ -1376,7 +1362,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.26", + "syn", "wasm-bindgen-shared", ] @@ -1398,7 +1384,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1467,7 +1453,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "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.0", ] [[package]] @@ -1476,13 +1471,28 @@ version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -1492,42 +1502,84 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] name = "windows_x86_64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] name = "x25519-dalek" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/nearby/connections/ukey2/ukey2_jni/java/build.gradle.kts b/nearby/connections/ukey2/ukey2_jni/java/build.gradle.kts index 58c58fc..78b0ebc 100644 --- a/nearby/connections/ukey2/ukey2_jni/java/build.gradle.kts +++ b/nearby/connections/ukey2/ukey2_jni/java/build.gradle.kts @@ -44,6 +44,7 @@ dependencies { implementation("com.google.code.findbugs:jsr305:3.0.2") implementation(kotlin("stdlib")) testImplementation("org.junit.jupiter:junit-jupiter:5.9.2") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2") } kotlin { @@ -51,10 +52,10 @@ kotlin { } tasks.jmh { - jvmArgs.value(mutableListOf("-Djava.library.path=../../../../target/release")) + jvmArgs.value(mutableListOf("-Djava.library.path=$projectDir/../../../../target/release")) } tasks.test { useJUnitPlatform() - jvmArgs = mutableListOf("-Djava.library.path=../../../../target/debug") + jvmArgs = mutableListOf("-Djava.library.path=$projectDir/../../../../target/debug") } diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/jmh/java/com/google/security/cryptauth/lib/securegcm/Ukey2Benchmark.java b/nearby/connections/ukey2/ukey2_jni/java/src/jmh/java/com/google/security/cryptauth/lib/securegcm/Ukey2Benchmark.java deleted file mode 100644 index eb063cc..0000000 --- a/nearby/connections/ukey2/ukey2_jni/java/src/jmh/java/com/google/security/cryptauth/lib/securegcm/Ukey2Benchmark.java +++ /dev/null @@ -1,83 +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. - */ - -package com.google.security.cryptauth.lib.securegcm; - -import org.openjdk.jmh.annotations.*; -import org.openjdk.jmh.infra.Blackhole; -import org.openjdk.jmh.profile.GCProfiler; -import org.openjdk.jmh.runner.Runner; -import org.openjdk.jmh.runner.RunnerException; -import org.openjdk.jmh.runner.options.Options; -import org.openjdk.jmh.runner.options.OptionsBuilder; - -import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.util.concurrent.TimeUnit; -import java.util.Random; - -/** - * Benchmark for encoding and decoding UKEY2 messages over the JNI, analogous to - * `ukey2_benches.rs`. The parameters and the operations also roughly matches the that of the Rust - * Criterion benchmark. That said, since the benchmark infrastructure is different, there will - * inevitably be differences the skews the number in certain ways – comparison of numbers from the - * different benchmarks should compared on order-of-magnitudes only. To get the JNI overhead, for - * example, it would be better use this JMH infra to measure a call into a no-op Rust function, - * which is a more apples-to-apples comparison. - * - * To run this benchmark, run - * cargo build -p ukey2_jni --release && ./gradlew jmh - */ -@State(Scope.Benchmark) -@OutputTimeUnit(TimeUnit.SECONDS) -@BenchmarkMode(Mode.Throughput) -public class Ukey2Benchmark { - - @State(Scope.Thread) - public static class ConnectionState { - D2DConnectionContextV1 connContext; - D2DConnectionContextV1 serverConnContext; - @Param({"10", "1024"}) - int sizeKibs; - byte[] inputBytes; - - @Setup - public void setup() throws Exception { - D2DHandshakeContext initiatorContext = - new D2DHandshakeContext(D2DHandshakeContext.Role.Initiator); - D2DHandshakeContext serverContext = - new D2DHandshakeContext(D2DHandshakeContext.Role.Responder); - serverContext.parseHandshakeMessage(initiatorContext.getNextHandshakeMessage()); - initiatorContext.parseHandshakeMessage(serverContext.getNextHandshakeMessage()); - serverContext.parseHandshakeMessage(initiatorContext.getNextHandshakeMessage()); - connContext = initiatorContext.toConnectionContext(); - serverConnContext = serverContext.toConnectionContext(); - Random random = new Random(); - inputBytes = new byte[sizeKibs * 1024]; - random.nextBytes(inputBytes); - } - } - - @Benchmark - @Fork(3) - @Warmup(iterations = 2, time = 500, timeUnit = TimeUnit.MILLISECONDS) - @Measurement(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) - public void encodeAndDecode(ConnectionState state, Blackhole blackhole) throws Exception { - byte[] encoded = state.connContext.encodeMessageToPeer(state.inputBytes, null); - byte[] decoded = state.serverConnContext.decodeMessageFromPeer(encoded, null); - blackhole.consume(decoded); - } -} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/jmh/java/com/google/security/cryptauth/lib/securegcm/ukey2/Ukey2Benchmark.java b/nearby/connections/ukey2/ukey2_jni/java/src/jmh/java/com/google/security/cryptauth/lib/securegcm/ukey2/Ukey2Benchmark.java new file mode 100644 index 0000000..9cca229 --- /dev/null +++ b/nearby/connections/ukey2/ukey2_jni/java/src/jmh/java/com/google/security/cryptauth/lib/securegcm/ukey2/Ukey2Benchmark.java @@ -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. + */ + +package com.google.security.cryptauth.lib.securegcm.ukey2; + +import com.google.security.cryptauth.lib.securegcm.ukey2.D2DHandshakeContext.Role; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; + +import java.util.concurrent.TimeUnit; +import java.util.Random; + +/** + * Benchmark for encoding and decoding UKEY2 messages over the JNI, analogous to `ukey2_benches.rs`. + * The parameters and the operations also roughly matches the that of the Rust Criterion benchmark. + * That said, since the benchmark infrastructure is different, there will inevitably be differences + * the skews the number in certain ways – comparison of numbers from the different benchmarks should + * compared on order-of-magnitudes only. To get the JNI overhead, for example, it would be better + * use this JMH infra to measure a call into a no-op Rust function, which is a more apples-to-apples + * comparison. + * + * <p>To run this benchmark, run cargo build -p ukey2_jni --release && ./gradlew jmh + */ +@State(Scope.Benchmark) +@OutputTimeUnit(TimeUnit.SECONDS) +@BenchmarkMode(Mode.Throughput) +public class Ukey2Benchmark { + + @State(Scope.Thread) + public static class ConnectionState { + D2DConnectionContextV1 connContext; + D2DConnectionContextV1 serverConnContext; + + @Param({"10", "1024"}) + int sizeKibs; + + byte[] inputBytes; + + @Setup + public void setup() throws Exception { + D2DHandshakeContext initiatorContext = + new D2DHandshakeContext(Role.INITIATOR); + D2DHandshakeContext serverContext = + new D2DHandshakeContext(Role.RESPONDER); + serverContext.parseHandshakeMessage(initiatorContext.getNextHandshakeMessage()); + initiatorContext.parseHandshakeMessage(serverContext.getNextHandshakeMessage()); + serverContext.parseHandshakeMessage(initiatorContext.getNextHandshakeMessage()); + connContext = initiatorContext.toConnectionContext(); + serverConnContext = serverContext.toConnectionContext(); + Random random = new Random(); + inputBytes = new byte[sizeKibs * 1024]; + random.nextBytes(inputBytes); + } + } + + @Benchmark + @Fork(3) + @Warmup(iterations = 2, time = 500, timeUnit = TimeUnit.MILLISECONDS) + @Measurement(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) + public void encodeAndDecode(ConnectionState state, Blackhole blackhole) throws Exception { + byte[] encoded = state.connContext.encodeMessageToPeer(state.inputBytes, null); + byte[] decoded = state.serverConnContext.decodeMessageFromPeer(encoded, null); + blackhole.consume(decoded); + } +} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/D2DConnectionContextV1.java b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/D2DConnectionContextV1.java deleted file mode 100644 index 7874cd9..0000000 --- a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/D2DConnectionContextV1.java +++ /dev/null @@ -1,123 +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. - */ - -package com.google.security.cryptauth.lib.securegcm; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class D2DConnectionContextV1 { - - static { - System.loadLibrary("ukey2_jni"); - } - - private static native byte[] encode_message_to_peer(long contextPtr, byte[] payload, byte[] associatedData) throws BadHandleException; - - private static native byte[] decode_message_from_peer(long contextPtr, byte[] message, byte[] associatedData) throws CryptoException; - - private static native byte[] get_session_unique(long contextPtr) throws BadHandleException; - - private static native int get_sequence_number_for_encoding(long contextPtr) throws BadHandleException; - - private static native int get_sequence_number_for_decoding(long contextPtr) throws BadHandleException; - - private static native byte[] save_session(long contextPtr) throws BadHandleException; - - private static native long from_saved_session(byte[] savedSessionInfo); - - private final long contextPtr; - - /** - * Java wrapper for D2DConnectionContextV1 to interact with the underlying Rust implementation - * - * @param contextPtr the handle to the Rust implementation. - */ - D2DConnectionContextV1(@Nonnull long contextPtr) { - this.contextPtr = contextPtr; - } - - /** - * Encode a message to the connection peer using session keys derived from the handshake. - * - * @param payload The message to be encrypted. - * @return The encrypted/encoded message. - */ - @Nonnull - public byte[] encodeMessageToPeer(@Nonnull byte[] payload, @Nullable byte[] associatedData) throws BadHandleException { - return encode_message_to_peer(contextPtr, payload, associatedData); - } - - /** - * Decodes/decrypts a message from the connection peer. - * - * @param message The message received over the connection. - * @return The decoded message from the connection peer. - */ - @Nonnull - public byte[] decodeMessageFromPeer(@Nonnull byte[] message, @Nullable byte[] associatedData) throws CryptoException { - return decode_message_from_peer(contextPtr, message, associatedData); - } - - /** - * A unique session identifier derived from session-specific information - * - * @return The session unique identifier - */ - @Nonnull - public byte[] getSessionUnique() throws BadHandleException { - return get_session_unique(contextPtr); - } - - /** - * Returns the encoding sequence number. - * - * @return the encoding sequence number. - */ - public int getSequenceNumberForEncoding() throws BadHandleException { - return get_sequence_number_for_encoding(contextPtr); - } - - /** - * Returns the decoding sequence number. - * - * @return the decoding sequence number. - */ - public int getSequenceNumberForDecoding() throws BadHandleException { - return get_sequence_number_for_decoding(contextPtr); - } - - /** - * Serializes the current session in a form usable by {@link D2DConnectionContextV1#fromSavedSession} - * - * @return a byte array representing the current session. - */ - @Nonnull - public byte[] saveSession() throws BadHandleException { - return save_session(contextPtr); - } - - /** - * Reconstructs and returns the session originally serialized by {@link D2DConnectionContextV1#saveSession} - * - * @param savedSessionInfo the byte array from saveSession() - * @return a D2DConnectionContextV1 session with the same properties as the context saved. - */ - public static D2DConnectionContextV1 fromSavedSession(@Nonnull byte[] savedSessionInfo) { - return new D2DConnectionContextV1(from_saved_session(savedSessionInfo)); - } - -} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/D2DHandshakeContext.java b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/D2DHandshakeContext.java deleted file mode 100644 index 39f7aa9..0000000 --- a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/D2DHandshakeContext.java +++ /dev/null @@ -1,122 +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. - */ - -package com.google.security.cryptauth.lib.securegcm; - -import javax.annotation.Nonnull; - -public class D2DHandshakeContext { - static { - System.loadLibrary("ukey2_jni"); - } - - public enum Role { - INITIATOR, - RESPONDER, - } - - private final long contextPtr; - - private static native boolean is_handshake_complete(long contextPtr) throws BadHandleException; - - private static native long create_context(boolean isClient); - - private static native byte[] get_next_handshake_message(long contextPtr) throws BadHandleException; - - private static native void parse_handshake_message(long contextPtr, byte[] message) throws BadHandleException, HandshakeException; - - private static native byte[] get_verification_string(long contextPtr, int length) throws BadHandleException, HandshakeException; - - private static native long to_connection_context(long contextPtr) throws HandshakeException; - - public D2DHandshakeContext(@Nonnull Role role) { - this.contextPtr = create_context(role == Role.INITIATOR); - } - - /** - * Convenience constructor that creates a UKEY2 D2DHandshakeContext for the initiator role. - * - * @return a D2DHandshakeContext for the role of initiator in the handshake. - */ - public static D2DHandshakeContext forInitiator() { - return new D2DHandshakeContext(Role.INITIATOR); - } - - /** - * Convenience constructor that creates a UKEY2 D2DHandshakeContext for the initiator role. - * - * @return a D2DHandshakeContext for the role of responder/server in the handshake. - */ - public static D2DHandshakeContext forResponder() { - return new D2DHandshakeContext(Role.RESPONDER); - } - - /** - * Function that checks if the handshake is completed. - * - * @return true/false depending on if the handshake is complete. - */ - public boolean isHandshakeComplete() throws BadHandleException { - return is_handshake_complete(contextPtr); - } - - /** - * Gets the next handshake message in the exchange. - * - * @return handshake message encoded in a SecureMessage. - */ - @Nonnull - public byte[] getNextHandshakeMessage() throws BadHandleException { - return get_next_handshake_message(contextPtr); - } - - /** - * Parses the handshake message. - * - * @param message - handshake message from the other side. - */ - @Nonnull - public void parseHandshakeMessage(@Nonnull byte[] message) throws BadHandleException, HandshakeException { - parse_handshake_message(contextPtr, message); - } - - /** - * Returns an authentication string suitable for authenticating the handshake out-of-band. Note - * that the authentication string can be short (e.g., a 6 digit visual confirmation code). Note: - * this should only be called when {#isHandshakeComplete} returns true. - * This code is analogous to the authentication string described in the spec. - * - * @param length - The length of the returned verification string. - * @return - The returned verification string as a byte array. - * @throws BadHandleException - Thrown if the handle is no longer valid, for example after calling {@link D2DHandshakeContext#toConnectionContext} - * @throws HandshakeException - Thrown if the handshake is not complete when this function is called. - */ - @Nonnull - public byte[] getVerificationString(int length) throws BadHandleException, HandshakeException { - return get_verification_string(contextPtr, length); - } - - /** - * Function to create a secure communication channel from the handshake after confirming the auth string generated by - * the handshake out-of-band (i.e. via a user-facing UI). - * - * @return a new {@link D2DConnectionContextV1} with the next protocol specified when creating the D2DHandshakeContext. - * @throws HandshakeException if the handsshake is not complete when this function is called. - */ - public D2DConnectionContextV1 toConnectionContext() throws HandshakeException { - return new D2DConnectionContextV1(to_connection_context(contextPtr)); - } -} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/BadHandleException.java b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException.java index 2efd7c4..78f0e5e 100644 --- a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/BadHandleException.java +++ b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException.java @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.security.cryptauth.lib.securegcm; +package com.google.security.cryptauth.lib.securegcm.ukey2; /** - * Represents an unrecoverable error (invalid handle) that has occurred during the handshake/connection. + * Represents an unrecoverable error (invalid handle) that has occurred during the + * handshake/connection. */ public class BadHandleException extends Exception { public BadHandleException(String message) { @@ -29,4 +30,4 @@ public class BadHandleException extends Exception { public BadHandleException(String message, Exception e) { super(message, e); } -}
\ No newline at end of file +} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/CryptoException.java b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/CryptoException.java index 6abeb53..11b5c9b 100644 --- a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/CryptoException.java +++ b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/CryptoException.java @@ -12,11 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.security.cryptauth.lib.securegcm; +package com.google.security.cryptauth.lib.securegcm.ukey2; -/** - * Represents an unrecoverable error that has occurred during the handshake procedure. - */ +/** Represents an unrecoverable error that has occurred during the handshake procedure. */ public class CryptoException extends Exception { public CryptoException(String message) { super(message); @@ -29,4 +27,4 @@ public class CryptoException extends Exception { public CryptoException(String message, Exception e) { super(message, e); } -}
\ No newline at end of file +} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/D2DConnectionContextV1.java b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/D2DConnectionContextV1.java new file mode 100644 index 0000000..9ce2517 --- /dev/null +++ b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/D2DConnectionContextV1.java @@ -0,0 +1,139 @@ +/* + * 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.security.cryptauth.lib.securegcm.ukey2; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class D2DConnectionContextV1 { + + static { + var path = System.getProperty("java.library.path"); + + if (path == null) { + throw new RuntimeException("Path isn't set."); + } + + var paths = java.util.List.of(path.split(";")); + paths.forEach(System.out::println); + + System.loadLibrary("ukey2_jni"); + } + + private static native byte[] encode_message_to_peer( + long contextPtr, byte[] payload, byte[] associatedData) throws BadHandleException; + + private static native byte[] decode_message_from_peer( + long contextPtr, byte[] message, byte[] associatedData) throws CryptoException; + + private static native byte[] get_session_unique(long contextPtr) throws BadHandleException; + + private static native int get_sequence_number_for_encoding(long contextPtr) + throws BadHandleException; + + private static native int get_sequence_number_for_decoding(long contextPtr) + throws BadHandleException; + + private static native byte[] save_session(long contextPtr) throws BadHandleException; + + private static native long from_saved_session(byte[] savedSessionInfo); + + private final long contextPtr; + + /** + * Java wrapper for D2DConnectionContextV1 to interact with the underlying Rust implementation + * + * @param contextPtr the handle to the Rust implementation. + */ + D2DConnectionContextV1(@Nonnull long contextPtr) { + this.contextPtr = contextPtr; + } + + /** + * Encode a message to the connection peer using session keys derived from the handshake. + * + * @param payload The message to be encrypted. + * @return The encrypted/encoded message. + */ + @Nonnull + public byte[] encodeMessageToPeer(@Nonnull byte[] payload, @Nullable byte[] associatedData) + throws BadHandleException { + return encode_message_to_peer(contextPtr, payload, associatedData); + } + + /** + * Decodes/decrypts a message from the connection peer. + * + * @param message The message received over the connection. + * @return The decoded message from the connection peer. + */ + @Nonnull + public byte[] decodeMessageFromPeer(@Nonnull byte[] message, @Nullable byte[] associatedData) + throws CryptoException { + return decode_message_from_peer(contextPtr, message, associatedData); + } + + /** + * A unique session identifier derived from session-specific information + * + * @return The session unique identifier + */ + @Nonnull + public byte[] getSessionUnique() throws BadHandleException { + return get_session_unique(contextPtr); + } + + /** + * Returns the encoding sequence number. + * + * @return the encoding sequence number. + */ + public int getSequenceNumberForEncoding() throws BadHandleException { + return get_sequence_number_for_encoding(contextPtr); + } + + /** + * Returns the decoding sequence number. + * + * @return the decoding sequence number. + */ + public int getSequenceNumberForDecoding() throws BadHandleException { + return get_sequence_number_for_decoding(contextPtr); + } + + /** + * Serializes the current session in a form usable by {@link + * D2DConnectionContextV1#fromSavedSession} + * + * @return a byte array representing the current session. + */ + @Nonnull + public byte[] saveSession() throws BadHandleException { + return save_session(contextPtr); + } + + /** + * Reconstructs and returns the session originally serialized by {@link + * D2DConnectionContextV1#saveSession} + * + * @param savedSessionInfo the byte array from saveSession() + * @return a D2DConnectionContextV1 session with the same properties as the context saved. + */ + public static D2DConnectionContextV1 fromSavedSession(@Nonnull byte[] savedSessionInfo) { + return new D2DConnectionContextV1(from_saved_session(savedSessionInfo)); + } +} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/D2DHandshakeContext.java b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/D2DHandshakeContext.java new file mode 100644 index 0000000..429295e --- /dev/null +++ b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/D2DHandshakeContext.java @@ -0,0 +1,129 @@ +/* + * 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.security.cryptauth.lib.securegcm.ukey2; + +import javax.annotation.Nonnull; + +public class D2DHandshakeContext { + static { + System.loadLibrary("ukey2_jni"); + } + + public enum Role { + INITIATOR, + RESPONDER, + } + + private final long contextPtr; + + private static native boolean is_handshake_complete(long contextPtr) throws BadHandleException; + + private static native long create_context(boolean isClient); + + private static native byte[] get_next_handshake_message(long contextPtr) + throws BadHandleException; + + private static native void parse_handshake_message(long contextPtr, byte[] message) + throws BadHandleException, HandshakeException; + + private static native byte[] get_verification_string(long contextPtr, int length) + throws BadHandleException, HandshakeException; + + private static native long to_connection_context(long contextPtr) throws HandshakeException; + + public D2DHandshakeContext(@Nonnull Role role) { + this.contextPtr = create_context(role == Role.INITIATOR); + } + + /** + * Convenience constructor that creates a UKEY2 D2DHandshakeContext for the initiator role. + * + * @return a D2DHandshakeContext for the role of initiator in the handshake. + */ + public static D2DHandshakeContext forInitiator() { + return new D2DHandshakeContext(Role.INITIATOR); + } + + /** + * Convenience constructor that creates a UKEY2 D2DHandshakeContext for the initiator role. + * + * @return a D2DHandshakeContext for the role of responder/server in the handshake. + */ + public static D2DHandshakeContext forResponder() { + return new D2DHandshakeContext(Role.RESPONDER); + } + + /** + * Function that checks if the handshake is completed. + * + * @return true/false depending on if the handshake is complete. + */ + public boolean isHandshakeComplete() throws BadHandleException { + return is_handshake_complete(contextPtr); + } + + /** + * Gets the next handshake message in the exchange. + * + * @return handshake message encoded in a SecureMessage. + */ + @Nonnull + public byte[] getNextHandshakeMessage() throws BadHandleException { + return get_next_handshake_message(contextPtr); + } + + /** + * Parses the handshake message. + * + * @param message - handshake message from the other side. + */ + @Nonnull + public void parseHandshakeMessage(@Nonnull byte[] message) + throws BadHandleException, HandshakeException { + parse_handshake_message(contextPtr, message); + } + + /** + * Returns an authentication string suitable for authenticating the handshake out-of-band. Note + * that the authentication string can be short (e.g., a 6 digit visual confirmation code). Note: + * this should only be called when {#isHandshakeComplete} returns true. This code is analogous to + * the authentication string described in the spec. + * + * @param length - The length of the returned verification string. + * @return - The returned verification string as a byte array. + * @throws BadHandleException - Thrown if the handle is no longer valid, for example after calling + * {@link D2DHandshakeContext#toConnectionContext} + * @throws HandshakeException - Thrown if the handshake is not complete when this function is + * called. + */ + @Nonnull + public byte[] getVerificationString(int length) throws BadHandleException, HandshakeException { + return get_verification_string(contextPtr, length); + } + + /** + * Function to create a secure communication channel from the handshake after confirming the auth + * string generated by the handshake out-of-band (i.e. via a user-facing UI). + * + * @return a new {@link D2DConnectionContextV1} with the next protocol specified when creating the + * D2DHandshakeContext. + * @throws HandshakeException if the handsshake is not complete when this function is called. + */ + public D2DConnectionContextV1 toConnectionContext() throws HandshakeException { + return new D2DConnectionContextV1(to_connection_context(contextPtr)); + } +} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/HandshakeException.java b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/HandshakeException.java index 17928e9..20d3112 100644 --- a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/HandshakeException.java +++ b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/HandshakeException.java @@ -12,21 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.security.cryptauth.lib.securegcm; +package com.google.security.cryptauth.lib.securegcm.ukey2; -/** - * Represents an unrecoverable error that has occurred during the handshake procedure. - */ +/** Represents an unrecoverable error that has occurred during the handshake procedure. */ public class HandshakeException extends Exception { - public HandshakeException(String message) { - super(message); - } + public HandshakeException(String message) { + super(message); + } - public HandshakeException(Exception e) { - super(e); - } + public HandshakeException(Exception e) { + super(e); + } - public HandshakeException(String message, Exception e) { - super(message, e); - } -}
\ No newline at end of file + public HandshakeException(String message, Exception e) { + super(message, e); + } +} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/SessionRestoreException.java b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/SessionRestoreException.java index c780973..026f8c5 100644 --- a/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/SessionRestoreException.java +++ b/nearby/connections/ukey2/ukey2_jni/java/src/main/java/com/google/security/cryptauth/lib/securegcm/ukey2/SessionRestoreException.java @@ -12,11 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.google.security.cryptauth.lib.securegcm; +package com.google.security.cryptauth.lib.securegcm.ukey2; -/** - * Represents an unrecoverable error that has occurred during the handshake procedure. - */ +/** Represents an unrecoverable error that has occurred during the handshake procedure. */ public class SessionRestoreException extends Exception { public SessionRestoreException(String message) { super(message); @@ -29,4 +27,4 @@ public class SessionRestoreException extends Exception { public SessionRestoreException(String message, Exception e) { super(message, e); } -}
\ No newline at end of file +} diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/test/java/com/google/security/cryptauth/lib/securegcm/TestUkey2Protocol.kt b/nearby/connections/ukey2/ukey2_jni/java/src/test/java/com/google/security/cryptauth/lib/securegcm/TestUkey2Protocol.kt deleted file mode 100644 index 79cbd15..0000000 --- a/nearby/connections/ukey2/ukey2_jni/java/src/test/java/com/google/security/cryptauth/lib/securegcm/TestUkey2Protocol.kt +++ /dev/null @@ -1,182 +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. - */ - -/* - * This Java source file was generated by the Gradle 'init' task. - */ -package com.google.security.cryptauth.lib.securegcm - -import java.nio.charset.StandardCharsets -import org.junit.jupiter.api.Assertions.assertArrayEquals -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertFalse -import org.junit.jupiter.api.Assertions.assertNotEquals -import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertDoesNotThrow -import org.junit.jupiter.api.assertThrows - -// Driver code -// Tests exception handling and the handshake routine, as well as encrypting/decrypting short message between the server and initiator contexts. -@Suppress("UNUSED_VARIABLE") -class TestUkey2Protocol { - @Test - fun testHandshake() { - val initiatorContext = - D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) - assertFalse(initiatorContext.isHandshakeComplete) - val serverContext = - D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) - assertFalse(serverContext.isHandshakeComplete) - assertDoesNotThrow { - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - assertTrue(initiatorContext.isHandshakeComplete) - assertTrue(serverContext.isHandshakeComplete) - } - } - - @Test - fun testSendReceiveMessage() { - val initiatorContext = - D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) - val serverContext = - D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) - assertDoesNotThrow { - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - val connContext = initiatorContext.toConnectionContext() - val serverConnContext = serverContext.toConnectionContext() - val initialShareString = "Nearby sharing to server" - val encoded = connContext.encodeMessageToPeer( - initialShareString.toByteArray( - StandardCharsets.UTF_8 - ), null - ) - val response = - String(serverConnContext.decodeMessageFromPeer(encoded, null), StandardCharsets.UTF_8) - assertEquals(response, initialShareString) - } - } - - @Test - fun testSaveRestoreSession() { - val initiatorContext = - D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) - val serverContext = - D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) - assertDoesNotThrow { - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - val connContext = initiatorContext.toConnectionContext() - val serverConnContext = serverContext.toConnectionContext() - val initiatorSavedSession = connContext.saveSession() - val restored = D2DConnectionContextV1.fromSavedSession(initiatorSavedSession) - assertArrayEquals(connContext.sessionUnique, restored.sessionUnique) - val initialShareString = "Nearby sharing to server" - val encoded = serverConnContext.encodeMessageToPeer( - initialShareString.toByteArray( - StandardCharsets.UTF_8 - ), null - ) - val response = String(restored.decodeMessageFromPeer(encoded, null), StandardCharsets.UTF_8) - assertEquals(response, initialShareString) - } - } - - @Test - fun testSaveRestoreBadSession() { - val initiatorContext = - D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) - val serverContext = - D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) - val deriveInitiatorSavedSession = { - assertDoesNotThrow { - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - val connContext = initiatorContext.toConnectionContext() - val serverConnContext = serverContext.toConnectionContext() - connContext.saveSession() - } - } - assertThrows<SessionRestoreException> { - val unused = D2DConnectionContextV1.fromSavedSession(deriveInitiatorSavedSession().copyOfRange(0, 20)) - } - } - - @Test - fun tryReuseHandshakeContext() { - val initiatorContext = - D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) - val serverContext = - D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) - assertDoesNotThrow { - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - val connContext = initiatorContext.toConnectionContext() - val serverConnContext = serverContext.toConnectionContext() - } - assertThrows<BadHandleException> { - val unused = serverContext.nextHandshakeMessage - } - } - - @Test - fun testSendReceiveMessageWithAssociatedData() { - val initiatorContext = - D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) - val serverContext = - D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) - val associatedData = "Associated data.".toByteArray() - assertDoesNotThrow { - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - val connContext = initiatorContext.toConnectionContext() - val serverConnContext = serverContext.toConnectionContext() - val initialShareString = "Nearby sharing to server" - val encoded = connContext.encodeMessageToPeer( - initialShareString.toByteArray( - StandardCharsets.UTF_8 - ), associatedData - ) - val response = - String(serverConnContext.decodeMessageFromPeer(encoded, associatedData), StandardCharsets.UTF_8) - assertEquals(response, initialShareString) - } - } - - @Test - fun testVerificationString() { - val initiatorContext = - D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) - val serverContext = - D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) - assertDoesNotThrow { - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) - serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) - } - assert(serverContext.isHandshakeComplete) - assert(initiatorContext.isHandshakeComplete) - assertArrayEquals(serverContext.getVerificationString(32), initiatorContext.getVerificationString(32)) - } -}
\ No newline at end of file diff --git a/nearby/connections/ukey2/ukey2_jni/java/src/test/java/com/google/security/cryptauth/lib/securegcm/ukey2/TestUkey2Protocol.kt b/nearby/connections/ukey2/ukey2_jni/java/src/test/java/com/google/security/cryptauth/lib/securegcm/ukey2/TestUkey2Protocol.kt new file mode 100644 index 0000000..f770977 --- /dev/null +++ b/nearby/connections/ukey2/ukey2_jni/java/src/test/java/com/google/security/cryptauth/lib/securegcm/ukey2/TestUkey2Protocol.kt @@ -0,0 +1,167 @@ +/* + * 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. + */ + +/* + * This Java source file was generated by the Gradle 'init' task. + */ +package com.google.security.cryptauth.lib.securegcm.ukey2 + +import java.nio.charset.StandardCharsets +import org.junit.jupiter.api.Assertions.assertArrayEquals +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertDoesNotThrow +import org.junit.jupiter.api.assertThrows + +// Driver code +// Tests exception handling and the handshake routine, as well as encrypting/decrypting short +// message between the server and initiator contexts. +@Suppress("UNUSED_VARIABLE") +class TestUkey2Protocol { + @Test + fun testHandshake() { + val initiatorContext = D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) + println("got initial context") + assertFalse(initiatorContext.isHandshakeComplete) + val serverContext = D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) + assertFalse(serverContext.isHandshakeComplete) + assertDoesNotThrow { + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + assertTrue(initiatorContext.isHandshakeComplete) + assertTrue(serverContext.isHandshakeComplete) + } + } + + @Test + fun testSendReceiveMessage() { + val initiatorContext = D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) + val serverContext = D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) + assertDoesNotThrow { + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + val connContext = initiatorContext.toConnectionContext() + val serverConnContext = serverContext.toConnectionContext() + val initialShareString = "Nearby sharing to server" + val encoded = + connContext.encodeMessageToPeer( + initialShareString.toByteArray(StandardCharsets.UTF_8), null) + val response = + String(serverConnContext.decodeMessageFromPeer(encoded, null), StandardCharsets.UTF_8) + assertEquals(response, initialShareString) + } + } + + @Test + fun testSaveRestoreSession() { + val initiatorContext = D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) + val serverContext = D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) + assertDoesNotThrow { + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + val connContext = initiatorContext.toConnectionContext() + val serverConnContext = serverContext.toConnectionContext() + val initiatorSavedSession = connContext.saveSession() + val restored = D2DConnectionContextV1.fromSavedSession(initiatorSavedSession) + assertArrayEquals(connContext.sessionUnique, restored.sessionUnique) + val initialShareString = "Nearby sharing to server" + val encoded = + serverConnContext.encodeMessageToPeer( + initialShareString.toByteArray(StandardCharsets.UTF_8), null) + val response = String(restored.decodeMessageFromPeer(encoded, null), StandardCharsets.UTF_8) + assertEquals(response, initialShareString) + } + } + + @Test + fun testSaveRestoreBadSession() { + val initiatorContext = D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) + val serverContext = D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) + val deriveInitiatorSavedSession = { + assertDoesNotThrow { + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + val connContext = initiatorContext.toConnectionContext() + val serverConnContext = serverContext.toConnectionContext() + connContext.saveSession() + } + } + assertThrows<SessionRestoreException> { + val unused = + D2DConnectionContextV1.fromSavedSession(deriveInitiatorSavedSession().copyOfRange(0, 20)) + } + } + + @Test + fun tryReuseHandshakeContext() { + val initiatorContext = D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) + val serverContext = D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) + assertDoesNotThrow { + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + val connContext = initiatorContext.toConnectionContext() + val serverConnContext = serverContext.toConnectionContext() + } + assertThrows<BadHandleException> { + val unused = serverContext.nextHandshakeMessage + } + } + + @Test + fun testSendReceiveMessageWithAssociatedData() { + val initiatorContext = D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) + val serverContext = D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) + val associatedData = "Associated data.".toByteArray() + assertDoesNotThrow { + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + val connContext = initiatorContext.toConnectionContext() + val serverConnContext = serverContext.toConnectionContext() + val initialShareString = "Nearby sharing to server" + val encoded = + connContext.encodeMessageToPeer( + initialShareString.toByteArray(StandardCharsets.UTF_8), associatedData) + val response = + String( + serverConnContext.decodeMessageFromPeer(encoded, associatedData), + StandardCharsets.UTF_8) + assertEquals(response, initialShareString) + } + } + + @Test + fun testVerificationString() { + val initiatorContext = D2DHandshakeContext(D2DHandshakeContext.Role.INITIATOR) + val serverContext = D2DHandshakeContext(D2DHandshakeContext.Role.RESPONDER) + assertDoesNotThrow { + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + initiatorContext.parseHandshakeMessage(serverContext.nextHandshakeMessage) + serverContext.parseHandshakeMessage(initiatorContext.nextHandshakeMessage) + } + assert(serverContext.isHandshakeComplete) + assert(initiatorContext.isHandshakeComplete) + assertArrayEquals( + serverContext.getVerificationString(32), initiatorContext.getVerificationString(32)) + } +} diff --git a/nearby/connections/ukey2/ukey2_jni/src/lib.rs b/nearby/connections/ukey2/ukey2_jni/src/lib.rs index 597c973..c500ddd 100644 --- a/nearby/connections/ukey2/ukey2_jni/src/lib.rs +++ b/nearby/connections/ukey2/ukey2_jni/src/lib.rs @@ -59,12 +59,12 @@ fn generate_handle() -> u64 { pub(crate) fn insert_handshake_handle(item: D2DBox) -> u64 { let mut handle = generate_handle(); - let map = HANDLE_MAPPING.lock(); + let mut map = HANDLE_MAPPING.lock(); while map.contains_key(&handle) { handle = generate_handle(); } - let result = HANDLE_MAPPING.lock().insert(handle, item); + let result = map.insert(handle, item); // result should always be None since we checked that handle map does not contain the key already assert!(result.is_none()); handle @@ -72,12 +72,12 @@ pub(crate) fn insert_handshake_handle(item: D2DBox) -> u64 { pub(crate) fn insert_conn_handle(item: ConnectionBox) -> u64 { let mut handle = generate_handle(); - let map = CONNECTION_HANDLE_MAPPING.lock(); + let mut map = CONNECTION_HANDLE_MAPPING.lock(); while map.contains_key(&handle) { handle = generate_handle(); } - let result = CONNECTION_HANDLE_MAPPING.lock().insert(handle, item); + let result = map.insert(handle, item); // result should always be None since we checked that handle map does not contain the key already assert!(result.is_none()); handle @@ -94,7 +94,7 @@ enum JniError { /// Tells the caller whether the handshake has completed or not. If the handshake is complete, /// the caller may call `to_connection_context`to obtain a connection context. #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHandshakeContext_is_1handshake_1complete( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DHandshakeContext_is_1handshake_1complete( env: JNIEnv, _: JClass, context_handle: jlong, @@ -103,7 +103,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands if let Some(ctx) = HANDLE_MAPPING.lock().get(&(context_handle as u64)) { is_complete = ctx.is_handshake_complete(); } else { - env.throw_new("com/google/security/cryptauth/lib/securegcm/BadHandleException", "") + env.throw_new("com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException", "") .expect("failed to find error class"); } is_complete as jboolean @@ -111,7 +111,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands /// Creates a new handshake context #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHandshakeContext_create_1context( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DHandshakeContext_create_1context( _: JNIEnv, _: JClass, is_client: jboolean, @@ -131,7 +131,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands /// Constructs the next message that should be sent in the handshake. #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHandshakeContext_get_1next_1handshake_1message( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DHandshakeContext_get_1next_1handshake_1message( env: JNIEnv, _: JClass, context_handle: jlong, @@ -140,7 +140,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands let next_message = if let Some(ctx) = HANDLE_MAPPING.lock().get(&(context_handle as u64)) { ctx.get_next_handshake_message() } else { - env.throw_new("com/google/security/cryptauth/lib/securegcm/BadHandleException", "") + env.throw_new("com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException", "") .expect("failed to find error class"); None }; @@ -156,7 +156,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands // Safety: We know the message pointer is safe as it is coming directly from the JVM. #[allow(clippy::not_unsafe_ptr_arg_deref)] #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHandshakeContext_parse_1handshake_1message( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DHandshakeContext_parse_1handshake_1message( env: JNIEnv, _: JClass, context_handle: jlong, @@ -166,14 +166,14 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands let result = if let Some(ctx) = HANDLE_MAPPING.lock().get_mut(&(context_handle as u64)) { ctx.handle_handshake_message(rust_buffer.as_slice()).map_err(JniError::HandleMessageError) } else { - env.throw_new("com/google/security/cryptauth/lib/securegcm/BadHandleException", "") + env.throw_new("com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException", "") .expect("failed to find error class"); Err(JniError::BadHandle) }; if let Err(e) = result { if !env.exception_check().unwrap() { env.throw_new( - "com/google/security/cryptauth/lib/securegcm/HandshakeException", + "com/google/security/cryptauth/lib/securegcm/ukey2/HandshakeException", match e { JniError::BadHandle => "Bad handle", JniError::DecodeError(_) => "Unable to decode message", @@ -189,7 +189,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands /// Returns the `CompletedHandshake` using the results from this handshake context. May only /// be called if `is_handshake_complete` returns true. #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHandshakeContext_get_1verification_1string( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DHandshakeContext_get_1verification_1string( env: JNIEnv, _: JClass, context_handle: jlong, @@ -201,14 +201,14 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands .map_err(|_| JniError::HandshakeError(HandshakeError::HandshakeNotComplete)) .map(|h| h.auth_string::<CryptoProvider>().derive_vec(length as usize).unwrap()) } else { - env.throw_new("com/google/security/cryptauth/lib/securegcm/BadHandleException", "") + env.throw_new("com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException", "") .expect("failed to find error class"); Err(JniError::BadHandle) }; if let Err(e) = result { if !env.exception_check().unwrap() { env.throw_new( - "com/google/security/cryptauth/lib/securegcm/HandshakeException", + "com/google/security/cryptauth/lib/securegcm/ukey2/HandshakeException", match e { JniError::BadHandle => "Bad handle", JniError::DecodeError(_) => "Unable to decode message", @@ -228,7 +228,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands /// Creates a [`D2DConnectionContextV1`] using the results of the handshake. May only be called /// if `is_handshake_complete` returns true. #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHandshakeContext_to_1connection_1context( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DHandshakeContext_to_1connection_1context( env: JNIEnv, _: JClass, context_handle: jlong, @@ -240,7 +240,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands }; if let Err(error) = conn_context { env.throw_new( - "com/google/security/cryptauth/lib/securegcm/HandshakeException", + "com/google/security/cryptauth/lib/securegcm/ukey2/HandshakeException", match error { JniError::BadHandle => "Bad context handle", JniError::HandshakeError(_) => "Handshake not complete", @@ -261,7 +261,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DHands // from the JVM. #[allow(clippy::not_unsafe_ptr_arg_deref)] #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConnectionContextV1_encode_1message_1to_1peer( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DConnectionContextV1_encode_1message_1to_1peer( env: JNIEnv, _: JClass, context_handle: jlong, @@ -291,7 +291,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne if let Ok(ret_vec) = result { env.byte_array_from_slice(ret_vec.as_slice()).expect("unable to create jByteArray") } else { - env.throw_new("com/google/security/cryptauth/lib/securegcm/BadHandleException", "") + env.throw_new("com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException", "") .expect("failed to find error class"); empty_array } @@ -304,7 +304,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne // from the JVM. #[allow(clippy::not_unsafe_ptr_arg_deref)] #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConnectionContextV1_decode_1message_1from_1peer( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DConnectionContextV1_decode_1message_1from_1peer( env: JNIEnv, _: JClass, context_handle: jlong, @@ -334,7 +334,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne env.byte_array_from_slice(message.as_slice()).expect("unable to create jByteArray") } else { env.throw_new( - "com/google/security/cryptauth/lib/securegcm/CryptoException", + "com/google/security/cryptauth/lib/securegcm/ukey2/CryptoException", match result.unwrap_err() { JniError::BadHandle => "Bad context handle", JniError::DecodeError(e) => match e { @@ -352,7 +352,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne /// Returns the last sequence number used to encode a message. #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConnectionContextV1_get_1sequence_1number_1for_1encoding( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DConnectionContextV1_get_1sequence_1number_1for_1encoding( env: JNIEnv, _: JClass, context_handle: jlong, @@ -360,7 +360,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne if let Some(ctx) = CONNECTION_HANDLE_MAPPING.lock().get(&(context_handle as u64)) { ctx.get_sequence_number_for_encoding() } else { - env.throw_new("com/google/security/cryptauth/lib/securegcm/BadHandleException", "") + env.throw_new("com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException", "") .expect("failed to find error class"); -1 } @@ -368,7 +368,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne /// Returns the last sequence number used to decode a message. #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConnectionContextV1_get_1sequence_1number_1for_1decoding( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DConnectionContextV1_get_1sequence_1number_1for_1decoding( env: JNIEnv, _: JClass, context_handle: jlong, @@ -376,7 +376,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne if let Some(ctx) = CONNECTION_HANDLE_MAPPING.lock().get(&(context_handle as u64)) { ctx.get_sequence_number_for_decoding() } else { - env.throw_new("com/google/security/cryptauth/lib/securegcm/BadHandleException", "") + env.throw_new("com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException", "") .expect("failed to find error class"); -1 } @@ -385,7 +385,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne /// Creates a saved session that can later be used for resumption. The session data may be /// persisted, but it must be stored in a secure location. #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConnectionContextV1_save_1session( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DConnectionContextV1_save_1session( env: JNIEnv, _: JClass, context_handle: jlong, @@ -394,7 +394,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne if let Some(ctx) = CONNECTION_HANDLE_MAPPING.lock().get(&(context_handle as u64)) { env.byte_array_from_slice(ctx.save_session().as_slice()).expect("unable to save session") } else { - env.throw_new("com/google/security/cryptauth/lib/securegcm/BadHandleException", "") + env.throw_new("com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException", "") .expect("failed to find error class"); empty_array } @@ -404,7 +404,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne // Safety: We know the session_info pointer is safe because it is coming directly from the JVM. #[no_mangle] #[allow(clippy::not_unsafe_ptr_arg_deref)] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConnectionContextV1_from_1saved_1session( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DConnectionContextV1_from_1saved_1session( env: JNIEnv, _: JClass, session_info: jbyteArray, @@ -416,7 +416,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne D2DConnectionContextV1::from_saved_session::<CryptoProvider>(session_info_rust.as_slice()); if ctx.is_err() { env.throw_new( - "com/google/security/cryptauth/lib/securegcm/SessionRestoreException", + "com/google/security/cryptauth/lib/securegcm/ukey2/SessionRestoreException", match ctx.err().unwrap() { DeserializeError::BadDataLength => "DeserializeError: bad session_info length", DeserializeError::BadProtocolVersion => "DeserializeError: bad protocol version", @@ -435,7 +435,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne /// of the ASCII string "D2D". Since the server and client share the same session keys, the /// resulting session unique is also the same. #[no_mangle] -pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConnectionContextV1_get_1session_1unique( +pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_ukey2_D2DConnectionContextV1_get_1session_1unique( env: JNIEnv, _: JClass, context_handle: jlong, @@ -445,7 +445,7 @@ pub extern "system" fn Java_com_google_security_cryptauth_lib_securegcm_D2DConne env.byte_array_from_slice(ctx.get_session_unique::<CryptoProvider>().as_slice()) .expect("unable to get unique session id") } else { - env.throw_new("com/google/security/cryptauth/lib/securegcm/BadHandleException", "") + env.throw_new("com/google/security/cryptauth/lib/securegcm/ukey2/BadHandleException", "") .expect("failed to find error class"); empty_array } diff --git a/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/device_to_device_messages.rs b/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/device_to_device_messages.rs index 3c2da35..71c247b 100644 --- a/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/device_to_device_messages.rs +++ b/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/device_to_device_messages.rs @@ -13,7 +13,7 @@ // limitations under the License. // This file is generated by rust-protobuf 3.2.0. Do not edit -// .proto file is parsed by protoc 3.19.1 +// .proto file is parsed by protoc 3.21.12 // @generated // https://github.com/rust-lang/rust-clippy/issues/702 diff --git a/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/securegcm.rs b/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/securegcm.rs index 3231440..70a927d 100644 --- a/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/securegcm.rs +++ b/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/securegcm.rs @@ -13,7 +13,7 @@ // limitations under the License. // This file is generated by rust-protobuf 3.2.0. Do not edit -// .proto file is parsed by protoc 3.19.1 +// .proto file is parsed by protoc 3.21.12 // @generated // https://github.com/rust-lang/rust-clippy/issues/702 diff --git a/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/securemessage.rs b/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/securemessage.rs index 161e0be..d83d137 100644 --- a/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/securemessage.rs +++ b/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/securemessage.rs @@ -13,7 +13,7 @@ // limitations under the License. // This file is generated by rust-protobuf 3.2.0. Do not edit -// .proto file is parsed by protoc 3.19.1 +// .proto file is parsed by protoc 3.21.12 // @generated // https://github.com/rust-lang/rust-clippy/issues/702 diff --git a/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/ukey.rs b/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/ukey.rs index 5370207..9be6b3d 100644 --- a/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/ukey.rs +++ b/nearby/connections/ukey2/ukey2_proto/src/ukey2_all_proto/ukey.rs @@ -13,7 +13,7 @@ // limitations under the License. // This file is generated by rust-protobuf 3.2.0. Do not edit -// .proto file is parsed by protoc 3.19.1 +// .proto file is parsed by protoc 3.21.12 // @generated // https://github.com/rust-lang/rust-clippy/issues/702 diff --git a/nearby/connections/ukey2/ukey2_shell/Cargo.toml b/nearby/connections/ukey2/ukey2_shell/Cargo.toml index 9a2856d..2ac12fa 100644 --- a/nearby/connections/ukey2/ukey2_shell/Cargo.toml +++ b/nearby/connections/ukey2/ukey2_shell/Cargo.toml @@ -11,4 +11,4 @@ workspace = true crypto_provider_rustcrypto = { workspace = true, features = [ "alloc" ] } ukey2_rs = { version = "0.1.0", path = "../ukey2" } ukey2_connections = { version = "0.1.0", path = "../ukey2_connections" } -clap = { version = "4.0.17", default-features = false, features = ["std", "derive"] } +clap = { workspace = true, features = ["std", "derive"] } diff --git a/nearby/crypto/crypto_provider_boringssl/Cargo.lock b/nearby/crypto/crypto_provider_boringssl/Cargo.lock index 7773e56..11ec2e3 100644 --- a/nearby/crypto/crypto_provider_boringssl/Cargo.lock +++ b/nearby/crypto/crypto_provider_boringssl/Cargo.lock @@ -3,6 +3,15 @@ version = 3 [[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] name = "base64" version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -68,6 +77,12 @@ dependencies = [ ] [[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -98,6 +113,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] name = "ppv-lite86" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -105,18 +126,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -171,10 +192,45 @@ dependencies = [ ] [[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "relative-path" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" + +[[package]] name = "rstest" -version = "0.17.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de1bb486a691878cd320c2f0d319ba91eeaa2e894066d8b5f8f117c000e9d962" +checksum = "97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199" dependencies = [ "rstest_macros", "rustc_version", @@ -182,15 +238,18 @@ dependencies = [ [[package]] name = "rstest_macros" -version = "0.17.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290ca1a1c8ca7edb7c3283bd44dc35dd54fdec6253a3912e201ba1072018fca8" +checksum = "d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605" dependencies = [ "cfg-if", + "glob", "proc-macro2", "quote", + "regex", + "relative-path", "rustc_version", - "syn 1.0.109", + "syn", "unicode-ident", ] @@ -203,7 +262,7 @@ dependencies = [ "quote", "rand", "rustc_version", - "syn 2.0.29", + "syn", ] [[package]] @@ -229,29 +288,29 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.187" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7fe14252655bd1e578af19f5fa00fe02fd0013b100ca6b49fde31c41bae4c" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.187" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46b2a6ca578b3f1d4501b12f78ed4692006d79d82a1a7c561c12dbc3d625eb8" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn", ] [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "6fbd975230bada99c8bb618e0c365c2eefa219158d5c6c29610fd09ff1833257" dependencies = [ "itoa", "ryu", @@ -260,20 +319,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.29" +version = "2.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" dependencies = [ "proc-macro2", "quote", diff --git a/nearby/crypto/crypto_provider_test/fuzz/Cargo.lock b/nearby/crypto/crypto_provider_test/fuzz/Cargo.lock index bd8f6f9..49c9513 100644 --- a/nearby/crypto/crypto_provider_test/fuzz/Cargo.lock +++ b/nearby/crypto/crypto_provider_test/fuzz/Cargo.lock @@ -61,9 +61,9 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "arbitrary" -version = "1.3.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" dependencies = [ "derive_arbitrary", ] @@ -76,9 +76,9 @@ checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "bitflags" -version = "1.3.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "block-buffer" @@ -100,9 +100,9 @@ dependencies = [ [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cbc" @@ -115,11 +115,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -140,24 +141,24 @@ dependencies = [ [[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 = "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 = "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", @@ -257,9 +258,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f711ade317dd348950a9910f81c5947e3d8907ebd2b83f76203ff1807e6a2bc2" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" dependencies = [ "cfg-if", "cpufeatures", @@ -273,20 +274,20 @@ dependencies = [ [[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.26", + "syn 2.0.48", ] [[package]] name = "der" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -294,13 +295,13 @@ dependencies = [ [[package]] name = "derive_arbitrary" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.48", ] [[package]] @@ -316,30 +317,31 @@ dependencies = [ [[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 = [ "signature", ] [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "sha2", + "subtle", ] [[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", @@ -366,9 +368,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" [[package]] name = "foreign-types" @@ -398,9 +400,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -436,9 +438,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[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", ] @@ -464,24 +466,24 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] [[package]] name = "libc" -version = "0.2.147" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libfuzzer-sys" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb09950ae85a0a94b27676cccf37da5ff13f27076aa1adbc6545dd0d0e1bd4e" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" dependencies = [ "arbitrary", "cc", @@ -490,9 +492,9 @@ dependencies = [ [[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 = "opaque-debug" @@ -502,9 +504,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" dependencies = [ "bitflags", "cfg-if", @@ -523,14 +525,14 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.48", ] [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" dependencies = [ "cc", "libc", @@ -540,9 +542,9 @@ dependencies = [ [[package]] name = "ouroboros" -version = "0.17.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4361ddfdd108bddc19367ba805a3a43773d8bc3e407ac30e6c364cd264dd52e" +checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" dependencies = [ "aliasable", "ouroboros_macro", @@ -551,15 +553,15 @@ dependencies = [ [[package]] name = "ouroboros_macro" -version = "0.17.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b81e113ed913910f05ef45c9344f67588fe6395f92d906eedf9ee5d54279922" +checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ "heck", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.48", ] [[package]] @@ -574,15 +576,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" [[package]] name = "platforms" -version = "3.0.2" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "polyval" @@ -604,9 +606,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[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", ] @@ -637,18 +639,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.31" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -705,15 +707,15 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -722,9 +724,9 @@ dependencies = [ [[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" [[package]] name = "static_assertions" @@ -750,9 +752,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.26" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -767,15 +769,15 @@ checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" [[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 = "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 = "universal-hash" @@ -817,6 +819,6 @@ dependencies = [ [[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/presence/CMakeLists.txt b/nearby/presence/CMakeLists.txt index d2a251b..9670c34 100644 --- a/nearby/presence/CMakeLists.txt +++ b/nearby/presence/CMakeLists.txt @@ -17,7 +17,7 @@ cmake_minimum_required(VERSION 3.14) project(NearbyProtocol) # required for designated initializers on MSVC -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) # root directory of repo set(BETO_CORE_ROOT ${CMAKE_SOURCE_DIR}/../..) diff --git a/nearby/presence/ldt/fuzz/Cargo.lock b/nearby/presence/ldt/fuzz/Cargo.lock index 419d9e9..7262f74 100644 --- a/nearby/presence/ldt/fuzz/Cargo.lock +++ b/nearby/presence/ldt/fuzz/Cargo.lock @@ -279,14 +279,15 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "sha2", + "subtle", ] [[package]] @@ -578,9 +579,9 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", diff --git a/nearby/presence/ldt_np_adv/fuzz/Cargo.lock b/nearby/presence/ldt_np_adv/fuzz/Cargo.lock index 6b6ef4b..3bfbfb9 100644 --- a/nearby/presence/ldt_np_adv/fuzz/Cargo.lock +++ b/nearby/presence/ldt_np_adv/fuzz/Cargo.lock @@ -283,14 +283,15 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "sha2", + "subtle", ] [[package]] @@ -605,9 +606,9 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", diff --git a/nearby/presence/ldt_np_adv_ffi/Cargo.lock b/nearby/presence/ldt_np_adv_ffi/Cargo.lock index 3f7e2a7..d8664ea 100644 --- a/nearby/presence/ldt_np_adv_ffi/Cargo.lock +++ b/nearby/presence/ldt_np_adv_ffi/Cargo.lock @@ -87,9 +87,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" -version = "1.3.2" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "block-buffer" @@ -323,15 +323,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", + "subtle", "zeroize", ] @@ -562,9 +563,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" dependencies = [ "bitflags", "cfg-if", @@ -588,9 +589,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" dependencies = [ "cc", "libc", @@ -776,9 +777,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sec1" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -801,9 +802,9 @@ checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", diff --git a/nearby/presence/np_adv/Cargo.toml b/nearby/presence/np_adv/Cargo.toml index e502c35..9b576a6 100644 --- a/nearby/presence/np_adv/Cargo.toml +++ b/nearby/presence/np_adv/Cargo.toml @@ -39,7 +39,6 @@ test_helper = { path = "../test_helper" } criterion.workspace = true crypto_provider_default = { workspace = true, features = ["std", "rustcrypto"] } np_ed25519 = { workspace = true, features = ["std"] } -rmp-serde = "1.1.2" sink = { workspace = true, features = ["std"] } [[bench]] diff --git a/nearby/presence/np_adv/benches/deser_adv.rs b/nearby/presence/np_adv/benches/deser_adv.rs index 08fd5c4..b52f53a 100644 --- a/nearby/presence/np_adv/benches/deser_adv.rs +++ b/nearby/presence/np_adv/benches/deser_adv.rs @@ -333,7 +333,9 @@ fn run_with_v1_creds<C>( } } } -fn add_des<I: SectionEncoder>(sb: &mut SectionBuilder<I>) { +fn add_des<I: SectionEncoder>( + sb: &mut SectionBuilder<&mut np_adv::extended::serialize::AdvBuilder, I>, +) { sb.add_de_res(|_| TxPower::try_from(17).map(TxPowerDataElement::from)).unwrap(); sb.add_de_res(|_| GenericDataElement::try_from(100_u32.into(), &[0; 10])).unwrap(); } diff --git a/nearby/presence/np_adv/src/deser_v1_tests.rs b/nearby/presence/np_adv/src/deser_v1_tests.rs index cea0063..e0cabc9 100644 --- a/nearby/presence/np_adv/src/deser_v1_tests.rs +++ b/nearby/presence/np_adv/src/deser_v1_tests.rs @@ -519,7 +519,7 @@ impl<C: CryptoProvider> TestIdentity<C> { } /// Add several DEs with random types and contents fn add_des<I: SectionEncoder, R: rand::Rng>( - mut sb: SectionBuilder<I>, + mut sb: SectionBuilder<&mut AdvBuilder, I>, rng: &mut R, ) -> Vec<GenericDataElement> { let mut des = Vec::new(); diff --git a/nearby/presence/np_adv/src/extended/deserialize/section_tests.rs b/nearby/presence/np_adv/src/extended/deserialize/section_tests.rs index f7e2025..5fa2dbe 100644 --- a/nearby/presence/np_adv/src/extended/deserialize/section_tests.rs +++ b/nearby/presence/np_adv/src/extended/deserialize/section_tests.rs @@ -523,7 +523,7 @@ fn do_deserialize_section_unencrypted<I: serialize::SectionEncoder>( fn fill_section_random_des<'adv, R: rand::Rng, I: serialize::SectionEncoder>( mut rng: &mut R, sink: &'adv mut Vec<u8>, - section_builder: &mut SectionBuilder<I>, + section_builder: &mut SectionBuilder<&mut AdvBuilder, I>, de_offset: usize, ) -> (Vec<DataElement<'adv>>, Vec<GenericDataElement>) { let mut expected_des = vec![]; diff --git a/nearby/presence/np_adv/src/extended/serialize/mod.rs b/nearby/presence/np_adv/src/extended/serialize/mod.rs index e753281..9d82273 100644 --- a/nearby/presence/np_adv/src/extended/serialize/mod.rs +++ b/nearby/presence/np_adv/src/extended/serialize/mod.rs @@ -161,6 +161,12 @@ pub struct AdvBuilder { advertisement_type: AdvertisementType, } +impl AsMut<AdvBuilder> for AdvBuilder { + fn as_mut(&mut self) -> &mut AdvBuilder { + self + } +} + impl AdvBuilder { /// Build an [AdvBuilder]. pub fn new(advertisement_type: AdvertisementType) -> Self { @@ -170,17 +176,10 @@ impl AdvBuilder { Self { adv, section_count: 0, advertisement_type } } - /// Create a section builder. - /// - /// The builder will not accept more DEs than can fit given the space already used in the - /// advertisement by previous sections, if any. - /// - /// Once the builder is populated, add it to the originating advertisement with - /// [SectionBuilder.add_to_advertisement]. - pub fn section_builder<SE: SectionEncoder>( - &mut self, - section_encoder: SE, - ) -> Result<SectionBuilder<SE>, AddSectionError> { + fn prepare_section_builder_buffer_and_de_offset<SE: SectionEncoder>( + &self, + ) -> Result<(CapacityLimitedVec<u8, NP_ADV_MAX_SECTION_LEN>, DataElementOffset), AddSectionError> + { // section header and identity prefix let prefix_len = 1 + SE::PREFIX_LEN; let minimum_section_len = prefix_len + SE::SUFFIX_LEN; @@ -203,16 +202,49 @@ impl AdvBuilder { // placeholder for section header and identity prefix section.resize(prefix_len, 0); - Ok(SectionBuilder { - section: CapacityLimitedVec { - vec: section, - // won't underflow: checked above - capacity: available_len - SE::SUFFIX_LEN, - }, - section_encoder, - adv_builder: self, - next_de_offset: SE::INITIAL_DE_OFFSET, - }) + let section = CapacityLimitedVec { + vec: section, + // won't underflow: checked above + capacity: available_len - SE::SUFFIX_LEN, + }; + let next_de_offset = SE::INITIAL_DE_OFFSET; + Ok((section, next_de_offset)) + } + + /// Create a section builder whose contents may be added to this advertisement. + /// + /// The builder will not accept more DEs than can fit given the space already used in the + /// advertisement by previous sections, if any. + /// + /// Once the builder is populated, add it to the originating advertisement with + /// [SectionBuilder.add_to_advertisement]. + pub fn section_builder<SE: SectionEncoder>( + &mut self, + section_encoder: SE, + ) -> Result<SectionBuilder<&mut AdvBuilder, SE>, AddSectionError> { + let (section, next_de_offset) = + self.prepare_section_builder_buffer_and_de_offset::<SE>()?; + + Ok(SectionBuilder { section, section_encoder, adv_builder: self, next_de_offset }) + } + + /// Create a section builder which actually takes ownership of this advertisement builder. + /// + /// This is unlike `AdvertisementBuilder#section_builder` in that the returned section + /// builder will take ownership of this advertisement builder, if the operation was + /// successful. Otherwise, this advertisement builder will be returned back to the + /// caller unaltered as part of the `Err` arm. + #[allow(clippy::result_large_err)] + pub fn into_section_builder<SE: SectionEncoder>( + self, + section_encoder: SE, + ) -> Result<SectionBuilder<AdvBuilder, SE>, (AdvBuilder, AddSectionError)> { + match self.prepare_section_builder_buffer_and_de_offset::<SE>() { + Ok((section, next_de_offset)) => { + Ok(SectionBuilder { section, section_encoder, adv_builder: self, next_de_offset }) + } + Err(err) => Err((self, err)), + } } /// Convert the builder into an encoded advertisement. @@ -220,6 +252,12 @@ impl AdvBuilder { EncodedAdvertisement { adv: to_array_view(self.adv) } } + /// Gets the current number of sections added to this advertisement + /// builder, not counting any outstanding SectionBuilders. + pub fn section_count(&self) -> usize { + self.section_count + } + /// Add the section, which must have come from a SectionBuilder generated from this, into this /// advertisement. fn add_section(&mut self, section: EncodedSection) { @@ -279,24 +317,56 @@ type EncodedSection = ArrayView<u8, NP_ADV_MAX_SECTION_LEN>; /// Accumulates data elements and encodes them into a section. #[derive(Debug)] -pub struct SectionBuilder<'a, SE: SectionEncoder> { +pub struct SectionBuilder<R: AsMut<AdvBuilder>, SE: SectionEncoder> { /// Contains the section header, the identity-specified overhead, and any DEs added pub(crate) section: CapacityLimitedVec<u8, NP_ADV_MAX_SECTION_LEN>, section_encoder: SE, - /// mut ref to enforce only one active section builder at a time - adv_builder: &'a mut AdvBuilder, + /// mut ref-able to enforce only one active section builder at a time + adv_builder: R, next_de_offset: DataElementOffset, } -impl<'a, SE: SectionEncoder> SectionBuilder<'a, SE> { +impl<'a, SE: SectionEncoder> SectionBuilder<&'a mut AdvBuilder, SE> { /// Add this builder to the advertisement that created it. pub fn add_to_advertisement(self) { - let adv_builder = self.adv_builder; + let _ = self.add_to_advertisement_internal(); + } +} + +impl<SE: SectionEncoder> SectionBuilder<AdvBuilder, SE> { + /// Gets the 0-based index of the section currently under construction + /// in the context of the containing advertisement. + pub fn section_index(&self) -> usize { + self.adv_builder.section_count() + } + /// Add this builder to the advertisement that created it, + /// and returns the containing advertisement back to the caller. + pub fn add_to_advertisement(self) -> AdvBuilder { + self.add_to_advertisement_internal() + } +} + +impl<R: AsMut<AdvBuilder>, SE: SectionEncoder> SectionBuilder<R, SE> { + /// Add this builder to the advertisement that created it. + /// Returns the mut-refable to the advertisement builder + /// which the contents of this section builder were added to. + fn add_to_advertisement_internal(mut self) -> R { + let adv_builder = self.adv_builder.as_mut(); + let adv_builder_header_byte = adv_builder.header_byte(); adv_builder.add_section(Self::build_section( + adv_builder_header_byte, self.section.into_inner(), self.section_encoder, - adv_builder, - )) + )); + self.adv_builder + } + + /// Gets the derived salt which will be employed for the next DE offset. + /// + /// Suitable for scenarios (like FFI) where a closure would be inappropriate + /// for DE construction, and interaction with the client is preferred. + pub fn next_de_salt(&self) -> SE::DerivedSalt { + self.section_encoder.de_salt(self.next_de_offset) } /// Add a data element to the section with a closure that returns a `Result`. @@ -306,8 +376,7 @@ impl<'a, SE: SectionEncoder> SectionBuilder<'a, SE> { &mut self, build_de: F, ) -> Result<(), AddDataElementError<E>> { - let writer = build_de(self.section_encoder.de_salt(self.next_de_offset)) - .map_err(AddDataElementError::BuildDeError)?; + let writer = build_de(self.next_de_salt()).map_err(AddDataElementError::BuildDeError)?; let orig_len = self.section.len(); // since we own the writer, and it's immutable, no race risk writing header w/ len then @@ -357,9 +426,9 @@ impl<'a, SE: SectionEncoder> SectionBuilder<'a, SE> { /// /// Implemented without self to avoid partial-move issues. fn build_section( + adv_builder_header_byte: u8, mut section_contents: tinyvec::ArrayVec<[u8; NP_ADV_MAX_SECTION_LEN]>, mut section_encoder: SE, - adv_builder: &AdvBuilder, ) -> EncodedSection { // there is space because the capacity for DEs was restricted to allow it section_contents.resize(section_contents.len() + SE::SUFFIX_LEN, 0); @@ -372,7 +441,7 @@ impl<'a, SE: SectionEncoder> SectionBuilder<'a, SE> { .expect("section length is always <=255 and non-negative"); section_encoder.postprocess( - adv_builder.header_byte(), + adv_builder_header_byte, section_contents[0], &mut section_contents[1..], ); diff --git a/nearby/presence/np_adv/src/extended/serialize/section_tests.rs b/nearby/presence/np_adv/src/extended/serialize/section_tests.rs index 68e5b60..3a6a5f9 100644 --- a/nearby/presence/np_adv/src/extended/serialize/section_tests.rs +++ b/nearby/presence/np_adv/src/extended/serialize/section_tests.rs @@ -805,7 +805,7 @@ fn do_signature_encrypted_identity_fixed_key_material_test<W: WriteDataElement>( /// Write `section_contents_len` bytes of DE and header into `section_builder` pub(crate) fn fill_section_builder<I: SectionEncoder>( section_contents_len: usize, - section_builder: &mut SectionBuilder<I>, + section_builder: &mut SectionBuilder<&mut AdvBuilder, I>, ) { // DEs can only go up to 127, so we'll need multiple for long sections for _ in 0..(section_contents_len / 100) { @@ -863,9 +863,14 @@ pub(crate) trait SectionBuilderExt { fn into_section(self) -> EncodedSection; } -impl<'a, I: SectionEncoder> SectionBuilderExt for SectionBuilder<'a, I> { +impl<R: AsMut<AdvBuilder>, I: SectionEncoder> SectionBuilderExt for SectionBuilder<R, I> { /// Convenience method for tests - fn into_section(self) -> EncodedSection { - Self::build_section(self.section.into_inner(), self.section_encoder, self.adv_builder) + fn into_section(mut self) -> EncodedSection { + let adv_builder_header_byte = self.adv_builder.as_mut().header_byte(); + Self::build_section( + adv_builder_header_byte, + self.section.into_inner(), + self.section_encoder, + ) } } diff --git a/nearby/presence/np_adv/src/legacy/actions/macros.rs b/nearby/presence/np_adv/src/legacy/actions/macros.rs index 8208a57..db241d6 100644 --- a/nearby/presence/np_adv/src/legacy/actions/macros.rs +++ b/nearby/presence/np_adv/src/legacy/actions/macros.rs @@ -48,25 +48,6 @@ macro_rules! boolean_element_action_element_impl_shared { /// Use `plaintext_only`, `ciphertext_only`, or `plaintext_and_ciphertext` to create appropriate /// impls. macro_rules! boolean_element { - ($type_name:ident, $index:expr, plaintext_only) => { - $crate::legacy::actions::macros::boolean_element_struct!($type_name); - $crate::legacy::actions::macros::boolean_element_struct_from_bool!($type_name); - - impl $crate::legacy::actions::ActionElement for $type_name { - $crate::legacy::actions::macros::boolean_element_action_element_impl_shared!( - $type_name, $index - ); - - fn supports_flavor(flavor: $crate::legacy::PacketFlavorEnum) -> bool { - match flavor { - $crate::legacy::PacketFlavorEnum::Plaintext => true, - $crate::legacy::PacketFlavorEnum::Ciphertext => false, - } - } - } - - $crate::legacy::actions::macros::boolean_element_to_plaintext_element!($type_name); - }; ($type_name:ident, $index:expr, ciphertext_only) => { $crate::legacy::actions::macros::boolean_element_struct!($type_name); $crate::legacy::actions::macros::boolean_element_struct_from_bool!($type_name); diff --git a/nearby/presence/np_adv/src/legacy/actions/mod.rs b/nearby/presence/np_adv/src/legacy/actions/mod.rs index 90a0186..e0f4514 100644 --- a/nearby/presence/np_adv/src/legacy/actions/mod.rs +++ b/nearby/presence/np_adv/src/legacy/actions/mod.rs @@ -439,5 +439,5 @@ macros::boolean_element!(NearbyShare, 9, plaintext_and_ciphertext); macros::boolean_element!(InstantTethering, 10, ciphertext_only); macros::boolean_element!(PhoneHub, 11, ciphertext_only); macros::boolean_element!(PresenceManager, 12, ciphertext_only); -macros::boolean_element!(Finder, 13, plaintext_only); -macros::boolean_element!(FastPairSass, 14, plaintext_only); +macros::boolean_element!(Finder, 13, plaintext_and_ciphertext); +macros::boolean_element!(FastPairSass, 14, plaintext_and_ciphertext); diff --git a/nearby/presence/np_adv/src/legacy/actions/tests.rs b/nearby/presence/np_adv/src/legacy/actions/tests.rs index d45d968..6e68211 100644 --- a/nearby/presence/np_adv/src/legacy/actions/tests.rs +++ b/nearby/presence/np_adv/src/legacy/actions/tests.rs @@ -250,18 +250,6 @@ fn action_bits_try_from_flavor_mismatch_plaintext() { } #[test] -fn action_bits_try_from_flavor_mismatch_ciphertext() { - assert_eq!( - FlavorNotSupported { flavor: PacketFlavorEnum::Ciphertext }, - ActionBits::<Ciphertext>::try_from(ActionType::Finder.all_bits()).unwrap_err() - ); - assert_eq!( - 0xF0000000, - ActionBits::<Ciphertext>::try_from(ActionType::ContextSyncSeqNum.all_bits()).unwrap().bits - ); -} - -#[test] fn actions_de_deser_plaintext_with_ciphertext_action() { assert_eq!( DataElementDeserializeError::FlavorNotSupported { diff --git a/nearby/presence/np_adv/src/legacy/random_data_elements.rs b/nearby/presence/np_adv/src/legacy/random_data_elements.rs index 00a2e93..aca906b 100644 --- a/nearby/presence/np_adv/src/legacy/random_data_elements.rs +++ b/nearby/presence/np_adv/src/legacy/random_data_elements.rs @@ -89,9 +89,8 @@ impl distributions::Distribution<ActionsDataElement<Ciphertext>> for distributio ActionType::PresenceManager => bits.set_action(PresenceManager::from(true)), ActionType::InstantTethering => bits.set_action(InstantTethering::from(true)), ActionType::PhoneHub => bits.set_action(PhoneHub::from(true)), - ActionType::Finder | ActionType::FastPairSass => { - unreachable!("not ciphertext actions") - } + ActionType::Finder => bits.set_action(Finder::from(true)), + ActionType::FastPairSass => bits.set_action(FastPairSass::from(true)), } } diff --git a/nearby/presence/np_adv/tests/examples_v1.rs b/nearby/presence/np_adv/tests/examples_v1.rs index 94b9d75..6e93a3d 100644 --- a/nearby/presence/np_adv/tests/examples_v1.rs +++ b/nearby/presence/np_adv/tests/examples_v1.rs @@ -90,13 +90,13 @@ struct IdentityMetadata { } impl IdentityMetadata { - /// Serialize this identity metadata to a MsgPack byte-string. + /// Serialize this identity metadata to a json byte-string. fn to_bytes(&self) -> Vec<u8> { - rmp_serde::to_vec(&self).expect("serialization should always succeed") + serde_json::to_vec(self).expect("Identity metadata serialization is infallible") } - /// Attempt to deserialize identity metadata from a MsgPack byte-string. + /// Attempt to deserialize identity metadata from a json byte-string. fn try_from_bytes(serialized: &[u8]) -> Option<Self> { - rmp_serde::from_slice(serialized).ok() + serde_json::from_slice(serialized).ok() } } diff --git a/nearby/presence/np_adv_dynamic/src/extended.rs b/nearby/presence/np_adv_dynamic/src/extended.rs index f961bd6..5e1328c 100644 --- a/nearby/presence/np_adv_dynamic/src/extended.rs +++ b/nearby/presence/np_adv_dynamic/src/extended.rs @@ -20,11 +20,12 @@ use thiserror::Error; /// An advertisement builder for V1 advertisements where the /// presence/absence of salt is determined at run-time instead of compile-time. pub struct BoxedAdvBuilder { - adv_builder: AdvBuilder, + adv_builder: Box<AdvBuilder>, } impl From<AdvBuilder> for BoxedAdvBuilder { fn from(adv_builder: AdvBuilder) -> Self { + let adv_builder = Box::new(adv_builder); BoxedAdvBuilder { adv_builder } } } @@ -48,14 +49,59 @@ impl From<AddSectionError> for BoxedAddSectionError { } } -fn wrap_section_builder<'a, C: CryptoProvider, S: Into<BoxedSectionBuilder<'a, C>>>( +fn wrap_owning_section_builder<C: CryptoProvider, S: Into<BoxedSectionBuilder<AdvBuilder, C>>>( + maybe_section_builder: Result<S, (AdvBuilder, AddSectionError)>, +) -> Result<BoxedSectionBuilder<AdvBuilder, C>, (BoxedAdvBuilder, BoxedAddSectionError)> { + match maybe_section_builder { + Ok(section_builder) => Ok(section_builder.into()), + Err((adv_builder, err)) => Err((adv_builder.into(), err.into())), + } +} + +fn wrap_mut_ref_section_builder< + 'a, + C: CryptoProvider, + S: Into<BoxedSectionBuilder<&'a mut AdvBuilder, C>>, +>( maybe_section_builder: Result<S, AddSectionError>, -) -> Result<BoxedSectionBuilder<'a, C>, BoxedAddSectionError> { +) -> Result<BoxedSectionBuilder<&'a mut AdvBuilder, C>, BoxedAddSectionError> { let section_builder = maybe_section_builder?; Ok(section_builder.into()) } impl BoxedAdvBuilder { + /// Gets the current count of sections which have been added + /// to this advertisement builder. Does not count currently- + /// outstanding section builders. + pub fn section_count(&self) -> usize { + self.adv_builder.section_count() + } + + /// Create a section builder using the given identity, + /// taking ownership of this advertisement builder. + /// + /// Unlike `BoxedAdvBuilder#section_builder`, the returned + /// section builder will take ownership of this advertisement + /// builder, if the operation was successful. Otherwise, + /// this advertisement builder will be returned back to the + /// caller unaltered as part of the `Err` arm. + pub fn into_section_builder<C: CryptoProvider>( + self, + identity: BoxedIdentity<C>, + ) -> Result<BoxedSectionBuilder<AdvBuilder, C>, (Self, BoxedAddSectionError)> { + match identity { + BoxedIdentity::PublicIdentity => wrap_owning_section_builder( + self.adv_builder.into_section_builder(PublicSectionEncoder::default()), + ), + BoxedIdentity::MicEncrypted(ident) => { + wrap_owning_section_builder(self.adv_builder.into_section_builder(ident)) + } + BoxedIdentity::SignedEncrypted(ident) => { + wrap_owning_section_builder(self.adv_builder.into_section_builder(ident)) + } + } + } + /// Create a section builder using the given identity. /// /// Returns `Err` if the underlying advertisement builder @@ -66,16 +112,16 @@ impl BoxedAdvBuilder { pub fn section_builder<C: CryptoProvider>( &mut self, identity: BoxedIdentity<C>, - ) -> Result<BoxedSectionBuilder<C>, BoxedAddSectionError> { + ) -> Result<BoxedSectionBuilder<&mut AdvBuilder, C>, BoxedAddSectionError> { match identity { - BoxedIdentity::PublicIdentity => wrap_section_builder( + BoxedIdentity::PublicIdentity => wrap_mut_ref_section_builder( self.adv_builder.section_builder(PublicSectionEncoder::default()), ), BoxedIdentity::MicEncrypted(ident) => { - wrap_section_builder(self.adv_builder.section_builder(ident)) + wrap_mut_ref_section_builder(self.adv_builder.section_builder(ident)) } BoxedIdentity::SignedEncrypted(ident) => { - wrap_section_builder(self.adv_builder.section_builder(ident)) + wrap_mut_ref_section_builder(self.adv_builder.section_builder(ident)) } } } @@ -99,16 +145,49 @@ pub enum BoxedIdentity<C: CryptoProvider> { /// A `SectionBuilder` whose corresponding Identity /// and salted-ness is given at run-time instead of /// at compile-time. -pub enum BoxedSectionBuilder<'a, C: CryptoProvider> { +pub enum BoxedSectionBuilder<R: AsMut<AdvBuilder>, C: CryptoProvider> { /// A builder for a public section. - Public(SectionBuilder<'a, PublicSectionEncoder>), + Public(Box<SectionBuilder<R, PublicSectionEncoder>>), /// A builder for a MIC-verified section. - MicEncrypted(SectionBuilder<'a, MicEncryptedSectionEncoder<C>>), + MicEncrypted(Box<SectionBuilder<R, MicEncryptedSectionEncoder<C>>>), /// A builder for a signature-verified section. - SignedEncrypted(SectionBuilder<'a, SignedEncryptedSectionEncoder<C>>), + SignedEncrypted(Box<SectionBuilder<R, SignedEncryptedSectionEncoder<C>>>), +} + +impl<C: CryptoProvider> BoxedSectionBuilder<AdvBuilder, C> { + /// Gets the 0-based index of the section currently under construction + /// in the context of the containing advertisement. + pub fn section_index(&self) -> usize { + match self { + BoxedSectionBuilder::Public(x) => x.section_index(), + BoxedSectionBuilder::MicEncrypted(x) => x.section_index(), + BoxedSectionBuilder::SignedEncrypted(x) => x.section_index(), + } + } + /// Add this builder to the advertisement that created it, + /// returning the containing advertisement builder. + pub fn add_to_advertisement(self) -> BoxedAdvBuilder { + let adv_builder = match self { + BoxedSectionBuilder::Public(x) => x.add_to_advertisement(), + BoxedSectionBuilder::MicEncrypted(x) => x.add_to_advertisement(), + BoxedSectionBuilder::SignedEncrypted(x) => x.add_to_advertisement(), + }; + BoxedAdvBuilder::from(adv_builder) + } } -impl<'a, C: CryptoProvider> BoxedSectionBuilder<'a, C> { +impl<'a, C: CryptoProvider> BoxedSectionBuilder<&'a mut AdvBuilder, C> { + /// Add this builder to the advertisement that created it. + pub fn add_to_advertisement(self) { + match self { + BoxedSectionBuilder::Public(x) => x.add_to_advertisement(), + BoxedSectionBuilder::MicEncrypted(x) => x.add_to_advertisement(), + BoxedSectionBuilder::SignedEncrypted(x) => x.add_to_advertisement(), + } + } +} + +impl<R: AsMut<AdvBuilder>, C: CryptoProvider> BoxedSectionBuilder<R, C> { /// Returns true if this wraps a section builder which /// leverages some encrypted identity. pub fn is_encrypted(&self) -> bool { @@ -118,14 +197,20 @@ impl<'a, C: CryptoProvider> BoxedSectionBuilder<'a, C> { BoxedSectionBuilder::SignedEncrypted(_) => true, } } - /// Add this builder to the advertisement that created it. - pub fn add_to_advertisement(self) { + /// Gets the derived salt of the next DE to be added to the section, + /// if this section-builder corresponds to an encrypted section. + /// Otherwise, returns nothing. + /// + /// Suitable for scenarios (like FFI) where a closure would be inappropriate + /// for DE construction, and interaction with the client is preferred. + pub fn next_de_salt(&self) -> Option<DeSalt<C>> { match self { - BoxedSectionBuilder::Public(x) => x.add_to_advertisement(), - BoxedSectionBuilder::MicEncrypted(x) => x.add_to_advertisement(), - BoxedSectionBuilder::SignedEncrypted(x) => x.add_to_advertisement(), + BoxedSectionBuilder::Public(_) => None, + BoxedSectionBuilder::MicEncrypted(x) => Some(x.next_de_salt()), + BoxedSectionBuilder::SignedEncrypted(x) => Some(x.next_de_salt()), } } + /// Add a data element to the section with a closure that returns a `Result`. /// /// The provided `build_de` closure will be invoked with the derived salt for this DE, @@ -158,27 +243,27 @@ impl<'a, C: CryptoProvider> BoxedSectionBuilder<'a, C> { } } -impl<'a, C: CryptoProvider> From<SectionBuilder<'a, PublicSectionEncoder>> - for BoxedSectionBuilder<'a, C> +impl<R: AsMut<AdvBuilder>, C: CryptoProvider> From<SectionBuilder<R, PublicSectionEncoder>> + for BoxedSectionBuilder<R, C> { - fn from(section_builder: SectionBuilder<'a, PublicSectionEncoder>) -> Self { - BoxedSectionBuilder::Public(section_builder) + fn from(section_builder: SectionBuilder<R, PublicSectionEncoder>) -> Self { + BoxedSectionBuilder::Public(Box::new(section_builder)) } } -impl<'a, C: CryptoProvider> From<SectionBuilder<'a, MicEncryptedSectionEncoder<C>>> - for BoxedSectionBuilder<'a, C> +impl<R: AsMut<AdvBuilder>, C: CryptoProvider> From<SectionBuilder<R, MicEncryptedSectionEncoder<C>>> + for BoxedSectionBuilder<R, C> { - fn from(section_builder: SectionBuilder<'a, MicEncryptedSectionEncoder<C>>) -> Self { - BoxedSectionBuilder::MicEncrypted(section_builder) + fn from(section_builder: SectionBuilder<R, MicEncryptedSectionEncoder<C>>) -> Self { + BoxedSectionBuilder::MicEncrypted(Box::new(section_builder)) } } -impl<'a, C: CryptoProvider> From<SectionBuilder<'a, SignedEncryptedSectionEncoder<C>>> - for BoxedSectionBuilder<'a, C> +impl<R: AsMut<AdvBuilder>, C: CryptoProvider> + From<SectionBuilder<R, SignedEncryptedSectionEncoder<C>>> for BoxedSectionBuilder<R, C> { - fn from(section_builder: SectionBuilder<'a, SignedEncryptedSectionEncoder<C>>) -> Self { - BoxedSectionBuilder::SignedEncrypted(section_builder) + fn from(section_builder: SectionBuilder<R, SignedEncryptedSectionEncoder<C>>) -> Self { + BoxedSectionBuilder::SignedEncrypted(Box::new(section_builder)) } } diff --git a/nearby/presence/np_c_ffi/Cargo.lock b/nearby/presence/np_c_ffi/Cargo.lock index 836d35b..bce44c6 100644 --- a/nearby/presence/np_c_ffi/Cargo.lock +++ b/nearby/presence/np_c_ffi/Cargo.lock @@ -363,15 +363,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", + "subtle", "zeroize", ] @@ -641,6 +642,17 @@ dependencies = [ ] [[package]] +name = "np_adv_dynamic" +version = "0.1.0" +dependencies = [ + "array_view", + "crypto_provider", + "np_adv", + "sink", + "thiserror", +] + +[[package]] name = "np_c_ffi" version = "0.1.0" dependencies = [ @@ -671,6 +683,7 @@ dependencies = [ "ldt_np_adv", "lock_adapter", "np_adv", + "np_adv_dynamic", "np_hkdf", ] @@ -1011,6 +1024,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] +name = "thiserror" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] name = "tinyvec" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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 81914c9..aab2a30 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 @@ -116,6 +116,24 @@ typedef enum { } np_ffi_DeallocateResult; /** + * Discriminant for `DecryptMetadataResult`. + */ +enum np_ffi_DecryptMetadataResultKind { + /** + * The attempt to decrypt the metadata of the associated credential succeeded + * The associated payload may be obtained via + * `DecryptMetadataResult#into_success`. + */ + NP_FFI_DECRYPT_METADATA_RESULT_KIND_SUCCESS, + /** + * The attempt to decrypt the metadata failed, either the payload had no matching identity + * ie it was a public advertisement OR the decrypt attempt itself was unsuccessful + */ + NP_FFI_DECRYPT_METADATA_RESULT_KIND_ERROR, +}; +typedef uint8_t np_ffi_DecryptMetadataResultKind; + +/** * Discriminant for `DeserializeAdvertisementResult`. */ enum np_ffi_DeserializeAdvertisementResultKind { @@ -191,6 +209,34 @@ enum np_ffi_DeserializedV1IdentityKind { typedef uint8_t np_ffi_DeserializedV1IdentityKind; /** + * The DE type for an encrypted identity + */ +enum np_ffi_EncryptedIdentityType { + /** + * Identity for broadcasts to nearby devices with the same + * logged-in-account (for some account). + */ + NP_FFI_ENCRYPTED_IDENTITY_TYPE_PRIVATE = 1, + /** + * Identity for broadcasts to nearby devices which this + * device has declared to trust. + */ + NP_FFI_ENCRYPTED_IDENTITY_TYPE_TRUSTED = 2, + /** + * Identity for broadcasts to devices which have been provisioned + * offline with this device. + */ + NP_FFI_ENCRYPTED_IDENTITY_TYPE_PROVISIONED = 4, +}; +typedef uint8_t np_ffi_EncryptedIdentityType; + +enum np_ffi_GetMetadataBufferPartsResultKind { + NP_FFI_GET_METADATA_BUFFER_PARTS_RESULT_KIND_SUCCESS = 0, + NP_FFI_GET_METADATA_BUFFER_PARTS_RESULT_KIND_ERROR = 1, +}; +typedef uint8_t np_ffi_GetMetadataBufferPartsResultKind; + +/** * Discriminant of `GetV0DEResult`. */ enum np_ffi_GetV0DEResultKind { @@ -211,6 +257,47 @@ enum np_ffi_GetV0DEResultKind { typedef uint8_t np_ffi_GetV0DEResultKind; /** + * Discriminant for `GetV0IdentityDetailsResult` + */ +enum np_ffi_GetV0IdentityDetailsResultKind { + /** + * The attempt to get the identity details + * for the advertisement failed, possibly + * due to the advertisement being a public + * advertisement, or the underlying + * advertisement has already been deallocated. + */ + NP_FFI_GET_V0_IDENTITY_DETAILS_RESULT_KIND_ERROR = 0, + /** + * The attempt to get the identity details succeeded. + * The wrapped identity details may be obtained via + * `GetV0IdentityDetailsResult#into_success`. + */ + NP_FFI_GET_V0_IDENTITY_DETAILS_RESULT_KIND_SUCCESS = 1, +}; +typedef uint8_t np_ffi_GetV0IdentityDetailsResultKind; + +/** + * Discriminant for `GetV1DE16ByteSaltResult`. + */ +enum np_ffi_GetV1DE16ByteSaltResultKind { + /** + * The attempt to get the derived salt failed, possibly + * because the passed DE offset was invalid (==255), + * or because there was no salt included for the + * referenced advertisement section (i.e: it was + * a public advertisement section, or it was deallocated.) + */ + NP_FFI_GET_V1DE16_BYTE_SALT_RESULT_KIND_ERROR = 0, + /** + * A 16-byte salt for the given DE offset was successfully + * derived. + */ + NP_FFI_GET_V1DE16_BYTE_SALT_RESULT_KIND_SUCCESS = 1, +}; +typedef uint8_t np_ffi_GetV1DE16ByteSaltResultKind; + +/** * Discriminant for the `GetV1DEResult` enum. */ enum np_ffi_GetV1DEResultKind { @@ -229,6 +316,27 @@ enum np_ffi_GetV1DEResultKind { typedef uint8_t np_ffi_GetV1DEResultKind; /** + * Discriminant for `GetV1IdentityDetailsResult` + */ +enum np_ffi_GetV1IdentityDetailsResultKind { + /** + * The attempt to get the identity details + * for the section failed, possibly + * due to the section being a public + * section, or the underlying + * advertisement has already been deallocated. + */ + NP_FFI_GET_V1_IDENTITY_DETAILS_RESULT_KIND_ERROR = 0, + /** + * The attempt to get the identity details succeeded. + * The wrapped identity details may be obtained via + * `GetV1IdentityDetailsResult#into_success`. + */ + NP_FFI_GET_V1_IDENTITY_DETAILS_RESULT_KIND_SUCCESS = 1, +}; +typedef uint8_t np_ffi_GetV1IdentityDetailsResultKind; + +/** * Discriminant for `GetV1SectionResult` */ enum np_ffi_GetV1SectionResultKind { @@ -296,6 +404,23 @@ enum np_ffi_V0DataElementKind { typedef uint8_t np_ffi_V0DataElementKind; /** + * Information about the verification scheme used + * for verifying the integrity of the contents + * of a decrypted section. + */ +enum np_ffi_V1VerificationMode { + /** + * Message integrity code verification. + */ + NP_FFI_V1_VERIFICATION_MODE_MIC = 0, + /** + * Signature verification. + */ + NP_FFI_V1_VERIFICATION_MODE_SIGNATURE = 1, +}; +typedef uint8_t np_ffi_V1VerificationMode; + +/** *A `#[repr(C)]` handle to a value of type `super::CredentialBookInternals`. */ typedef struct { @@ -394,6 +519,52 @@ typedef struct { } np_ffi_V1MatchableCredential; /** + *A `#[repr(C)]` handle to a value of type `super::DecryptedMetadataInternals`. + */ +typedef struct { + uint64_t handle_id; +} np_ffi_DecryptedMetadata; + +/** + * The result of decrypting metadata from either a V0Payload or DeserializedV1Section + */ +typedef enum { + NP_FFI_DECRYPT_METADATA_RESULT_SUCCESS, + NP_FFI_DECRYPT_METADATA_RESULT_ERROR, +} np_ffi_DecryptMetadataResult_Tag; + +typedef struct { + np_ffi_DecryptMetadataResult_Tag tag; + union { + struct { + np_ffi_DecryptedMetadata success; + }; + }; +} np_ffi_DecryptMetadataResult; + +/** + * The pointer and length of the decrypted metadata byte buffer + */ +typedef struct { + const uint8_t *ptr; + uintptr_t len; +} np_ffi_MetadataBufferParts; + +typedef enum { + NP_FFI_GET_METADATA_BUFFER_PARTS_RESULT_SUCCESS, + NP_FFI_GET_METADATA_BUFFER_PARTS_RESULT_ERROR, +} np_ffi_GetMetadataBufferPartsResult_Tag; + +typedef struct { + np_ffi_GetMetadataBufferPartsResult_Tag tag; + union { + struct { + np_ffi_MetadataBufferParts success; + }; + }; +} np_ffi_GetMetadataBufferPartsResult; + +/** *A `#[repr(C)]` handle to a value of type `super::V0PayloadInternals`. */ typedef struct { @@ -576,6 +747,49 @@ typedef struct { } np_ffi_GetV0DEResult; /** + * Information about the identity which matched a + * decrypted V0 advertisement. + */ +typedef struct { + /** + * The identity type (private/provisioned/trusted) + */ + np_ffi_EncryptedIdentityType identity_type; + /** + * The ID of the credential which + * matched the deserialized adv + */ + uint32_t cred_id; + /** + * The 14-byte legacy metadata key + */ + uint8_t metadata_key[14]; + /** + * The 2-byte advertisement salt + */ + uint8_t salt[2]; +} np_ffi_DeserializedV0IdentityDetails; + +/** + * The result of attempting to get the identity details + * for a V0 advertisement via + * `DeserializedV0Advertisement#get_identity_details`. + */ +typedef enum { + NP_FFI_GET_V0_IDENTITY_DETAILS_RESULT_ERROR, + NP_FFI_GET_V0_IDENTITY_DETAILS_RESULT_SUCCESS, +} np_ffi_GetV0IdentityDetailsResult_Tag; + +typedef struct { + np_ffi_GetV0IdentityDetailsResult_Tag tag; + union { + struct { + np_ffi_DeserializedV0IdentityDetails success; + }; + }; +} np_ffi_GetV0IdentityDetailsResult; + +/** * Handle to a deserialized V1 section */ typedef struct { @@ -683,6 +897,75 @@ typedef struct { } np_ffi_GetV1DEResult; /** + * Information about the identity which matched + * a decrypted V1 section. + */ +typedef struct { + /** + * The identity type (private/provisioned/trusted) + */ + np_ffi_EncryptedIdentityType identity_type; + /** + * The verification mode (MIC/Signature) which + * was used to verify the decrypted adv contents. + */ + np_ffi_V1VerificationMode verification_mode; + /** + * The ID of the credential which + * matched the deserialized section. + */ + uint32_t cred_id; + /** + * The 16-byte metadata key. + */ + uint8_t metadata_key[16]; +} np_ffi_DeserializedV1IdentityDetails; + +/** + * The result of attempting to get the identity details + * for a V1 advertisement section via + * `DeserializedV1Advertisement#get_identity_details`. + */ +typedef enum { + NP_FFI_GET_V1_IDENTITY_DETAILS_RESULT_ERROR, + NP_FFI_GET_V1_IDENTITY_DETAILS_RESULT_SUCCESS, +} np_ffi_GetV1IdentityDetailsResult_Tag; + +typedef struct { + np_ffi_GetV1IdentityDetailsResult_Tag tag; + union { + struct { + np_ffi_DeserializedV1IdentityDetails success; + }; + }; +} np_ffi_GetV1IdentityDetailsResult; + +/** + * A FFI safe wrapper of a fixed size array + */ +typedef struct { + uint8_t _0[16]; +} np_ffi_FixedSizeArray_16; + +/** + * The result of attempting to get a derived 16-byte salt + * for a given DE within a section. + */ +typedef enum { + NP_FFI_GET_V1DE16_BYTE_SALT_RESULT_ERROR, + NP_FFI_GET_V1DE16_BYTE_SALT_RESULT_SUCCESS, +} np_ffi_GetV1DE16ByteSaltResult_Tag; + +typedef struct { + np_ffi_GetV1DE16ByteSaltResult_Tag tag; + union { + struct { + np_ffi_FixedSizeArray_16 success; + }; + }; +} np_ffi_GetV1DE16ByteSaltResult; + +/** * Overrides the global panic handler to be used when NP C FFI calls panic. * This method will only have an effect on the global panic-handler * the first time it's called, and this method will return `true` @@ -854,6 +1137,42 @@ np_ffi_AddCredentialToSlabResult np_ffi_CredentialSlab_add_v1_credential(np_ffi_ np_ffi_V1MatchableCredential v1_cred); /** + * Frees the underlying resources of the decrypted metadata buffer + */ +np_ffi_DeallocateResult np_ffi_deallocate_DecryptedMetadata(np_ffi_DecryptedMetadata metadata); + +/** + * Gets the tag of a `DecryptMetadataResult` tagged-union. On success the wrapped identity + * details may be obtained via `DecryptMetadataResult#into_success`. + */ +np_ffi_DecryptMetadataResultKind np_ffi_DecryptMetadataResult_kind(np_ffi_DecryptMetadataResult result); + +/** + * Casts a `DecryptMetadataResult` to the `Success` variant, panicking in the + * case where the passed value is of a different enum variant. + */ +np_ffi_DecryptedMetadata np_ffi_DecryptMetadataResult_into_SUCCESS(np_ffi_DecryptMetadataResult result); + +/** + * Gets the pointer and length of the heap allocated byte buffer of decrypted metadata + */ +np_ffi_GetMetadataBufferPartsResult np_ffi_DecryptedMetadata_get_metadata_buffer_parts(np_ffi_DecryptedMetadata metadata); + +/** + * Gets the tag of a `GetMetadataBufferPartsResult` tagged-union. On success the wrapped identity + * details may be obtained via `GetMetadataBufferPartsResult#into_success`. + */ +np_ffi_GetMetadataBufferPartsResultKind np_ffi_GetMetadataBufferPartsResult_kind(np_ffi_GetMetadataBufferPartsResult result); + +/** + * Casts a `GetMetadataBufferPartsResult` to the `Success` variant, panicking in the + * case where the passed value is of a different enum variant. This returns the pointer and length + * of the byte buffer containing the decrypted metadata. There can be a data-race between attempts + * to access the contents of the buffer and attempts to free the handle from different threads. + */ +np_ffi_MetadataBufferParts np_ffi_GetMetadataBufferPartsResult_into_SUCCESS(np_ffi_GetMetadataBufferPartsResult result); + +/** * Attempts to deserialize an advertisement with the given service-data * payload (presumed to be under the NP service UUID) using credentials * pulled from the given credential-book. @@ -933,6 +1252,29 @@ np_ffi_DeallocateResult np_ffi_deallocate_legible_v0_advertisement(np_ffi_Legibl np_ffi_GetV0DEResult np_ffi_V0Payload_get_de(np_ffi_V0Payload payload, uint8_t index); /** + * Attempts to decrypt the metadata for the matched credential for this V0 payload (if any) + */ +np_ffi_DecryptMetadataResult np_ffi_V0Payload_decrypt_metadata(np_ffi_V0Payload payload); + +/** + * Gets the identity details for this V0 payload, or returns an error if this payload does not have + * any associated identity (public advertisement) + */ +np_ffi_GetV0IdentityDetailsResult np_ffi_V0Payload_get_identity_details(np_ffi_V0Payload payload); + +/** + * Gets the tag of a `GetV0IdentityDetailsResult` tagged-union. On success the wrapped identity + * details may be obtained via `GetV0IdentityDetailsResult#into_success`. + */ +np_ffi_GetV0IdentityDetailsResultKind np_ffi_GetV0IdentityDetailsResult_kind(np_ffi_GetV0IdentityDetailsResult result); + +/** + * Casts a `GetV0IdentityDetailsResult` to the `Success` variant, panicking in the + * case where the passed value is of a different enum variant. + */ +np_ffi_DeserializedV0IdentityDetails np_ffi_GetV0IdentityDetailsResult_into_SUCCESS(np_ffi_GetV0IdentityDetailsResult result); + +/** * Deallocates any internal data of a `V0Payload` */ np_ffi_DeallocateResult np_ffi_deallocate_v0_payload(np_ffi_V0Payload payload); @@ -1029,12 +1371,55 @@ np_ffi_GetV1DEResult np_ffi_DeserializedV1Section_get_de(np_ffi_DeserializedV1Se uint8_t de_index); /** + * Gets the identity details used to decrypt this V1 section, or returns an error if this payload + * does not have any associated identity (public advertisement) + */ +np_ffi_GetV1IdentityDetailsResult np_ffi_DeserializedV1Section_get_identity_details(np_ffi_DeserializedV1Section section); + +/** + * Gets the tag of a `GetV1IdentityDetailsResult` tagged-union. On success the wrapped identity + * details may be obtained via `GetV0IdentityDetailsResult#into_success`. + */ +np_ffi_GetV1IdentityDetailsResultKind np_ffi_GetV1IdentityDetailsResult_kind(np_ffi_GetV1IdentityDetailsResult result); + +/** + * Casts a `GetV1IdentityDetailsResult` to the `Success` variant, panicking in the + * case where the passed value is of a different enum variant. + */ +np_ffi_DeserializedV1IdentityDetails np_ffi_GetV1IdentityDetailsResult_into_SUCCESS(np_ffi_GetV1IdentityDetailsResult result); + +/** + * Attempts to decrypt the metadata for the matched credential for this V0 payload (if any) + */ +np_ffi_DecryptMetadataResult np_ffi_DeserializedV1Section_decrypt_metadata(np_ffi_DeserializedV1Section section); + +/** + * Attempts to derive a 16-byte DE salt for a DE in this section with the given DE offset. This + * operation may fail if the passed offset is 255 (causes overflow) or if the section + * is leveraging a public identity, and hence, doesn't have an associated salt. + */ +np_ffi_GetV1DE16ByteSaltResult np_ffi_DeserializedV1Section_derive_16_byte_salt_for_offset(np_ffi_DeserializedV1Section section, + uint8_t offset); + +/** + * Gets the tag of a `GetV1DE16ByteSaltResult` tagged-union. On success the wrapped identity + * details may be obtained via `GetV1DE16ByteSaltResult#into_success`. + */ +np_ffi_GetV1DE16ByteSaltResultKind np_ffi_GetV1DE16ByteSaltResult_kind(np_ffi_GetV1DE16ByteSaltResult result); + +/** + * Casts a `GetV1DE16ByteSaltResult` to the `Success` variant, panicking in the + * case where the passed value is of a different enum variant. + */ +np_ffi_FixedSizeArray_16 np_ffi_GetV1DE16ByteSaltResult_into_SUCCESS(np_ffi_GetV1DE16ByteSaltResult result); + +/** * Gets the tag of the `GetV1DEResult` tagged-union. */ np_ffi_GetV1DEResultKind np_ffi_GetV1DEResult_kind(np_ffi_GetV1DEResult result); /** - * Casts a `GetV1DEResult` to the `Success` vartiant, panicking in the + * Casts a `GetV1DEResult` to the `Success` variant, panicking in the * case where the passed value is of a different enum variant. */ np_ffi_V1DataElement np_ffi_GetV1DEResult_into_SUCCESS(np_ffi_GetV1DEResult result); diff --git a/nearby/presence/np_c_ffi/include/cpp/np_cpp_ffi_functions.h b/nearby/presence/np_c_ffi/include/cpp/np_cpp_ffi_functions.h index ad3ec24..ffd63b0 100644 --- a/nearby/presence/np_c_ffi/include/cpp/np_cpp_ffi_functions.h +++ b/nearby/presence/np_c_ffi/include/cpp/np_cpp_ffi_functions.h @@ -178,6 +178,30 @@ AddCredentialToSlabResult np_ffi_CredentialSlab_add_v0_credential(CredentialSlab AddCredentialToSlabResult np_ffi_CredentialSlab_add_v1_credential(CredentialSlab credential_slab, V1MatchableCredential v1_cred); +/// Frees the underlying resources of the decrypted metadata buffer +DeallocateResult np_ffi_deallocate_DecryptedMetadata(DecryptedMetadata metadata); + +/// Gets the tag of a `DecryptMetadataResult` tagged-union. On success the wrapped identity +/// details may be obtained via `DecryptMetadataResult#into_success`. +DecryptMetadataResultKind np_ffi_DecryptMetadataResult_kind(DecryptMetadataResult result); + +/// Casts a `DecryptMetadataResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. +DecryptedMetadata np_ffi_DecryptMetadataResult_into_SUCCESS(DecryptMetadataResult result); + +/// Gets the pointer and length of the heap allocated byte buffer of decrypted metadata +GetMetadataBufferPartsResult np_ffi_DecryptedMetadata_get_metadata_buffer_parts(DecryptedMetadata metadata); + +/// Gets the tag of a `GetMetadataBufferPartsResult` tagged-union. On success the wrapped identity +/// details may be obtained via `GetMetadataBufferPartsResult#into_success`. +GetMetadataBufferPartsResultKind np_ffi_GetMetadataBufferPartsResult_kind(GetMetadataBufferPartsResult result); + +/// Casts a `GetMetadataBufferPartsResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. This returns the pointer and length +/// of the byte buffer containing the decrypted metadata. There can be a data-race between attempts +/// to access the contents of the buffer and attempts to free the handle from different threads. +MetadataBufferParts np_ffi_GetMetadataBufferPartsResult_into_SUCCESS(GetMetadataBufferPartsResult result); + /// Attempts to deserialize an advertisement with the given service-data /// payload (presumed to be under the NP service UUID) using credentials /// pulled from the given credential-book. @@ -229,6 +253,21 @@ DeallocateResult np_ffi_deallocate_legible_v0_advertisement(LegibleDeserializedV /// Attempts to get the data-element with the given index in the passed v0 adv payload GetV0DEResult np_ffi_V0Payload_get_de(V0Payload payload, uint8_t index); +/// Attempts to decrypt the metadata for the matched credential for this V0 payload (if any) +DecryptMetadataResult np_ffi_V0Payload_decrypt_metadata(V0Payload payload); + +/// Gets the identity details for this V0 payload, or returns an error if this payload does not have +/// any associated identity (public advertisement) +GetV0IdentityDetailsResult np_ffi_V0Payload_get_identity_details(V0Payload payload); + +/// Gets the tag of a `GetV0IdentityDetailsResult` tagged-union. On success the wrapped identity +/// details may be obtained via `GetV0IdentityDetailsResult#into_success`. +GetV0IdentityDetailsResultKind np_ffi_GetV0IdentityDetailsResult_kind(GetV0IdentityDetailsResult result); + +/// Casts a `GetV0IdentityDetailsResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. +DeserializedV0IdentityDetails np_ffi_GetV0IdentityDetailsResult_into_SUCCESS(GetV0IdentityDetailsResult result); + /// Deallocates any internal data of a `V0Payload` DeallocateResult np_ffi_deallocate_v0_payload(V0Payload payload); @@ -290,10 +329,39 @@ DeserializedV1IdentityKind np_ffi_DeserializedV1Section_get_identity_kind(Deseri /// Gets the data-element with the given index in the passed section. GetV1DEResult np_ffi_DeserializedV1Section_get_de(DeserializedV1Section section, uint8_t de_index); +/// Gets the identity details used to decrypt this V1 section, or returns an error if this payload +/// does not have any associated identity (public advertisement) +GetV1IdentityDetailsResult np_ffi_DeserializedV1Section_get_identity_details(DeserializedV1Section section); + +/// Gets the tag of a `GetV1IdentityDetailsResult` tagged-union. On success the wrapped identity +/// details may be obtained via `GetV0IdentityDetailsResult#into_success`. +GetV1IdentityDetailsResultKind np_ffi_GetV1IdentityDetailsResult_kind(GetV1IdentityDetailsResult result); + +/// Casts a `GetV1IdentityDetailsResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. +DeserializedV1IdentityDetails np_ffi_GetV1IdentityDetailsResult_into_SUCCESS(GetV1IdentityDetailsResult result); + +/// Attempts to decrypt the metadata for the matched credential for this V0 payload (if any) +DecryptMetadataResult np_ffi_DeserializedV1Section_decrypt_metadata(DeserializedV1Section section); + +/// Attempts to derive a 16-byte DE salt for a DE in this section with the given DE offset. This +/// operation may fail if the passed offset is 255 (causes overflow) or if the section +/// is leveraging a public identity, and hence, doesn't have an associated salt. +GetV1DE16ByteSaltResult np_ffi_DeserializedV1Section_derive_16_byte_salt_for_offset(DeserializedV1Section section, + uint8_t offset); + +/// Gets the tag of a `GetV1DE16ByteSaltResult` tagged-union. On success the wrapped identity +/// details may be obtained via `GetV1DE16ByteSaltResult#into_success`. +GetV1DE16ByteSaltResultKind np_ffi_GetV1DE16ByteSaltResult_kind(GetV1DE16ByteSaltResult result); + +/// Casts a `GetV1DE16ByteSaltResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. +FixedSizeArray<16> np_ffi_GetV1DE16ByteSaltResult_into_SUCCESS(GetV1DE16ByteSaltResult result); + /// Gets the tag of the `GetV1DEResult` tagged-union. GetV1DEResultKind np_ffi_GetV1DEResult_kind(GetV1DEResult result); -/// Casts a `GetV1DEResult` to the `Success` vartiant, panicking in the +/// Casts a `GetV1DEResult` to the `Success` variant, panicking in the /// case where the passed value is of a different enum variant. V1DataElement np_ffi_GetV1DEResult_into_SUCCESS(GetV1DEResult result); 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 d39bb70..b5908ef 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 @@ -87,6 +87,17 @@ enum class DeallocateResult { Success = 1, }; +/// Discriminant for `DecryptMetadataResult`. +enum class DecryptMetadataResultKind : uint8_t { + /// The attempt to decrypt the metadata of the associated credential succeeded + /// The associated payload may be obtained via + /// `DecryptMetadataResult#into_success`. + Success, + /// The attempt to decrypt the metadata failed, either the payload had no matching identity + /// ie it was a public advertisement OR the decrypt attempt itself was unsuccessful + Error, +}; + /// Discriminant for `DeserializeAdvertisementResult`. enum class DeserializeAdvertisementResultKind : uint8_t { /// Deserializing the advertisement failed, for some reason or another. @@ -132,6 +143,24 @@ enum class DeserializedV1IdentityKind : uint8_t { Decrypted = 1, }; +/// The DE type for an encrypted identity +enum class EncryptedIdentityType : uint8_t { + /// Identity for broadcasts to nearby devices with the same + /// logged-in-account (for some account). + Private = 1, + /// Identity for broadcasts to nearby devices which this + /// device has declared to trust. + Trusted = 2, + /// Identity for broadcasts to devices which have been provisioned + /// offline with this device. + Provisioned = 4, +}; + +enum class GetMetadataBufferPartsResultKind : uint8_t { + Success = 0, + Error = 1, +}; + /// Discriminant of `GetV0DEResult`. enum class GetV0DEResultKind : uint8_t { /// The attempt to get the DE succeeded. @@ -145,6 +174,33 @@ enum class GetV0DEResultKind : uint8_t { Error = 1, }; +/// Discriminant for `GetV0IdentityDetailsResult` +enum class GetV0IdentityDetailsResultKind : uint8_t { + /// The attempt to get the identity details + /// for the advertisement failed, possibly + /// due to the advertisement being a public + /// advertisement, or the underlying + /// advertisement has already been deallocated. + Error = 0, + /// The attempt to get the identity details succeeded. + /// The wrapped identity details may be obtained via + /// `GetV0IdentityDetailsResult#into_success`. + Success = 1, +}; + +/// Discriminant for `GetV1DE16ByteSaltResult`. +enum class GetV1DE16ByteSaltResultKind : uint8_t { + /// The attempt to get the derived salt failed, possibly + /// because the passed DE offset was invalid (==255), + /// or because there was no salt included for the + /// referenced advertisement section (i.e: it was + /// a public advertisement section, or it was deallocated.) + Error = 0, + /// A 16-byte salt for the given DE offset was successfully + /// derived. + Success = 1, +}; + /// Discriminant for the `GetV1DEResult` enum. enum class GetV1DEResultKind : uint8_t { /// Attempting to get the DE at the given position failed, @@ -156,6 +212,20 @@ enum class GetV1DEResultKind : uint8_t { Success = 1, }; +/// Discriminant for `GetV1IdentityDetailsResult` +enum class GetV1IdentityDetailsResultKind : uint8_t { + /// The attempt to get the identity details + /// for the section failed, possibly + /// due to the section being a public + /// section, or the underlying + /// advertisement has already been deallocated. + Error = 0, + /// The attempt to get the identity details succeeded. + /// The wrapped identity details may be obtained via + /// `GetV1IdentityDetailsResult#into_success`. + Success = 1, +}; + /// Discriminant for `GetV1SectionResult` enum class GetV1SectionResultKind : uint8_t { /// The attempt to get the section failed, @@ -200,6 +270,16 @@ enum class V0DataElementKind : uint8_t { Actions = 1, }; +/// Information about the verification scheme used +/// for verifying the integrity of the contents +/// of a decrypted section. +enum class V1VerificationMode : uint8_t { + /// Message integrity code verification. + Mic = 0, + /// Signature verification. + Signature = 1, +}; + ///A `#[repr(C)]` handle to a value of type `super::CredentialBookInternals`. struct CredentialBook { uint64_t handle_id; @@ -285,6 +365,50 @@ struct V1MatchableCredential { FfiMatchedCredential matched_cred; }; +///A `#[repr(C)]` handle to a value of type `super::DecryptedMetadataInternals`. +struct DecryptedMetadata { + uint64_t handle_id; +}; + +/// The result of decrypting metadata from either a V0Payload or DeserializedV1Section +struct DecryptMetadataResult { + enum class Tag { + Success, + Error, + }; + + struct Success_Body { + DecryptedMetadata _0; + }; + + Tag tag; + union { + Success_Body success; + }; +}; + +/// The pointer and length of the decrypted metadata byte buffer +struct MetadataBufferParts { + const uint8_t *ptr; + uintptr_t len; +}; + +struct GetMetadataBufferPartsResult { + enum class Tag { + Success, + Error, + }; + + struct Success_Body { + MetadataBufferParts _0; + }; + + Tag tag; + union { + Success_Body success; + }; +}; + ///A `#[repr(C)]` handle to a value of type `super::V0PayloadInternals`. struct V0Payload { uint64_t handle_id; @@ -449,6 +573,39 @@ struct GetV0DEResult { }; }; +/// Information about the identity which matched a +/// decrypted V0 advertisement. +struct DeserializedV0IdentityDetails { + /// The identity type (private/provisioned/trusted) + EncryptedIdentityType identity_type; + /// The ID of the credential which + /// matched the deserialized adv + uint32_t cred_id; + /// The 14-byte legacy metadata key + uint8_t metadata_key[14]; + /// The 2-byte advertisement salt + uint8_t salt[2]; +}; + +/// The result of attempting to get the identity details +/// for a V0 advertisement via +/// `DeserializedV0Advertisement#get_identity_details`. +struct GetV0IdentityDetailsResult { + enum class Tag { + Error, + Success, + }; + + struct Success_Body { + DeserializedV0IdentityDetails _0; + }; + + Tag tag; + union { + Success_Body success; + }; +}; + /// Handle to a deserialized V1 section struct DeserializedV1Section { LegibleV1Sections legible_sections_handle; @@ -531,5 +688,63 @@ struct GetV1DEResult { }; }; +/// Information about the identity which matched +/// a decrypted V1 section. +struct DeserializedV1IdentityDetails { + /// The identity type (private/provisioned/trusted) + EncryptedIdentityType identity_type; + /// The verification mode (MIC/Signature) which + /// was used to verify the decrypted adv contents. + V1VerificationMode verification_mode; + /// The ID of the credential which + /// matched the deserialized section. + uint32_t cred_id; + /// The 16-byte metadata key. + uint8_t metadata_key[16]; +}; + +/// The result of attempting to get the identity details +/// for a V1 advertisement section via +/// `DeserializedV1Advertisement#get_identity_details`. +struct GetV1IdentityDetailsResult { + enum class Tag { + Error, + Success, + }; + + struct Success_Body { + DeserializedV1IdentityDetails _0; + }; + + Tag tag; + union { + Success_Body success; + }; +}; + +/// A FFI safe wrapper of a fixed size array +template<uintptr_t N> +struct FixedSizeArray { + uint8_t _0[N]; +}; + +/// The result of attempting to get a derived 16-byte salt +/// for a given DE within a section. +struct GetV1DE16ByteSaltResult { + enum class Tag { + Error, + Success, + }; + + struct Success_Body { + FixedSizeArray<16> _0; + }; + + Tag tag; + union { + Success_Body success; + }; +}; + } // namespace internal } // namespace np_ffi diff --git a/nearby/presence/np_c_ffi/src/credentials.rs b/nearby/presence/np_c_ffi/src/credentials.rs index 70949a6..3cbd76f 100644 --- a/nearby/presence/np_c_ffi/src/credentials.rs +++ b/nearby/presence/np_c_ffi/src/credentials.rs @@ -19,6 +19,11 @@ use np_ffi_core::common::*; use np_ffi_core::credentials::credential_book::CredentialBook; use np_ffi_core::credentials::credential_slab::CredentialSlab; use np_ffi_core::credentials::*; +use np_ffi_core::deserialize::decrypted_metadata::DecryptedMetadata; +use np_ffi_core::deserialize::{ + DecryptMetadataResult, DecryptMetadataResultKind, GetMetadataBufferPartsResult, + GetMetadataBufferPartsResultKind, MetadataBufferParts, +}; use np_ffi_core::utils::FfiEnum; /// Allocates a new credential-book from the given slab, returning a handle @@ -157,3 +162,57 @@ pub extern "C" fn np_ffi_CredentialSlab_add_v1_credential( let matched_credential = MatchedCredential::new(v1_cred.matched_cred.cred_id, metadata_slice); credential_slab.add_v1(v1_cred.discovery_cred, matched_credential) } + +/// Frees the underlying resources of the decrypted metadata buffer +#[no_mangle] +pub extern "C" fn np_ffi_deallocate_DecryptedMetadata( + metadata: DecryptedMetadata, +) -> DeallocateResult { + metadata.deallocate_metadata() +} + +/// Gets the tag of a `DecryptMetadataResult` tagged-union. On success the wrapped identity +/// details may be obtained via `DecryptMetadataResult#into_success`. +#[no_mangle] +pub extern "C" fn np_ffi_DecryptMetadataResult_kind( + result: DecryptMetadataResult, +) -> DecryptMetadataResultKind { + result.kind() +} + +/// Casts a `DecryptMetadataResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. +#[no_mangle] +pub extern "C" fn np_ffi_DecryptMetadataResult_into_SUCCESS( + result: DecryptMetadataResult, +) -> DecryptedMetadata { + unwrap(result.into_success(), PanicReason::EnumCastFailed) +} + +/// Gets the pointer and length of the heap allocated byte buffer of decrypted metadata +#[no_mangle] +pub extern "C" fn np_ffi_DecryptedMetadata_get_metadata_buffer_parts( + metadata: DecryptedMetadata, +) -> GetMetadataBufferPartsResult { + metadata.get_metadata_buffer_parts() +} + +/// Gets the tag of a `GetMetadataBufferPartsResult` tagged-union. On success the wrapped identity +/// details may be obtained via `GetMetadataBufferPartsResult#into_success`. +#[no_mangle] +pub extern "C" fn np_ffi_GetMetadataBufferPartsResult_kind( + result: GetMetadataBufferPartsResult, +) -> GetMetadataBufferPartsResultKind { + result.kind() +} + +/// Casts a `GetMetadataBufferPartsResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. This returns the pointer and length +/// of the byte buffer containing the decrypted metadata. There can be a data-race between attempts +/// to access the contents of the buffer and attempts to free the handle from different threads. +#[no_mangle] +pub extern "C" fn np_ffi_GetMetadataBufferPartsResult_into_SUCCESS( + result: GetMetadataBufferPartsResult, +) -> MetadataBufferParts { + unwrap(result.into_success(), PanicReason::EnumCastFailed) +} diff --git a/nearby/presence/np_c_ffi/src/deserialize/v0.rs b/nearby/presence/np_c_ffi/src/deserialize/v0.rs index 28bec8a..7a460a2 100644 --- a/nearby/presence/np_c_ffi/src/deserialize/v0.rs +++ b/nearby/presence/np_c_ffi/src/deserialize/v0.rs @@ -16,6 +16,7 @@ use crate::{panic, unwrap, PanicReason}; use np_ffi_core::common::DeallocateResult; use np_ffi_core::deserialize::v0::v0_payload::V0Payload; use np_ffi_core::deserialize::v0::*; +use np_ffi_core::deserialize::DecryptMetadataResult; use np_ffi_core::utils::FfiEnum; /// Gets the tag of a `DeserializedV0Advertisement` tagged-union. @@ -74,6 +75,39 @@ pub extern "C" fn np_ffi_V0Payload_get_de(payload: V0Payload, index: u8) -> GetV payload.get_de(index) } +/// Attempts to decrypt the metadata for the matched credential for this V0 payload (if any) +#[no_mangle] +pub extern "C" fn np_ffi_V0Payload_decrypt_metadata(payload: V0Payload) -> DecryptMetadataResult { + payload.decrypt_metadata() +} + +/// Gets the identity details for this V0 payload, or returns an error if this payload does not have +/// any associated identity (public advertisement) +#[no_mangle] +pub extern "C" fn np_ffi_V0Payload_get_identity_details( + payload: V0Payload, +) -> GetV0IdentityDetailsResult { + payload.get_identity_details() +} + +/// Gets the tag of a `GetV0IdentityDetailsResult` tagged-union. On success the wrapped identity +/// details may be obtained via `GetV0IdentityDetailsResult#into_success`. +#[no_mangle] +pub extern "C" fn np_ffi_GetV0IdentityDetailsResult_kind( + result: GetV0IdentityDetailsResult, +) -> GetV0IdentityDetailsResultKind { + result.kind() +} + +/// Casts a `GetV0IdentityDetailsResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. +#[no_mangle] +pub extern "C" fn np_ffi_GetV0IdentityDetailsResult_into_SUCCESS( + result: GetV0IdentityDetailsResult, +) -> DeserializedV0IdentityDetails { + unwrap(result.into_success(), PanicReason::EnumCastFailed) +} + /// Deallocates any internal data of a `V0Payload` #[no_mangle] pub extern "C" fn np_ffi_deallocate_v0_payload(payload: V0Payload) -> DeallocateResult { diff --git a/nearby/presence/np_c_ffi/src/deserialize/v1.rs b/nearby/presence/np_c_ffi/src/deserialize/v1.rs index dc682a3..598ce9c 100644 --- a/nearby/presence/np_c_ffi/src/deserialize/v1.rs +++ b/nearby/presence/np_c_ffi/src/deserialize/v1.rs @@ -13,7 +13,9 @@ // limitations under the License. use crate::{unwrap, PanicReason}; +use np_ffi_core::common::FixedSizeArray; use np_ffi_core::deserialize::v1::*; +use np_ffi_core::deserialize::DecryptMetadataResult; use np_ffi_core::utils::FfiEnum; /// Gets the number of legible sections on a deserialized V1 advertisement. @@ -86,13 +88,77 @@ pub extern "C" fn np_ffi_DeserializedV1Section_get_de( section.get_de(de_index) } +/// Gets the identity details used to decrypt this V1 section, or returns an error if this payload +/// does not have any associated identity (public advertisement) +#[no_mangle] +pub extern "C" fn np_ffi_DeserializedV1Section_get_identity_details( + section: DeserializedV1Section, +) -> GetV1IdentityDetailsResult { + section.get_identity_details() +} + +/// Gets the tag of a `GetV1IdentityDetailsResult` tagged-union. On success the wrapped identity +/// details may be obtained via `GetV0IdentityDetailsResult#into_success`. +#[no_mangle] +pub extern "C" fn np_ffi_GetV1IdentityDetailsResult_kind( + result: GetV1IdentityDetailsResult, +) -> GetV1IdentityDetailsResultKind { + result.kind() +} + +/// Casts a `GetV1IdentityDetailsResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. +#[no_mangle] +pub extern "C" fn np_ffi_GetV1IdentityDetailsResult_into_SUCCESS( + result: GetV1IdentityDetailsResult, +) -> DeserializedV1IdentityDetails { + unwrap(result.into_success(), PanicReason::EnumCastFailed) +} + +/// Attempts to decrypt the metadata for the matched credential for this V0 payload (if any) +#[no_mangle] +pub extern "C" fn np_ffi_DeserializedV1Section_decrypt_metadata( + section: DeserializedV1Section, +) -> DecryptMetadataResult { + section.decrypt_metadata() +} + +/// Attempts to derive a 16-byte DE salt for a DE in this section with the given DE offset. This +/// operation may fail if the passed offset is 255 (causes overflow) or if the section +/// is leveraging a public identity, and hence, doesn't have an associated salt. +#[no_mangle] +pub extern "C" fn np_ffi_DeserializedV1Section_derive_16_byte_salt_for_offset( + section: DeserializedV1Section, + offset: u8, +) -> GetV1DE16ByteSaltResult { + section.derive_16_byte_salt_for_offset(offset) +} + +/// Gets the tag of a `GetV1DE16ByteSaltResult` tagged-union. On success the wrapped identity +/// details may be obtained via `GetV1DE16ByteSaltResult#into_success`. +#[no_mangle] +pub extern "C" fn np_ffi_GetV1DE16ByteSaltResult_kind( + result: GetV1DE16ByteSaltResult, +) -> GetV1DE16ByteSaltResultKind { + result.kind() +} + +/// Casts a `GetV1DE16ByteSaltResult` to the `Success` variant, panicking in the +/// case where the passed value is of a different enum variant. +#[no_mangle] +pub extern "C" fn np_ffi_GetV1DE16ByteSaltResult_into_SUCCESS( + result: GetV1DE16ByteSaltResult, +) -> FixedSizeArray<16> { + unwrap(result.into_success(), PanicReason::EnumCastFailed) +} + /// Gets the tag of the `GetV1DEResult` tagged-union. #[no_mangle] pub extern "C" fn np_ffi_GetV1DEResult_kind(result: GetV1DEResult) -> GetV1DEResultKind { result.kind() } -/// Casts a `GetV1DEResult` to the `Success` vartiant, panicking in the +/// Casts a `GetV1DEResult` to the `Success` variant, panicking in the /// case where the passed value is of a different enum variant. #[no_mangle] pub extern "C" fn np_ffi_GetV1DEResult_into_SUCCESS(result: GetV1DEResult) -> V1DataElement { diff --git a/nearby/presence/np_c_ffi/src/lib.rs b/nearby/presence/np_c_ffi/src/lib.rs index 84e9859..50e74b6 100644 --- a/nearby/presence/np_c_ffi/src/lib.rs +++ b/nearby/presence/np_c_ffi/src/lib.rs @@ -87,8 +87,6 @@ impl PanicHandler { } } -//TODO: use a std library RwLock if we have that available, spin is only needed for no_std and -// won't be as performant static PANIC_HANDLER: RwLock<PanicHandler> = RwLock::new(PanicHandler::new()); pub(crate) fn panic(reason: PanicReason) -> ! { diff --git a/nearby/presence/np_cpp_ffi/include/nearby_protocol.h b/nearby/presence/np_cpp_ffi/include/nearby_protocol.h index 1e16eef..cc02007 100644 --- a/nearby/presence/np_cpp_ffi/include/nearby_protocol.h +++ b/nearby/presence/np_cpp_ffi/include/nearby_protocol.h @@ -19,6 +19,8 @@ #include "absl/strings/str_format.h" #include "np_cpp_ffi_types.h" +#include <span> + // This namespace provides a C++ API surface to the Rust nearby protocol // implementation. This is a wrapper over the np_ffi::internal namespace defined // in the headers np_cpp_ffi_functions.h and np_cpp_ffi_types.h which are @@ -50,25 +52,34 @@ namespace nearby_protocol { // Re-exporting cbindgen generated types which are used in the public API +using np_ffi::internal::AddCredentialToSlabResult; using np_ffi::internal::BooleanActionType; -using np_ffi::internal::CreateCredentialSlabResultKind; using np_ffi::internal::CreateCredentialBookResultKind; +using np_ffi::internal::CreateCredentialSlabResultKind; using np_ffi::internal::DeserializeAdvertisementResultKind; using np_ffi::internal::DeserializedV0AdvertisementKind; +using np_ffi::internal::DeserializedV0IdentityDetails; using np_ffi::internal::DeserializedV0IdentityKind; +using np_ffi::internal::DeserializedV1IdentityDetails; using np_ffi::internal::DeserializedV1IdentityKind; +using np_ffi::internal::EncryptedIdentityType; using np_ffi::internal::GetV0DEResultKind; using np_ffi::internal::PanicReason; using np_ffi::internal::TxPower; using np_ffi::internal::V0DataElementKind; +using np_ffi::internal::V1VerificationMode; template <uintptr_t N> using FfiByteBuffer = np_ffi::internal::ByteBuffer<N>; // All of the types defined in this header class RawAdvertisementPayload; class CredentialBook; +class CredentialSlab; class Deserializer; class DeserializeAdvertisementResult; +class MatchedCredentialData; +class V0MatchableCredential; +class V1MatchableCredential; // V0 Classes class DeserializedV0Advertisement; @@ -156,6 +167,13 @@ public: // Creates a new instance of a CredentialSlab, returns the CredentialSlab on // success or a Status code on failure [[nodiscard]] static absl::StatusOr<CredentialSlab> TryCreate(); + + // Adds a V0 credential to the slab + [[nodiscard]] absl::Status AddV0Credential(V0MatchableCredential v0_cred); + + // Adds a V1 credential to the slab + [[nodiscard]] absl::Status AddV1Credential(V1MatchableCredential v1_cred); + private: friend class CredentialBook; explicit CredentialSlab(np_ffi::internal::CredentialSlab credential_slab) @@ -189,7 +207,8 @@ public: // returning the CredentialBook on success or a Status code on failure. // The passed credential-slab will be deallocated if this operation // is successful. - [[nodiscard]] static absl::StatusOr<CredentialBook> TryCreateFromSlab(CredentialSlab &slab); + [[nodiscard]] static absl::StatusOr<CredentialBook> + TryCreateFromSlab(CredentialSlab &slab); private: friend class Deserializer; @@ -200,6 +219,64 @@ private: bool moved_; }; +// Holds data associated with a specific credential which will be returned to +// the caller when it is successfully matched with an advertisement. +class MatchedCredentialData { +public: + // Creates matched credential data from a provided credential_id used to + // correlate the data back to its full credential data, and the metadata byte + // buffer as copied from the given span over bytes. After calling + // this the bytes are copied into the rust code, so the + // encrypted_metadata_bytes_buffer can be freed. + // + // Safety: this is safe if the span is over a valid buffer of bytes. The copy + // from the memory address isn't atomic, so concurrent modification of the + // array from another thread would cause undefined behavior. + [[nodiscard]] MatchedCredentialData(uint32_t cred_id, + std::span<uint8_t> metadata_bytes); + +private: + np_ffi::internal::FfiMatchedCredential data_; + friend class V0MatchableCredential; + friend class V1MatchableCredential; +}; + +// Holds the v0 credential data needed by the deserializer to decrypt +// advertisements, along with some provided matched data that will be returned +// back to the caller upon a successful credential match. +class V0MatchableCredential { +public: + // Creates a new V0MatchableCredential from a key seed, its calculated hmac + // value and some match data. + [[nodiscard]] V0MatchableCredential( + std::array<uint8_t, 32> key_seed, + std::array<uint8_t, 32> legacy_metadata_key_hmac, + MatchedCredentialData matched_credential_data); + +private: + friend class CredentialSlab; + np_ffi::internal::V0MatchableCredential internal_{}; +}; + +// Holds the v1 credential data needed by the deserializer to decrypt +// advertisements, along with some provided matched data that will be returned +// back to the caller upon a successful credential match. +class V1MatchableCredential { +public: + // Creates a new V1MatchableCredential from key material, its calculated hmac + // value and some match data. + [[nodiscard]] V1MatchableCredential( + std::array<uint8_t, 32> key_seed, + std::array<uint8_t, 32> expected_unsigned_metadata_key_hmac, + std::array<uint8_t, 32> expected_signed_metadata_key_hmac, + std::array<uint8_t, 32> pub_key, + MatchedCredentialData matched_credential_data); + +private: + friend class CredentialSlab; + np_ffi::internal::V1MatchableCredential internal_; +}; + // Representation of a buffer of bytes returned from deserialization APIs template <size_t N> class ByteBuffer { public: @@ -417,6 +494,16 @@ public: // element if it exists otherwise returns an Error status code [[nodiscard]] absl::StatusOr<V0DataElement> TryGetDataElement(uint8_t index); + // Decrypts the metadata of the credential which matched with this + // advertisement, or returns an error if the metadata key is invalid and unable + // to successfully decrypt the metadata. + [[nodiscard]] absl::StatusOr<std::vector<uint8_t>> DecryptMetadata(); + + // Gets the details of the identity data element of this payload or returns an + // error if the payload does not have an identity (public advertisement) + [[nodiscard]] absl::StatusOr<DeserializedV0IdentityDetails> + GetIdentityDetails(); + private: friend class LegibleDeserializedV0Advertisement; explicit V0Payload(np_ffi::internal::V0Payload v0_payload) @@ -506,11 +593,29 @@ class DeserializedV1Section { public: // Returns the number of data elements present in the section [[nodiscard]] uint8_t NumberOfDataElements(); + // Returns the DeserializedV1IdentityKind of the identity [[nodiscard]] DeserializedV1IdentityKind GetIdentityKind(); + // Tries to get the data element in the section at the given index [[nodiscard]] absl::StatusOr<V1DataElement> TryGetDataElement(uint8_t index); + // Decrypts the metadata of the credential which matched with this section + [[nodiscard]] absl::StatusOr<std::vector<uint8_t>> DecryptMetadata(); + + // Gets the details of the identity data element of this section or returns an + // error if the section does not conatin an identity (public section) + [[nodiscard]] absl::StatusOr<DeserializedV1IdentityDetails> + GetIdentityDetails(); + + // Attempts to derive a 16-byte DE salt for a DE in this section with the + // given DE offset. This operation may fail if the passed offset is 255 + // (causes overflow) or if the section is leveraging a public identity, and + // hence, doesn't have an associated salt. The offset should come from a + // particular deserialized v1 de via `V1DataElement::GetOffset()` + [[nodiscard]] absl::StatusOr<std::array<uint8_t, 16>> + DeriveSaltForOffset(uint8_t offset); + private: friend class DeserializedV1Advertisement; explicit DeserializedV1Section( @@ -531,6 +636,8 @@ public: [[nodiscard]] uint32_t GetDataElementTypeCode() const; // Yields the payload bytes of the data element [[nodiscard]] ByteBuffer<127> GetPayload() const; + /// Gets the offset for this V1 data element. + [[nodiscard]] uint8_t GetOffset() const; private: friend class DeserializedV1Section; diff --git a/nearby/presence/np_cpp_ffi/nearby_protocol.cc b/nearby/presence/np_cpp_ffi/nearby_protocol.cc index 106eb77..c2f8566 100644 --- a/nearby/presence/np_cpp_ffi/nearby_protocol.cc +++ b/nearby/presence/np_cpp_ffi/nearby_protocol.cc @@ -27,7 +27,7 @@ namespace nearby_protocol { static void panic_handler(PanicReason reason); struct PanicHandler { - void (*handler)(PanicReason); + void (* handler)(PanicReason); bool set_by_client; }; @@ -43,7 +43,7 @@ static void panic_handler(PanicReason reason) { std::abort(); } -static void _assert_panic(bool condition, const char *func, const char *file, +static void _assert_panic(bool condition, const char* func, const char* file, int line) { if (!condition) { std::cout << "Assert failed: \n function: " << func << "\n file: " << file @@ -54,7 +54,7 @@ static void _assert_panic(bool condition, const char *func, const char *file, #define assert_panic(e) _assert_panic(e, __func__, __ASSERT_FILE_NAME, __LINE__) -bool GlobalConfig::SetPanicHandler(void (*handler)(PanicReason)) { +bool GlobalConfig::SetPanicHandler(void (* handler)(PanicReason)) { if (!gPanicHandler.set_by_client) { gPanicHandler.handler = handler; gPanicHandler.set_by_client = true; @@ -80,15 +80,15 @@ void GlobalConfig::SetMaxNumCredentialBooks(uint32_t max_num_credential_books) { void GlobalConfig::SetMaxNumDeserializedV0Advertisements( uint32_t max_num_deserialized_v0_advertisements) { np_ffi::internal:: - np_ffi_global_config_set_max_num_deserialized_v0_advertisements( - max_num_deserialized_v0_advertisements); + np_ffi_global_config_set_max_num_deserialized_v0_advertisements( + max_num_deserialized_v0_advertisements); } void GlobalConfig::SetMaxNumDeserializedV1Advertisements( uint32_t max_num_deserialized_v1_advertisements) { np_ffi::internal:: - np_ffi_global_config_set_max_num_deserialized_v1_advertisements( - max_num_deserialized_v1_advertisements); + np_ffi_global_config_set_max_num_deserialized_v1_advertisements( + max_num_deserialized_v1_advertisements); } absl::StatusOr<CredentialSlab> CredentialSlab::TryCreate() { @@ -96,16 +96,16 @@ absl::StatusOr<CredentialSlab> CredentialSlab::TryCreate() { auto kind = np_ffi::internal::np_ffi_CreateCredentialSlabResult_kind(result); switch (kind) { - case CreateCredentialSlabResultKind::Success: { - auto slab = CredentialSlab( - np_ffi::internal::np_ffi_CreateCredentialSlabResult_into_SUCCESS( - result)); - return slab; - } - case CreateCredentialSlabResultKind::NoSpaceLeft: { - return absl::ResourceExhaustedError( - "No space left to create credential slab"); - } + case CreateCredentialSlabResultKind::Success: { + auto slab = CredentialSlab( + np_ffi::internal::np_ffi_CreateCredentialSlabResult_into_SUCCESS( + result)); + return slab; + } + case CreateCredentialSlabResultKind::NoSpaceLeft: { + return absl::ResourceExhaustedError( + "No space left to create credential slab"); + } } } @@ -117,13 +117,13 @@ CredentialSlab::~CredentialSlab() { } } -CredentialSlab::CredentialSlab(CredentialSlab &&other) noexcept +CredentialSlab::CredentialSlab(CredentialSlab&& other) noexcept : credential_slab_(other.credential_slab_), moved_(other.moved_) { other.credential_slab_ = {}; other.moved_ = true; } -CredentialSlab &CredentialSlab::operator=(CredentialSlab &&other) noexcept { +CredentialSlab& CredentialSlab::operator=(CredentialSlab&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = np_ffi::internal::np_ffi_deallocate_credential_slab( @@ -140,24 +140,58 @@ CredentialSlab &CredentialSlab::operator=(CredentialSlab &&other) noexcept { return *this; } -absl::StatusOr<CredentialBook> CredentialBook::TryCreateFromSlab(CredentialSlab &slab) { +absl::Status CredentialSlab::AddV0Credential(V0MatchableCredential v0_cred) { + assert_panic(!this->moved_); + auto result = np_ffi::internal::np_ffi_CredentialSlab_add_v0_credential( + this->credential_slab_, v0_cred.internal_); + switch (result) { + case AddCredentialToSlabResult::Success: { + return absl::OkStatus(); + } + case AddCredentialToSlabResult::InvalidHandle: { + return absl::InvalidArgumentError( + "invalid credential slab handle provided"); + } + } +} + +absl::Status CredentialSlab::AddV1Credential(V1MatchableCredential v1_cred) { + assert_panic(!this->moved_); + auto result = np_ffi::internal::np_ffi_CredentialSlab_add_v1_credential( + this->credential_slab_, v1_cred.internal_); + switch (result) { + case AddCredentialToSlabResult::Success: { + return absl::OkStatus(); + } + case AddCredentialToSlabResult::InvalidHandle: { + return absl::InvalidArgumentError( + "invalid credential slab handle provided"); + } + } +} + +absl::StatusOr<CredentialBook> +CredentialBook::TryCreateFromSlab(CredentialSlab& slab) { assert_panic(!slab.moved_); - auto result = np_ffi::internal::np_ffi_create_credential_book_from_slab(slab.credential_slab_); + auto result = np_ffi::internal::np_ffi_create_credential_book_from_slab( + slab.credential_slab_); auto kind = np_ffi::internal::np_ffi_CreateCredentialBookResult_kind(result); switch (kind) { - case CreateCredentialBookResultKind::Success: { - auto book = np_ffi::internal::np_ffi_CreateCredentialBookResult_into_SUCCESS(result); - slab.moved_ = true; - return CredentialBook(book); - } - case CreateCredentialBookResultKind::NoSpaceLeft: { - return absl::ResourceExhaustedError( - "No space left to create credential book"); - } - case CreateCredentialBookResultKind::InvalidSlabHandle: { - return absl::NotFoundError( - "The slab referenced by the given handle was not found."); - } + case CreateCredentialBookResultKind::Success: { + auto book = + np_ffi::internal::np_ffi_CreateCredentialBookResult_into_SUCCESS( + result); + slab.moved_ = true; + return CredentialBook(book); + } + case CreateCredentialBookResultKind::NoSpaceLeft: { + return absl::ResourceExhaustedError( + "No space left to create credential book"); + } + case CreateCredentialBookResultKind::InvalidSlabHandle: { + return absl::NotFoundError( + "The slab referenced by the given handle was not found."); + } } } @@ -169,13 +203,13 @@ CredentialBook::~CredentialBook() { } } -CredentialBook::CredentialBook(CredentialBook &&other) noexcept +CredentialBook::CredentialBook(CredentialBook&& other) noexcept : credential_book_(other.credential_book_), moved_(other.moved_) { other.credential_book_ = {}; other.moved_ = true; } -CredentialBook &CredentialBook::operator=(CredentialBook &&other) noexcept { +CredentialBook& CredentialBook::operator=(CredentialBook&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = np_ffi::internal::np_ffi_deallocate_credential_book( @@ -193,8 +227,8 @@ CredentialBook &CredentialBook::operator=(CredentialBook &&other) noexcept { } DeserializeAdvertisementResult -Deserializer::DeserializeAdvertisement(RawAdvertisementPayload &payload, - const CredentialBook &credential_book) { +Deserializer::DeserializeAdvertisement(RawAdvertisementPayload& payload, + const CredentialBook& credential_book) { assert_panic(!credential_book.moved_); auto result = np_ffi::internal::np_ffi_deserialize_advertisement( {payload.buffer_.internal_}, credential_book.credential_book_); @@ -232,14 +266,14 @@ DeserializeAdvertisementResult::~DeserializeAdvertisementResult() { } DeserializeAdvertisementResult::DeserializeAdvertisementResult( - DeserializeAdvertisementResult &&other) noexcept + DeserializeAdvertisementResult&& other) noexcept : result_(other.result_), moved_(other.moved_) { other.result_ = {}; other.moved_ = true; } -DeserializeAdvertisementResult &DeserializeAdvertisementResult::operator=( - DeserializeAdvertisementResult &&other) noexcept { +DeserializeAdvertisementResult& DeserializeAdvertisementResult::operator=( + DeserializeAdvertisementResult&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = @@ -258,14 +292,14 @@ DeserializeAdvertisementResult &DeserializeAdvertisementResult::operator=( // V0 Stuff DeserializedV0Advertisement::DeserializedV0Advertisement( - DeserializedV0Advertisement &&other) noexcept + DeserializedV0Advertisement&& other) noexcept : v0_advertisement_(other.v0_advertisement_), moved_(other.moved_) { other.v0_advertisement_ = {}; other.moved_ = true; } -DeserializedV0Advertisement &DeserializedV0Advertisement::operator=( - DeserializedV0Advertisement &&other) noexcept { +DeserializedV0Advertisement& DeserializedV0Advertisement::operator=( + DeserializedV0Advertisement&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = @@ -309,16 +343,16 @@ LegibleDeserializedV0Advertisement DeserializedV0Advertisement::IntoLegible() { } LegibleDeserializedV0Advertisement::LegibleDeserializedV0Advertisement( - LegibleDeserializedV0Advertisement &&other) noexcept + LegibleDeserializedV0Advertisement&& other) noexcept : legible_v0_advertisement_(other.legible_v0_advertisement_), moved_(other.moved_) { other.moved_ = true; other.legible_v0_advertisement_ = {}; } -LegibleDeserializedV0Advertisement & +LegibleDeserializedV0Advertisement& LegibleDeserializedV0Advertisement::operator=( - LegibleDeserializedV0Advertisement &&other) noexcept { + LegibleDeserializedV0Advertisement&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = @@ -343,19 +377,20 @@ LegibleDeserializedV0Advertisement::~LegibleDeserializedV0Advertisement() { } } -DeserializedV0IdentityKind LegibleDeserializedV0Advertisement::GetIdentityKind() { +DeserializedV0IdentityKind +LegibleDeserializedV0Advertisement::GetIdentityKind() { assert_panic(!this->moved_); - auto result = - np_ffi::internal::np_ffi_LegibleDeserializedV0Advertisement_get_identity_kind( - legible_v0_advertisement_); + auto result = np_ffi::internal:: + np_ffi_LegibleDeserializedV0Advertisement_get_identity_kind( + legible_v0_advertisement_); return result; } uint8_t LegibleDeserializedV0Advertisement::GetNumberOfDataElements() { assert_panic(!this->moved_); return np_ffi::internal:: - np_ffi_LegibleDeserializedV0Advertisement_get_num_des( - legible_v0_advertisement_); + np_ffi_LegibleDeserializedV0Advertisement_get_num_des( + legible_v0_advertisement_); } V0Payload LegibleDeserializedV0Advertisement::IntoPayload() { @@ -366,13 +401,13 @@ V0Payload LegibleDeserializedV0Advertisement::IntoPayload() { return V0Payload(result); } -V0Payload::V0Payload(V0Payload &&other) noexcept +V0Payload::V0Payload(V0Payload&& other) noexcept : v0_payload_(other.v0_payload_), moved_(other.moved_) { other.v0_payload_ = {}; other.moved_ = true; } -V0Payload &V0Payload::operator=(V0Payload &&other) noexcept { +V0Payload& V0Payload::operator=(V0Payload&& other) noexcept { if (this != &other) { if (!this->moved_) { auto result = @@ -401,16 +436,75 @@ absl::StatusOr<V0DataElement> V0Payload::TryGetDataElement(uint8_t index) { auto result = np_ffi::internal::np_ffi_V0Payload_get_de(v0_payload_, index); auto kind = np_ffi::internal::np_ffi_GetV0DEResult_kind(result); switch (kind) { - case GetV0DEResultKind::Success: { - auto de = np_ffi_GetV0DEResult_into_SUCCESS(result); - return V0DataElement(de); + case GetV0DEResultKind::Success: { + auto de = np_ffi_GetV0DEResult_into_SUCCESS(result); + return V0DataElement(de); + } + case GetV0DEResultKind::Error: { + return absl::OutOfRangeError("Invalid Data Element index"); + } } - case GetV0DEResultKind::Error: { - return absl::OutOfRangeError("Invalid Data Element index"); +} + +static absl::StatusOr<std::vector<uint8_t>> +MetadataResultToVec(np_ffi::internal::DecryptMetadataResult decrypt_result) { + auto kind = + np_ffi::internal::np_ffi_DecryptMetadataResult_kind(decrypt_result); + switch (kind) { + case np_ffi::internal::DecryptMetadataResultKind::Success: { + auto metadata = + np_ffi::internal::np_ffi_DecryptMetadataResult_into_SUCCESS( + decrypt_result); + auto parts_result = + np_ffi::internal::np_ffi_DecryptedMetadata_get_metadata_buffer_parts( + metadata); + // The handle is guaranteed to be valid by the C++ wrapper so this should + // never fail + assert_panic(np_ffi::internal::np_ffi_GetMetadataBufferPartsResult_kind( + parts_result) == + np_ffi::internal::GetMetadataBufferPartsResultKind::Success); + auto parts = + np_ffi::internal::np_ffi_GetMetadataBufferPartsResult_into_SUCCESS( + parts_result); + std::vector<uint8_t> result(parts.ptr, parts.ptr + parts.len); + + // Now that the contents have been copied into the vec, the underlying + // handle can be de-allocated + auto deallocate_result = + np_ffi::internal::np_ffi_deallocate_DecryptedMetadata(metadata); + assert_panic(deallocate_result == + np_ffi::internal::DeallocateResult::Success); + return result; + } + case np_ffi::internal::DecryptMetadataResultKind::Error: { + return absl::InvalidArgumentError("Invalid V0 payload handle"); + } } +} + +absl::StatusOr<DeserializedV0IdentityDetails> V0Payload::GetIdentityDetails() { + assert_panic(!this->moved_); + auto result = np_ffi::internal::np_ffi_V0Payload_get_identity_details( + this->v0_payload_); + auto kind = np_ffi::internal::np_ffi_GetV0IdentityDetailsResult_kind(result); + switch (kind) { + case np_ffi::internal::GetV0IdentityDetailsResultKind::Error: { + return absl::InvalidArgumentError("Invalid handle"); + } + case np_ffi::internal::GetV0IdentityDetailsResultKind::Success: { + return np_ffi::internal::np_ffi_GetV0IdentityDetailsResult_into_SUCCESS( + result); + } } } +absl::StatusOr<std::vector<uint8_t>> V0Payload::DecryptMetadata() { + assert_panic(!this->moved_); + auto decrypt_result = + np_ffi::internal::np_ffi_V0Payload_decrypt_metadata(this->v0_payload_); + return MetadataResultToVec(decrypt_result); +} + V0DataElementKind V0DataElement::GetKind() { return np_ffi::internal::np_ffi_V0DataElement_kind(v0_data_element_); } @@ -440,7 +534,7 @@ uint8_t V0Actions::GetContextSyncSequenceNumber() { // This is called after all references to the shared_ptr have gone out of scope auto DeallocateV1Adv( - np_ffi::internal::DeserializedV1Advertisement *v1_advertisement) { + np_ffi::internal::DeserializedV1Advertisement* v1_advertisement) { auto result = np_ffi::internal::np_ffi_deallocate_deserialized_V1_advertisement( *v1_advertisement); @@ -457,11 +551,11 @@ DeserializedV1Advertisement::DeserializedV1Advertisement( } DeserializedV1Advertisement::DeserializedV1Advertisement( - DeserializedV1Advertisement &&other) noexcept + DeserializedV1Advertisement&& other) noexcept : v1_advertisement_(std::move(other.v1_advertisement_)) {} -DeserializedV1Advertisement &DeserializedV1Advertisement::operator=( - DeserializedV1Advertisement &&other) noexcept { +DeserializedV1Advertisement& DeserializedV1Advertisement::operator=( + DeserializedV1Advertisement&& other) noexcept { if (this != &other) { this->v1_advertisement_ = std::move(other.v1_advertisement_); } @@ -472,15 +566,15 @@ DeserializedV1Advertisement &DeserializedV1Advertisement::operator=( uint8_t DeserializedV1Advertisement::GetNumLegibleSections() { assert_panic(this->v1_advertisement_ != nullptr); return np_ffi::internal:: - np_ffi_DeserializedV1Advertisement_get_num_legible_sections( - *v1_advertisement_); + np_ffi_DeserializedV1Advertisement_get_num_legible_sections( + *v1_advertisement_); } uint8_t DeserializedV1Advertisement::GetNumUndecryptableSections() { assert_panic(this->v1_advertisement_ != nullptr); return np_ffi::internal:: - np_ffi_DeserializedV1Advertisement_get_num_undecryptable_sections( - *v1_advertisement_); + np_ffi_DeserializedV1Advertisement_get_num_undecryptable_sections( + *v1_advertisement_); } absl::StatusOr<DeserializedV1Section> @@ -491,14 +585,14 @@ DeserializedV1Advertisement::TryGetSection(uint8_t section_index) { *v1_advertisement_, section_index); auto kind = np_ffi::internal::np_ffi_GetV1SectionResult_kind(result); switch (kind) { - case np_ffi::internal::GetV1SectionResultKind::Error: { - return absl::OutOfRangeError("Invalid section index"); - } - case np_ffi::internal::GetV1SectionResultKind::Success: { - auto section = - np_ffi::internal::np_ffi_GetV1SectionResult_into_SUCCESS(result); - return DeserializedV1Section(section, v1_advertisement_); - } + case np_ffi::internal::GetV1SectionResultKind::Error: { + return absl::OutOfRangeError("Invalid section index"); + } + case np_ffi::internal::GetV1SectionResultKind::Success: { + auto section = + np_ffi::internal::np_ffi_GetV1SectionResult_into_SUCCESS(result); + return DeserializedV1Section(section, v1_advertisement_); + } } } @@ -517,23 +611,112 @@ DeserializedV1Section::TryGetDataElement(uint8_t index) { np_ffi::internal::np_ffi_DeserializedV1Section_get_de(section_, index); auto kind = np_ffi::internal::np_ffi_GetV1DEResult_kind(result); switch (kind) { - case np_ffi::internal::GetV1DEResultKind::Error: { - return absl::OutOfRangeError("Invalid data element index for this section"); + case np_ffi::internal::GetV1DEResultKind::Error: { + return absl::OutOfRangeError("Invalid data element index for this section"); + } + case np_ffi::internal::GetV1DEResultKind::Success: { + return V1DataElement( + np_ffi::internal::np_ffi_GetV1DEResult_into_SUCCESS(result)); + } } - case np_ffi::internal::GetV1DEResultKind::Success: { - return V1DataElement( - np_ffi::internal::np_ffi_GetV1DEResult_into_SUCCESS(result)); +} + +absl::StatusOr<std::vector<uint8_t>> DeserializedV1Section::DecryptMetadata() { + assert_panic(this->owning_v1_advertisement_ != nullptr); + auto decrypt_result = + np_ffi::internal::np_ffi_DeserializedV1Section_decrypt_metadata( + this->section_); + return MetadataResultToVec(decrypt_result); +} + +absl::StatusOr<DeserializedV1IdentityDetails> +DeserializedV1Section::GetIdentityDetails() { + assert_panic(this->owning_v1_advertisement_ != nullptr); + auto result = + np_ffi::internal::np_ffi_DeserializedV1Section_get_identity_details( + this->section_); + auto kind = np_ffi::internal::np_ffi_GetV1IdentityDetailsResult_kind(result); + switch (kind) { + case np_ffi::internal::GetV1IdentityDetailsResultKind::Error: { + return absl::InvalidArgumentError("Invalid handle"); + } + case np_ffi::internal::GetV1IdentityDetailsResultKind::Success: { + return np_ffi::internal::np_ffi_GetV1IdentityDetailsResult_into_SUCCESS( + result); + } } +} + +absl::StatusOr<std::array<uint8_t, 16>> DeserializedV1Section::DeriveSaltForOffset( + uint8_t offset) { + auto result = + np_ffi::internal::np_ffi_DeserializedV1Section_derive_16_byte_salt_for_offset( + this->section_, + offset); + auto kind = np_ffi::internal::np_ffi_GetV1DE16ByteSaltResult_kind(result); + switch (kind) { + case np_ffi::internal::GetV1DE16ByteSaltResultKind::Error: { + return absl::InvalidArgumentError("Failed to derive salt for offset"); + } + case np_ffi::internal::GetV1DE16ByteSaltResultKind::Success: { + auto buffer = np_ffi::internal::np_ffi_GetV1DE16ByteSaltResult_into_SUCCESS(result); + return std::to_array(buffer._0); + } } } uint32_t V1DataElement::GetDataElementTypeCode() const { return np_ffi::internal::np_ffi_V1DEType_to_uint32_t( - v1_data_element_.generic._0.de_type); + np_ffi::internal::np_ffi_V1DataElement_to_generic(this->v1_data_element_) + .de_type); } ByteBuffer<127> V1DataElement::GetPayload() const { - return ByteBuffer(v1_data_element_.generic._0.payload); + return ByteBuffer( + np_ffi::internal::np_ffi_V1DataElement_to_generic(this->v1_data_element_) + .payload); } +uint8_t V1DataElement::GetOffset() const { + return np_ffi::internal::np_ffi_V1DataElement_to_generic( + this->v1_data_element_) + .offset; +} + +MatchedCredentialData::MatchedCredentialData( + uint32_t cred_id, std::span<uint8_t> metadata_bytes) { + this->data_ = {cred_id, metadata_bytes.data(), metadata_bytes.size()}; +} + +template<typename T, size_t N> +static void CopyToRawArray(T (& dest)[N], const std::array<T, N>& src) { + memcpy(dest, src.data(), sizeof(T) * N); +} + +V0MatchableCredential::V0MatchableCredential( + std::array<uint8_t, 32> key_seed, + std::array<uint8_t, 32> legacy_metadata_key_hmac, + MatchedCredentialData matched_credential_data) { + np_ffi::internal::V0DiscoveryCredential discovery_cred{}; + CopyToRawArray(discovery_cred.key_seed, key_seed); + CopyToRawArray(discovery_cred.legacy_metadata_key_hmac, + legacy_metadata_key_hmac); + this->internal_ = {discovery_cred, matched_credential_data.data_}; +} + +V1MatchableCredential::V1MatchableCredential( + std::array<uint8_t, 32> key_seed, + std::array<uint8_t, 32> expected_unsigned_metadata_key_hmac, + std::array<uint8_t, 32> expected_signed_metadata_key_hmac, + std::array<uint8_t, 32> pub_key, + MatchedCredentialData matched_credential_data) { + np_ffi::internal::V1DiscoveryCredential discovery_cred{}; + CopyToRawArray(discovery_cred.key_seed, key_seed); + CopyToRawArray(discovery_cred.expected_unsigned_metadata_key_hmac, + expected_unsigned_metadata_key_hmac); + CopyToRawArray(discovery_cred.expected_signed_metadata_key_hmac, + expected_signed_metadata_key_hmac); + CopyToRawArray(discovery_cred.pub_key, pub_key); + this->internal_ = {discovery_cred, matched_credential_data.data_}; +} } // namespace nearby_protocol diff --git a/nearby/presence/np_cpp_ffi/sample/main.cc b/nearby/presence/np_cpp_ffi/sample/main.cc index a02a523..1d273da 100644 --- a/nearby/presence/np_cpp_ffi/sample/main.cc +++ b/nearby/presence/np_cpp_ffi/sample/main.cc @@ -81,10 +81,8 @@ int main() { auto v1_byte_string = "20" // V1 Advertisement header "04" // Section Header "03" // Public Identity DE header - "260046" // Length 2 Actions DE - "03" // Section Header - "03" // Public Identity DE header - "1505"; // Length 1 Tx Power DE with value 5 + "260046";// Length 2 Actions DE + auto v1_bytes = absl::HexStringToBytes(v1_byte_string); auto v1_buffer = nearby_protocol::ByteBuffer<255>::CopyFrom(v1_bytes); nearby_protocol::RawAdvertisementPayload v1_payload(v1_buffer.value()); diff --git a/nearby/presence/np_cpp_ffi/tests/CMakeLists.txt b/nearby/presence/np_cpp_ffi/tests/CMakeLists.txt index b5ff838..549a072 100644 --- a/nearby/presence/np_cpp_ffi/tests/CMakeLists.txt +++ b/nearby/presence/np_cpp_ffi/tests/CMakeLists.txt @@ -14,14 +14,16 @@ add_executable( np_ffi_tests - deserialize_result_tests.cc - deserialize_v0_tests.cc - deserialize_v1_tests.cc - credential_slab_tests.cc - credential_book_tests.cc byte_buffer_tests.cc + credential_book_tests.cc + credential_slab_tests.cc + deserialize_result_tests.cc np_cpp_test.h np_cpp_test.cc + v0_private_identity_tests.cc + v0_public_identity_tests.cc + v1_private_identity_tests.cc + v1_public_identity_tests.cc ) target_link_libraries( diff --git a/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc b/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc index 15f262e..7e1a048 100644 --- a/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/byte_buffer_tests.cc @@ -13,12 +13,13 @@ // limitations under the License. #include "nearby_protocol.h" +#include "np_cpp_test.h" #include "shared_test_util.h" #include "absl/strings/escaping.h" #include "gtest/gtest.h" -TEST(ByteBufferTests, ByteBufferMaxLength) { +TEST_F(NpCppTest, ByteBufferMaxLength) { // Each hex byte takes up 2 characters so length 510 string = 255 bytes of hex auto str_bytes = generate_hex_string(510); auto bytes = absl::HexStringToBytes(str_bytes); @@ -28,7 +29,7 @@ TEST(ByteBufferTests, ByteBufferMaxLength) { ASSERT_EQ(bytes, string); } -TEST(ByteBufferTooLarge, ByteBufferInvalidLength) { +TEST_F(NpCppTest, ByteBufferInvalidLength) { // 256 bytes should fail auto str_bytes = generate_hex_string(512); auto bytes = absl::HexStringToBytes(str_bytes); @@ -36,26 +37,26 @@ TEST(ByteBufferTooLarge, ByteBufferInvalidLength) { ASSERT_FALSE(buffer.ok()); } -TEST(ByteBufferTests, ByteBufferRoundTrip) { +TEST_F(NpCppTest, ByteBufferRoundTrip) { auto bytes = absl::HexStringToBytes("2003031503"); auto buffer = nearby_protocol::ByteBuffer<255>::CopyFrom(bytes); auto string = buffer.value().ToString(); ASSERT_EQ(bytes, string); } -TEST(ByteBufferTests, ByteBufferPayloadWrongSize) { +TEST_F(NpCppTest, ByteBufferPayloadWrongSize) { auto bytes = absl::HexStringToBytes("1111111111111111111111"); auto buffer = nearby_protocol::ByteBuffer<10>::CopyFrom(bytes); ASSERT_FALSE(buffer.ok()); } -TEST(ByteBufferTests, ByteBufferEmptyString) { +TEST_F(NpCppTest, ByteBufferEmptyString) { auto bytes = absl::HexStringToBytes(""); auto buffer = nearby_protocol::ByteBuffer<10>::CopyFrom(bytes); ASSERT_TRUE(buffer.ok()); } -TEST(ByteBufferTests, ByteBufferToVector) { +TEST_F(NpCppTest, ByteBufferToVector) { auto bytes = absl::HexStringToBytes("1234567890"); auto buffer = nearby_protocol::ByteBuffer<100>::CopyFrom(bytes); auto vec = buffer.value().ToVector(); @@ -63,7 +64,7 @@ TEST(ByteBufferTests, ByteBufferToVector) { ASSERT_EQ(vec, expected); } -TEST(ByteBufferTests, ByteBufferEndToEndPayloadAsString) { +TEST_F(NpCppTest, ByteBufferEndToEndPayloadAsString) { std::string bytes = absl::HexStringToBytes("2003031503"); auto buffer = nearby_protocol::ByteBuffer<255>::CopyFrom(bytes); ASSERT_TRUE(buffer.ok()); @@ -71,7 +72,9 @@ TEST(ByteBufferTests, ByteBufferEndToEndPayloadAsString) { nearby_protocol::RawAdvertisementPayload adv(buffer.value()); auto credential_slab = nearby_protocol::CredentialSlab::TryCreate().value(); - auto credential_book = nearby_protocol::CredentialBook::TryCreateFromSlab(credential_slab).value(); + auto credential_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(credential_slab) + .value(); auto str = nearby_protocol::Deserializer::DeserializeAdvertisement( adv, credential_book) .IntoV1() diff --git a/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc b/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc index dcaf421..af8fc0d 100644 --- a/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/credential_book_tests.cc @@ -37,7 +37,7 @@ TEST_F(NpCppTest, TestSetMaxCredBooks) { ASSERT_TRUE(absl::IsResourceExhausted(book3_result.status())); } -TEST_F(NpCppTest, TestMoveConstructor) { +TEST_F(NpCppTest, TestBookMoveConstructor) { auto slab = nearby_protocol::CredentialSlab::TryCreate().value(); auto book = nearby_protocol::CredentialBook::TryCreateFromSlab(slab).value(); auto deserialize_result = @@ -69,7 +69,7 @@ TEST_F(NpCppTest, TestMoveConstructor) { ""); } -TEST_F(NpCppTest, TestMoveAssignment) { +TEST_F(NpCppTest, TestBookMoveAssignment) { auto slab = nearby_protocol::CredentialSlab::TryCreate().value(); auto book = nearby_protocol::CredentialBook::TryCreateFromSlab(slab).value(); auto deserialize_result = diff --git a/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc b/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc index f715361..c8ddb3c 100644 --- a/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/credential_slab_tests.cc @@ -13,8 +13,8 @@ // limitations under the License. #include "nearby_protocol.h" -#include "shared_test_util.h" #include "np_cpp_test.h" +#include "shared_test_util.h" #include "gtest/gtest.h" @@ -41,16 +41,186 @@ TEST_F(NpCppTest, TestSlabMoveConstructor) { // credential-book. nearby_protocol::CredentialSlab next_slab(std::move(slab)); - auto maybe_book = nearby_protocol::CredentialBook::TryCreateFromSlab(next_slab); + auto maybe_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(next_slab); ASSERT_TRUE(maybe_book.ok()); // Now, both slabs should be moved-out-of, since `TryCreateFromSlab` takes // ownership. Verify that this is the case, and attempts to re-use the slabs // result in an assert failure. ASSERT_DEATH([[maybe_unused]] auto failure = - nearby_protocol::CredentialBook::TryCreateFromSlab(slab), //NOLINT(bugprone-use-after-move) + nearby_protocol::CredentialBook::TryCreateFromSlab( + slab), // NOLINT(bugprone-use-after-move) + ""); + ASSERT_DEATH( + [[maybe_unused]] auto failure = + nearby_protocol::CredentialBook::TryCreateFromSlab(next_slab), + ""); +} + +TEST_F(NpCppTest, TestSlabDestructor) { + { + auto slab1_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab1_result.ok()); + + auto slab2_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab2_result.ok()); + + auto slab3_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab3_result.ok()); + + auto slab4_result = nearby_protocol::CredentialSlab::TryCreate(); + + ASSERT_FALSE(slab4_result.ok()); + ASSERT_TRUE(absl::IsResourceExhausted(slab4_result.status())); + } + + // Now that the above variables have gone out of scope we should verify that + // the destructor succeeded in cleaning up those resources + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); +} + +TEST_F(NpCppTest, TestSlabMoveAssignment) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + // create a second slab + auto other_slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(other_slab_result.ok()); + + // move assignment should override currently assigned slab with new one, + // freeing the existing one. + auto other_slab = std::move(slab_result.value()); + auto maybe_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(other_slab); + ASSERT_TRUE(maybe_book.ok()); + + // The old object should now lead to use after moved assert failure + ASSERT_DEATH([[maybe_unused]] auto failure = + nearby_protocol::CredentialBook::TryCreateFromSlab( + slab_result.value()), // NOLINT(bugprone-use-after-move) ""); + + // moving again should still lead to a use after moved assert failure + auto another_moved_book = std::move(slab_result.value()); ASSERT_DEATH([[maybe_unused]] auto failure = - nearby_protocol::CredentialBook::TryCreateFromSlab(next_slab), + nearby_protocol::CredentialBook::TryCreateFromSlab( + another_moved_book), // NOLINT(bugprone-use-after-move) ""); } + +TEST_F(NpCppTest, TestAddV0Credential) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + uint8_t metadata[] = {1, 2, 3}; + std::span<uint8_t> metadata_span(metadata); + + nearby_protocol::MatchedCredentialData match_data(111, metadata_span); + std::array<uint8_t, 32> key_seed{1, 2, 3}; + std::array<uint8_t, 32> legacy_metadata_key_hmac{1, 2, 3}; + + nearby_protocol::V0MatchableCredential v0_cred( + key_seed, legacy_metadata_key_hmac, match_data); + auto add_result = slab_result.value().AddV0Credential(v0_cred); + ASSERT_EQ(add_result, absl::OkStatus()); +} + +TEST_F(NpCppTest, TestAddV0CredentialAfterMoved) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + // creating a book will move the slab + auto maybe_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(slab_result.value()); + ASSERT_TRUE(maybe_book.ok()); + + uint8_t metadata[] = {1, 2, 3}; + std::span<uint8_t> metadata_span(metadata); + nearby_protocol::MatchedCredentialData match_data(111, metadata_span); + std::array<uint8_t, 32> key_seed{1, 2, 3}; + std::array<uint8_t, 32> legacy_metadata_key_hmac{1, 2, 3}; + nearby_protocol::V0MatchableCredential v0_cred( + key_seed, legacy_metadata_key_hmac, match_data); + + ASSERT_DEATH([[maybe_unused]] auto add_result = + slab_result.value().AddV0Credential(v0_cred); + , ""); +} + +TEST_F(NpCppTest, TestAddV1Credential) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + uint8_t metadata[] = {1, 2, 3}; + std::span<uint8_t> metadata_span(metadata); + nearby_protocol::MatchedCredentialData match_data(111, metadata_span); + std::array<uint8_t, 32> key_seed{1, 2, 3}; + std::array<uint8_t, 32> expected_unsigned_metadata_key_hmac{1, 2, 3}; + std::array<uint8_t, 32> expected_signed_metadata_key_hmac{1, 2, 3}; + std::array<uint8_t, 32> pub_key{1, 2, 3}; + nearby_protocol::V1MatchableCredential v1_cred( + key_seed, expected_unsigned_metadata_key_hmac, + expected_signed_metadata_key_hmac, pub_key, match_data); + + auto add_result = slab_result.value().AddV1Credential(v1_cred); + ASSERT_EQ(add_result, absl::OkStatus()); +} + +TEST_F(NpCppTest, TestAddV1CredentialAfterMoved) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + // creating a book will move the slab + auto maybe_book = + nearby_protocol::CredentialBook::TryCreateFromSlab(slab_result.value()); + ASSERT_TRUE(maybe_book.ok()); + + uint8_t metadata[] = {1, 2, 3}; + std::span<uint8_t> metadata_span(metadata); + nearby_protocol::MatchedCredentialData match_data(111, metadata_span); + std::array<uint8_t, 32> key_seed{1, 2, 3}; + std::array<uint8_t, 32> expected_unsigned_metadata_key_hmac{1, 2, 3}; + std::array<uint8_t, 32> expected_signed_metadata_key_hmac{1, 2, 3}; + std::array<uint8_t, 32> pub_key{1, 2, 3}; + nearby_protocol::V1MatchableCredential v1_cred( + key_seed, expected_unsigned_metadata_key_hmac, + expected_signed_metadata_key_hmac, pub_key, match_data); + + ASSERT_DEATH([[maybe_unused]] auto add_result = + slab_result.value().AddV1Credential(v1_cred); + , ""); +} + +// make sure the book can be populated with many credentials +TEST_F(NpCppTest, TestAddManyCredentials) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + // Should be able to load the slab up with many credentials + for (int i = 0; i < 500; i++) { + uint8_t metadata[] = {1, 2, 3}; + std::span<uint8_t> metadata_span(metadata); + nearby_protocol::MatchedCredentialData match_data(111, metadata_span); + std::array<uint8_t, 32> key_seed{1, 2, 3}; + std::array<uint8_t, 32> legacy_metadata_key_hmac{1, 2, 3}; + nearby_protocol::V0MatchableCredential v0_cred( + key_seed, legacy_metadata_key_hmac, match_data); + auto add_result = slab_result->AddV0Credential(v0_cred); + ASSERT_EQ(add_result, absl::OkStatus()); + + std::array<uint8_t, 32> v1_key_seed{1, 2, 3}; + std::array<uint8_t, 32> v1_expected_unsigned_metadata_key_hmac{1, 2, 3}; + std::array<uint8_t, 32> v1_expected_signed_metadata_key_hmac{1, 2, 3}; + std::array<uint8_t, 32> v1_pub_key{1, 2, 3}; + nearby_protocol::V1MatchableCredential v1_cred( + v1_key_seed, v1_expected_unsigned_metadata_key_hmac, + v1_expected_signed_metadata_key_hmac, v1_pub_key, match_data); + + auto add_v1_result = slab_result->AddV1Credential(v1_cred); + ASSERT_EQ(add_v1_result, absl::OkStatus()); + } + ASSERT_TRUE( + nearby_protocol::CredentialBook::TryCreateFromSlab(*slab_result).ok()); +} diff --git a/nearby/presence/np_cpp_ffi/tests/np_cpp_test.h b/nearby/presence/np_cpp_ffi/tests/np_cpp_test.h index 03eb03a..1787c35 100644 --- a/nearby/presence/np_cpp_ffi/tests/np_cpp_test.h +++ b/nearby/presence/np_cpp_ffi/tests/np_cpp_test.h @@ -18,7 +18,7 @@ #include "nearby_protocol.h" #include "shared_test_util.h" -#include <gtest/gtest.h> +#include "gtest/gtest.h" class NpCppTest : public testing::Test { protected: diff --git a/nearby/presence/np_cpp_ffi/tests/v0_private_identity_tests.cc b/nearby/presence/np_cpp_ffi/tests/v0_private_identity_tests.cc new file mode 100644 index 0000000..e2a60f2 --- /dev/null +++ b/nearby/presence/np_cpp_ffi/tests/v0_private_identity_tests.cc @@ -0,0 +1,211 @@ +// 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. + +#include "nearby_protocol.h" +#include "np_cpp_test.h" +#include "gtest/gtest.h" + +#include <algorithm> + +static nearby_protocol::RawAdvertisementPayload + V0AdvPrivateIdentity(nearby_protocol::ByteBuffer<255>( + {20, + { + 0x00, // Adv Header + 0x21, // private DE w/ a 2 byte payload + 0x22, 0x22, // salt + 0x85, 0xBF, 0xA8, // encrypted de contents, Tx Power with value 3 + 0x83, 0x58, 0x7C, 0x50, 0xCF, 0x98, 0x38, + 0xA7, 0x8A, 0xC0, 0x1C, 0x96, 0xF9, + }})); + +static uint8_t encrypted_metadata[] = { + 0x26, 0xC5, 0xEA, 0xD4, 0xED, 0x58, 0xF8, 0xFC, 0xE8, 0xF4, 0xAB, 0x0C, + 0x93, 0x2B, 0x75, 0xAA, 0x74, 0x39, 0x67, 0xDB, 0x1E, 0xF2, 0x33, 0xB5, + 0x43, 0xCC, 0x94, 0xAA, 0xA3, 0xBB, 0xB9, 0x4C, 0xBF, 0x57, 0x77, 0xD0, + 0x43, 0x0C, 0x7F, 0xF7, 0x36, 0x03, 0x29, 0xE0, 0x57, 0xBA, 0x97, 0x7F, + 0xF2, 0xD1, 0x51, 0xDB, 0xC9, 0x01, 0x47, 0xE7, 0x48, 0x36, +}; + +static std::array<uint8_t, 32> legacy_metadata_key_hmac = { + 0x88, 0x33, 0xDE, 0xD5, 0x4D, 0x00, 0x92, 0xE8, 0x80, 0x70, 0xD5, + 0x1F, 0x18, 0xEC, 0x22, 0x45, 0x75, 0x7C, 0x24, 0xDF, 0xE3, 0x8C, + 0xB2, 0xDE, 0x77, 0xB6, 0x78, 0x85, 0xFC, 0xA5, 0x67, 0x4D, +}; + +// The canned data in this test was taken from np_adv/tests/examples_v0.rs +TEST_F(NpCppTest, V0PrivateIdentitySimpleCase) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + std::span<uint8_t> metadata_span(encrypted_metadata); + nearby_protocol::MatchedCredentialData match_data(123, metadata_span); + + std::array<uint8_t, 32> key_seed = {}; + std::fill_n(key_seed.begin(), 32, 0x11); + + nearby_protocol::V0MatchableCredential v0_cred( + key_seed, legacy_metadata_key_hmac, match_data); + + auto add_result = slab_result->AddV0Credential(v0_cred); + ASSERT_EQ(add_result, absl::OkStatus()); + + auto book_result = + nearby_protocol::CredentialBook::TryCreateFromSlab(*slab_result); + ASSERT_TRUE(book_result.ok()); + + auto deserialize_result = + nearby_protocol::Deserializer::DeserializeAdvertisement( + V0AdvPrivateIdentity, *book_result); + ASSERT_EQ(deserialize_result.GetKind(), + nearby_protocol::DeserializeAdvertisementResultKind::V0); + + auto v0_adv = deserialize_result.IntoV0(); + auto kind = v0_adv.GetKind(); + ASSERT_EQ(kind, nearby_protocol::DeserializedV0AdvertisementKind::Legible); + + auto legible_adv = v0_adv.IntoLegible(); + auto identity_kind = legible_adv.GetIdentityKind(); + ASSERT_EQ(identity_kind, + nearby_protocol::DeserializedV0IdentityKind::Decrypted); + ASSERT_EQ(legible_adv.GetNumberOfDataElements(), 1); + + auto payload = legible_adv.IntoPayload(); + auto de = payload.TryGetDataElement(0); + ASSERT_TRUE(de.ok()); + + auto metadata = payload.DecryptMetadata(); + ASSERT_TRUE(metadata.ok()); + ASSERT_EQ(std::string("{\"name\":\"Alice\",\"email\":\"alice@gmail.com\"}"), + std::string(metadata->begin(), metadata->end())); + + auto identity_details = payload.GetIdentityDetails(); + ASSERT_TRUE(identity_details.ok()); + ASSERT_EQ(identity_details->cred_id, 123); + ASSERT_EQ(identity_details->identity_type, + nearby_protocol::EncryptedIdentityType::Private); + + auto de_type = de->GetKind(); + ASSERT_EQ(de_type, nearby_protocol::V0DataElementKind::TxPower); + + auto tx_power_de = de->AsTxPower(); + ASSERT_EQ(tx_power_de.tx_power, 3); +} + +static nearby_protocol::CredentialBook CreateEmptyCredBook() { + auto slab = nearby_protocol::CredentialSlab::TryCreate().value(); + auto book = nearby_protocol::CredentialBook::TryCreateFromSlab(slab).value(); + return book; +} + +TEST_F(NpCppTest, V0PrivateIdentityEmptyBook) { + auto book = CreateEmptyCredBook(); + auto deserialize_result = + nearby_protocol::Deserializer::DeserializeAdvertisement( + V0AdvPrivateIdentity, book); + ASSERT_EQ(deserialize_result.GetKind(), + nearby_protocol::DeserializeAdvertisementResultKind::V0); + + auto v0_adv = deserialize_result.IntoV0(); + ASSERT_EQ( + v0_adv.GetKind(), + nearby_protocol::DeserializedV0AdvertisementKind::NoMatchingCredentials); + + // Should not be able to actually access contents + ASSERT_DEATH([[maybe_unused]] auto failure = v0_adv.IntoLegible(), ""); +} + +TEST_F(NpCppTest, V0PrivateIdentityNoMatchingCreds) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + uint8_t metadata[] = {0}; + std::span<uint8_t> metadata_span(metadata); + nearby_protocol::MatchedCredentialData match_data(123, metadata_span); + + // A randomly picked key seed, does NOT match what was used for the canned adv + std::array<uint8_t, 32> key_seed = {}; + std::fill_n(key_seed.begin(), 31, 0x11); + + nearby_protocol::V0MatchableCredential v0_cred( + key_seed, legacy_metadata_key_hmac, match_data); + + auto add_result = slab_result->AddV0Credential(v0_cred); + ASSERT_EQ(add_result, absl::OkStatus()); + + auto book_result = + nearby_protocol::CredentialBook::TryCreateFromSlab(*slab_result); + ASSERT_TRUE(book_result.ok()); + + auto deserialize_result = + nearby_protocol::Deserializer::DeserializeAdvertisement( + V0AdvPrivateIdentity, *book_result); + ASSERT_EQ(deserialize_result.GetKind(), + nearby_protocol::DeserializeAdvertisementResultKind::V0); + + auto v0_adv = deserialize_result.IntoV0(); + ASSERT_EQ( + v0_adv.GetKind(), + nearby_protocol::DeserializedV0AdvertisementKind::NoMatchingCredentials); + + // Should not be able to actually access contents + ASSERT_DEATH([[maybe_unused]] auto failure = v0_adv.IntoLegible(), ""); +} + +// Make sure the correct credential is matched out of multiple provided +TEST_F(NpCppTest, V0PrivateIdentityMultipleCredentials) { + auto slab = nearby_protocol::CredentialSlab::TryCreate().value(); + std::span<uint8_t> metadata_span(encrypted_metadata); + std::array<uint8_t, 32> key_seed = {}; + + // Non matching credential + nearby_protocol::MatchedCredentialData match_data(123, metadata_span); + std::fill_n(key_seed.begin(), 32, 0x12); + nearby_protocol::V0MatchableCredential v0_cred( + key_seed, legacy_metadata_key_hmac, match_data); + ASSERT_TRUE(slab.AddV0Credential(v0_cred).ok()); + + // Matching credential + nearby_protocol::MatchedCredentialData match_data2(456, metadata_span); + std::fill_n(key_seed.begin(), 32, 0x11); + nearby_protocol::V0MatchableCredential v0_cred2( + key_seed, legacy_metadata_key_hmac, match_data2); + ASSERT_TRUE(slab.AddV0Credential(v0_cred2).ok()); + + // Non matching credential + nearby_protocol::MatchedCredentialData match_data3(789, metadata_span); + std::fill_n(key_seed.begin(), 32, 0x13); + nearby_protocol::V0MatchableCredential v0_cred3( + key_seed, legacy_metadata_key_hmac, match_data3); + ASSERT_TRUE(slab.AddV0Credential(v0_cred3).ok()); + + auto book = + nearby_protocol::CredentialBook::TryCreateFromSlab(slab).value(); + auto legible_adv = + nearby_protocol::Deserializer::DeserializeAdvertisement( + V0AdvPrivateIdentity, book).IntoV0().IntoLegible(); + ASSERT_EQ(legible_adv.GetIdentityKind(), + nearby_protocol::DeserializedV0IdentityKind::Decrypted); + ASSERT_EQ(legible_adv.GetNumberOfDataElements(), 1); + + auto payload = legible_adv.IntoPayload(); + ASSERT_TRUE(payload.TryGetDataElement(0).ok()); + + // Make sure the correct credential matches + auto identity_details = payload.GetIdentityDetails(); + ASSERT_TRUE(identity_details.ok()); + ASSERT_EQ(identity_details->cred_id, 456); + ASSERT_EQ(identity_details->identity_type, + nearby_protocol::EncryptedIdentityType::Private); +} diff --git a/nearby/presence/np_cpp_ffi/tests/deserialize_v0_tests.cc b/nearby/presence/np_cpp_ffi/tests/v0_public_identity_tests.cc index 54b17ab..3ed2d79 100644 --- a/nearby/presence/np_cpp_ffi/tests/deserialize_v0_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/v0_public_identity_tests.cc @@ -15,7 +15,6 @@ #include "nearby_protocol.h" #include "shared_test_util.h" #include "np_cpp_test.h" - #include "gtest/gtest.h" TEST_F(NpCppTest, InvalidCast) { diff --git a/nearby/presence/np_cpp_ffi/tests/v1_private_identity_tests.cc b/nearby/presence/np_cpp_ffi/tests/v1_private_identity_tests.cc new file mode 100644 index 0000000..8cd0bd0 --- /dev/null +++ b/nearby/presence/np_cpp_ffi/tests/v1_private_identity_tests.cc @@ -0,0 +1,130 @@ +// 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. + +#include "nearby_protocol.h" +#include "np_cpp_test.h" +#include "gtest/gtest.h" +#include <algorithm> + +// All canned data output from np_adv/tests/examples_v1.rs +static nearby_protocol::RawAdvertisementPayload + V1AdvPrivateIdentity(nearby_protocol::ByteBuffer<255>( + {105, + { + 0x20, 0x67, 0x91, 0x10, 0x08, 0xAD, 0x69, 0x46, 0x04, 0x5D, 0xAE, + 0x6D, 0xB7, 0xF7, 0x5C, 0xD3, 0xB8, 0xAC, 0xF0, 0xBF, 0x75, 0x90, + 0x01, 0xBE, 0x73, 0x33, 0xA4, 0x76, 0x84, 0x4A, 0x09, 0x0F, 0x2B, + 0x99, 0x47, 0xDF, 0x8B, 0x46, 0xCA, 0x16, 0xCE, 0x13, 0xB5, 0x6E, + 0x53, 0xAE, 0x28, 0x56, 0x44, 0x0E, 0xA6, 0x8D, 0xEB, 0xA1, 0x11, + 0xAF, 0x4E, 0x1B, 0xE0, 0x8E, 0xF5, 0xBA, 0x90, 0x4F, 0x2E, 0x94, + 0xFC, 0xDE, 0xA6, 0x7F, 0x5D, 0xC8, 0x37, 0xB7, 0xEF, 0xCA, 0xAC, + 0x8B, 0x9F, 0x1B, 0xD4, 0xC6, 0x11, 0x85, 0xD3, 0x67, 0x39, 0x32, + 0xD1, 0x82, 0xCA, 0x4E, 0xB9, 0x46, 0x03, 0x83, 0x68, 0x56, 0x0B, + 0xCC, 0xFD, 0x7A, 0x2A, 0xBE, 0x07, + }})); + +static std::array<uint8_t, 32> key_seed = { + 0x31, 0x43, 0x63, 0x1E, 0xCA, 0xE8, 0x97, 0x4B, 0x96, 0x50, 0xCC, + 0x1C, 0x48, 0x25, 0x0E, 0x81, 0x58, 0x06, 0x81, 0x51, 0xF9, 0xEB, + 0x25, 0x23, 0x03, 0xD4, 0x97, 0x6D, 0x95, 0x19, 0x91, 0x39, +}; + +static std::array<uint8_t, 32> expected_unsigned_metadata_key_hmac = {0}; + +static std::array<uint8_t, 32> expected_signed_metadata_key_hmac = { + 0x1C, 0xBC, 0xEB, 0xDC, 0x17, 0xB5, 0x91, 0xE5, 0x07, 0x9D, 0x70, + 0xC1, 0xE8, 0x4B, 0xCC, 0xDB, 0x4B, 0x0F, 0x76, 0x83, 0x59, 0x62, + 0x0A, 0x2D, 0x55, 0x0B, 0x3B, 0x36, 0xA4, 0x92, 0x8B, 0x13, +}; + +static std::array<uint8_t, 32> public_key = { + 0x6D, 0x0D, 0xB6, 0x09, 0x10, 0xB1, 0x4E, 0xC4, 0x7E, 0x10, 0x16, + 0x14, 0x9C, 0x9F, 0xF2, 0x14, 0x0F, 0xEC, 0x53, 0x76, 0xE3, 0x07, + 0xD9, 0xD3, 0x9E, 0xAE, 0xE7, 0x45, 0x2C, 0x03, 0xEC, 0x6D, +}; + +static uint8_t encrypted_metadata[] = { + 0x09, 0xB8, 0xC6, 0x6B, 0x71, 0x43, 0x55, 0x4C, 0xB9, 0x9D, 0xBF, + 0xE4, 0xAF, 0x3E, 0xA2, 0x56, 0x0E, 0x6C, 0xBC, 0xDC, 0x3F, 0x3F, + 0x0D, 0x28, 0xD4, 0x50, 0xA9, 0xEA, 0xC3, 0x60, 0xB0, 0x81, 0x31, + 0xE2, 0x67, 0xB5, 0xC8, 0x15, 0x0C, 0xCA, 0x0B, 0x9B, 0x2C, 0x80, + 0xC1, 0xB1, 0xF6, 0x5F, 0xE1, 0x51, 0xF9, 0xE2, 0x23, 0x56, 0xD4, + 0x0B, 0x89, 0xA7, 0xF3, 0x4D, 0xE8, 0x79, 0x26, 0x44, 0x7E, 0x62, + 0xDE, 0x53, 0x13, 0x15, 0x3D, 0xFC, 0x04, 0x2E, 0x2D, 0x08, 0x43, + 0x2E, 0xE1, 0x96, 0xE8, 0x0F, 0xD0, 0xFC, 0xDE, 0x03, 0x86, 0x23, + 0xB6, 0x98, 0x85, 0x27, 0x67, 0xD8, 0x1D, 0xC3, 0xE2, 0xE0, 0xA4, + 0x32, 0x1A, 0x5F, 0x51, 0x0B, 0xA8, 0xD8, 0xA7, 0x23, 0xA4, 0x57, +}; + +TEST_F(NpCppTest, V1PrivateIdentitySimpleCase) { + auto slab_result = nearby_protocol::CredentialSlab::TryCreate(); + ASSERT_TRUE(slab_result.ok()); + + std::span<uint8_t> metadata_span(encrypted_metadata); + nearby_protocol::MatchedCredentialData match_data(123, metadata_span); + + nearby_protocol::V1MatchableCredential v1_cred( + key_seed, expected_unsigned_metadata_key_hmac, + expected_signed_metadata_key_hmac, public_key, match_data); + + auto add_result = slab_result->AddV1Credential(v1_cred); + ASSERT_EQ(add_result, absl::OkStatus()); + + auto book_result = + nearby_protocol::CredentialBook::TryCreateFromSlab(*slab_result); + ASSERT_TRUE(book_result.ok()); + + auto deserialize_result = + nearby_protocol::Deserializer::DeserializeAdvertisement( + V1AdvPrivateIdentity, *book_result); + ASSERT_EQ(deserialize_result.GetKind(), + nearby_protocol::DeserializeAdvertisementResultKind::V1); + + auto v1_adv = deserialize_result.IntoV1(); + ASSERT_EQ(v1_adv.GetNumUndecryptableSections(), 0); + ASSERT_EQ(v1_adv.GetNumLegibleSections(), 1); + + auto section = v1_adv.TryGetSection(0); + ASSERT_TRUE(section.ok()); + ASSERT_EQ(section->GetIdentityKind(), + nearby_protocol::DeserializedV1IdentityKind::Decrypted); + ASSERT_EQ(section->NumberOfDataElements(), 1); + + auto metadata = section->DecryptMetadata(); + ASSERT_TRUE(metadata.ok()); + ASSERT_EQ( + std::string("{\"uuid\":\"378845e1-2616-420d-86f5-674177a7504d\"," + "\"display_name\":\"Alice\",\"location\":\"Wonderland\"}"), + std::string(metadata->begin(), metadata->end())); + + auto identity_details = section->GetIdentityDetails(); + ASSERT_TRUE(identity_details.ok()); + ASSERT_EQ(identity_details->cred_id, 123); + ASSERT_EQ(identity_details->verification_mode, + nearby_protocol::V1VerificationMode::Signature); + ASSERT_EQ(identity_details->identity_type, + nearby_protocol::EncryptedIdentityType::Private); + + auto de = section->TryGetDataElement(0); + ASSERT_TRUE(de.ok()); + ASSERT_EQ(de->GetDataElementTypeCode(), 5); + ASSERT_EQ(de->GetPayload().ToVector(), std::vector<uint8_t>{7}); + + auto offset = de->GetOffset(); + auto derived_salt = section->DeriveSaltForOffset(offset); + ASSERT_TRUE(derived_salt.ok()); + std::array<uint8_t, 16> expected = + {94, 154, 245, 152, 164, 22, 131, 157, 8, 79, 28, 77, 236, 57, 17, 97}; + ASSERT_EQ(*derived_salt, expected); +}
\ No newline at end of file diff --git a/nearby/presence/np_cpp_ffi/tests/deserialize_v1_tests.cc b/nearby/presence/np_cpp_ffi/tests/v1_public_identity_tests.cc index aa32f7b..aa32f7b 100644 --- a/nearby/presence/np_cpp_ffi/tests/deserialize_v1_tests.cc +++ b/nearby/presence/np_cpp_ffi/tests/v1_public_identity_tests.cc diff --git a/nearby/presence/np_ffi_core/Cargo.toml b/nearby/presence/np_ffi_core/Cargo.toml index 0c14d1c..6c9a6f4 100644 --- a/nearby/presence/np_ffi_core/Cargo.toml +++ b/nearby/presence/np_ffi_core/Cargo.toml @@ -11,6 +11,7 @@ workspace = true array_view.workspace = true ldt_np_adv.workspace = true np_adv = { workspace = true, features = ["alloc"] } +np_adv_dynamic.workspace = true np_hkdf.workspace = true handle_map.workspace = true crypto_provider.workspace = true diff --git a/nearby/presence/np_ffi_core/src/common.rs b/nearby/presence/np_ffi_core/src/common.rs index 6333db5..5996e80 100644 --- a/nearby/presence/np_ffi_core/src/common.rs +++ b/nearby/presence/np_ffi_core/src/common.rs @@ -15,12 +15,14 @@ //! in order to define the interfaces in this crate's various modules. use array_view::ArrayView; +use crypto_provider::{CryptoProvider, CryptoRng}; +use crypto_provider_default::CryptoProviderImpl; use handle_map::HandleNotPresentError; -use lock_adapter::std::RwLock; +use lock_adapter::std::{RwLock, RwLockWriteGuard}; use lock_adapter::RwLock as _; use std::string::String; -const DEFAULT_MAX_HANDLES: u32 = u32::MAX - 1; +pub(crate) const DEFAULT_MAX_HANDLES: u32 = u32::MAX - 1; /// Configuration for top-level constants to be used /// by the rest of the FFI which are independent of @@ -61,6 +63,12 @@ pub struct CommonConfig { /// value will be set to `u32::MAX - 1`, which is the upper-bound /// on this value. max_num_deserialized_v1_advertisements: u32, + + /// The maximum number of v1 advertisement builders + /// which may be active at any one time. By default, this + /// value will be set to `u32::MAX - 1`, which is the upper-bound + /// on this value. + max_num_v1_advertisement_builders: u32, } impl Default for CommonConfig { @@ -77,6 +85,7 @@ impl CommonConfig { max_num_credential_books: DEFAULT_MAX_HANDLES, max_num_deserialized_v0_advertisements: DEFAULT_MAX_HANDLES, max_num_deserialized_v1_advertisements: DEFAULT_MAX_HANDLES, + max_num_v1_advertisement_builders: DEFAULT_MAX_HANDLES, } } #[cfg(feature = "std")] @@ -110,6 +119,9 @@ impl CommonConfig { pub(crate) fn max_num_deserialized_v1_advertisements(&self) -> u32 { self.max_num_deserialized_v1_advertisements } + pub(crate) fn max_num_v1_advertisement_builders(&self) -> u32 { + self.max_num_v1_advertisement_builders + } pub(crate) fn set_num_shards(&mut self, num_shards: u8) { self.num_shards = num_shards } @@ -139,7 +151,7 @@ impl CommonConfig { DEFAULT_MAX_HANDLES.min(max_num_deserialized_v0_advertisements) } - /// Sets the maximum number of active handles to deserialized v0 + /// Sets the maximum number of active handles to deserialized v1 /// advertisements which may be active at any one time. /// Max value: `u32::MAX - 1`. pub fn set_max_num_deserialized_v1_advertisements( @@ -149,6 +161,16 @@ impl CommonConfig { self.max_num_deserialized_v1_advertisements = DEFAULT_MAX_HANDLES.min(max_num_deserialized_v1_advertisements) } + /// Sets the maximum number of active handles to v1 advertisement + /// builders which may be active at any one time. + /// Max value: `u32::MAX - 1`. + pub fn set_max_num_v1_advertisement_builders( + &mut self, + max_num_v1_advertisement_builders: u32, + ) { + self.max_num_v1_advertisement_builders = + DEFAULT_MAX_HANDLES.min(max_num_v1_advertisement_builders) + } } static COMMON_CONFIG: RwLock<CommonConfig> = RwLock::new(CommonConfig::new()); @@ -168,6 +190,9 @@ pub(crate) fn global_max_num_deserialized_v0_advertisements() -> u32 { pub(crate) fn global_max_num_deserialized_v1_advertisements() -> u32 { COMMON_CONFIG.read().max_num_deserialized_v1_advertisements() } +pub(crate) fn global_max_num_v1_advertisement_builders() -> u32 { + COMMON_CONFIG.read().max_num_v1_advertisement_builders() +} /// Sets an override to the number of shards to employ in the NP FFI's /// internal handle-maps, which places an upper bound on the number @@ -271,8 +296,12 @@ pub struct RawAdvertisementPayload { impl RawAdvertisementPayload { /// Yields a slice of the bytes in this raw advertisement payload. + #[allow(clippy::unwrap_used)] pub fn as_slice(&self) -> &[u8] { - self.bytes.as_slice() + // The unwrapping here will never trigger a panic, + // because the byte-buffer is 255 bytes, the byte-length + // of which is the maximum value storable in a u8. + self.bytes.as_slice().unwrap() } } @@ -289,6 +318,21 @@ pub struct ByteBuffer<const N: usize> { bytes: [u8; N], } +/// A FFI safe wrapper of a fixed size array +#[repr(C)] +pub struct FixedSizeArray<const N: usize>([u8; N]); + +impl<const N: usize> FixedSizeArray<N> { + /// Constructs a byte-buffer from a Rust-side-derived owned array + pub(crate) fn from_array(bytes: [u8; N]) -> Self { + Self(bytes) + } + /// Yields a slice of the bytes + pub fn as_slice(&self) -> &[u8] { + self.0.as_slice() + } +} + impl<const N: usize> ByteBuffer<N> { /// Constructs a byte-buffer from a Rust-side-derived /// ArrayView, which is assumed to be trusted to be @@ -300,11 +344,39 @@ impl<const N: usize> ByteBuffer<N> { Self { len, bytes } } /// Yields a slice of the first `self.len` bytes of `self.bytes`. - pub fn as_slice(&self) -> &[u8] { - &self.bytes[..(self.len as usize)] + pub fn as_slice(&self) -> Option<&[u8]> { + if self.len as usize <= N { + Some(&self.bytes[..(self.len as usize)]) + } else { + None + } + } +} + +pub(crate) type CryptoRngImpl = <CryptoProviderImpl as CryptoProvider>::CryptoRng; + +pub(crate) struct LazyInitCryptoRng { + maybe_rng: Option<CryptoRngImpl>, +} + +impl LazyInitCryptoRng { + const fn new() -> Self { + Self { maybe_rng: None } + } + pub(crate) fn get_rng(&mut self) -> &mut CryptoRngImpl { + self.maybe_rng.get_or_insert_with(CryptoRngImpl::new) } } +/// Shared, lazily-initialized cryptographically-secure +/// RNG for all operations in the FFI core. +static CRYPTO_RNG: RwLock<LazyInitCryptoRng> = RwLock::new(LazyInitCryptoRng::new()); + +/// Gets a write guard to the (lazily-init) library-global crypto rng. +pub(crate) fn get_global_crypto_rng() -> RwLockWriteGuard<'static, LazyInitCryptoRng> { + CRYPTO_RNG.write() +} + /// The DE type for an encrypted identity #[derive(Clone, Copy)] #[repr(u8)] @@ -320,6 +392,17 @@ pub enum EncryptedIdentityType { Provisioned = 4, } +impl From<EncryptedIdentityType> for np_adv::de_type::EncryptedIdentityDataElementType { + fn from(val: EncryptedIdentityType) -> np_adv::de_type::EncryptedIdentityDataElementType { + use np_adv::de_type::EncryptedIdentityDataElementType; + match val { + EncryptedIdentityType::Private => EncryptedIdentityDataElementType::Private, + EncryptedIdentityType::Trusted => EncryptedIdentityDataElementType::Trusted, + EncryptedIdentityType::Provisioned => EncryptedIdentityDataElementType::Provisioned, + } + } +} + impl From<np_adv::de_type::EncryptedIdentityDataElementType> for EncryptedIdentityType { fn from(value: np_adv::de_type::EncryptedIdentityDataElementType) -> Self { use np_adv::de_type::EncryptedIdentityDataElementType; diff --git a/nearby/presence/np_ffi_core/src/credentials.rs b/nearby/presence/np_ffi_core/src/credentials.rs index 0972d45..c1fc808 100644 --- a/nearby/presence/np_ffi_core/src/credentials.rs +++ b/nearby/presence/np_ffi_core/src/credentials.rs @@ -380,3 +380,37 @@ pub fn deallocate_credential_book(credential_book: CredentialBook) -> Deallocate pub fn deallocate_credential_slab(credential_slab: CredentialSlab) -> DeallocateResult { credential_slab.deallocate().map(|_| ()).into() } + +/// Cryptographic information about a particular V1 broadcast credential +/// necessary to encrypt V1 MIC-verified and signature-verified sections. +#[repr(C)] +pub struct V1BroadcastCredential { + key_seed: [u8; 32], + metadata_key: [u8; 16], + private_key: [u8; 32], +} + +impl V1BroadcastCredential { + /// Constructs a new `V1BroadcastCredential` from the given + /// key-seed, 16-byte metadata key, and the raw bytes + /// of the ed25519 private key. + /// + /// Safety: Since this representation requires transmission + /// of the raw bytes of an ed25519 private key (and other + /// sensitive cryptographic info) over FFI, foreign-lang + /// code around how this information is maintained + /// deserves close scrutiny. + pub fn new(key_seed: [u8; 32], metadata_key: [u8; 16], private_key: [u8; 32]) -> Self { + Self { key_seed, metadata_key, private_key } + } + pub(crate) fn into_internal( + self, + ) -> np_adv::credential::v1::SimpleSignedBroadcastCryptoMaterial { + let permit = crypto_provider::ed25519::RawPrivateKeyPermit::default(); + np_adv::credential::v1::SimpleSignedBroadcastCryptoMaterial::new( + self.key_seed, + np_adv::MetadataKey(self.metadata_key), + crypto_provider::ed25519::PrivateKey::from_raw_private_key(self.private_key, &permit), + ) + } +} diff --git a/nearby/presence/np_ffi_core/src/deserialize/mod.rs b/nearby/presence/np_ffi_core/src/deserialize/mod.rs index 44510f6..5c1a891 100644 --- a/nearby/presence/np_ffi_core/src/deserialize/mod.rs +++ b/nearby/presence/np_ffi_core/src/deserialize/mod.rs @@ -19,7 +19,9 @@ use crate::deserialize::v0::*; use crate::deserialize::v1::*; use crate::utils::FfiEnum; use crypto_provider_default::CryptoProviderImpl; -use handle_map::{HandleLike, HandleMapFullError, HandleNotPresentError}; +use handle_map::{ + declare_handle_map, HandleLike, HandleMapDimensions, HandleMapFullError, HandleNotPresentError, +}; use np_adv::deserialization_arena; pub mod v0; @@ -154,8 +156,8 @@ pub fn deserialize_advertisement( deserialize_advertisement_from_slice(adv_payload.as_slice(), credential_book) } -/// Errors returned from [`crate::deserialize::v0::v0_payload::V0Payload#decrypt_metadata`]. -pub enum DecryptMetadataError { +/// Errors returned from attempting to decrypt metadata +pub(crate) enum DecryptMetadataError { /// The advertisement payload handle was either deallocated /// or corresponds to a public advertisement, and so we /// don't have any metadata to decrypt. @@ -163,3 +165,122 @@ pub enum DecryptMetadataError { /// Decryption of the raw metadata bytes failed. DecryptionFailed, } + +/// The result of decrypting metadata from either a V0Payload or DeserializedV1Section +#[repr(C)] +#[allow(missing_docs)] +pub enum DecryptMetadataResult { + Success(DecryptedMetadata), + Error, +} + +/// Discriminant for `DecryptMetadataResult`. +#[repr(u8)] +pub enum DecryptMetadataResultKind { + /// The attempt to decrypt the metadata of the associated credential succeeded + /// The associated payload may be obtained via + /// `DecryptMetadataResult#into_success`. + Success, + /// The attempt to decrypt the metadata failed, either the payload had no matching identity + /// ie it was a public advertisement OR the decrypt attempt itself was unsuccessful + Error, +} + +impl FfiEnum for DecryptMetadataResult { + type Kind = DecryptMetadataResultKind; + + fn kind(&self) -> Self::Kind { + match self { + DecryptMetadataResult::Success(_) => DecryptMetadataResultKind::Success, + DecryptMetadataResult::Error => DecryptMetadataResultKind::Error, + } + } +} + +impl DecryptMetadataResult { + declare_enum_cast! {into_success, Success, DecryptedMetadata} +} + +/// Internals of decrypted metadata +pub struct DecryptedMetadataInternals { + decrypted_bytes: Box<[u8]>, +} + +declare_handle_map! { + mod decrypted_metadata { + #[dimensions = super::get_decrypted_metadata_handle_map_dimensions()] + type DecryptedMetadata: HandleLike<Object = super::DecryptedMetadataInternals>; + } +} +use decrypted_metadata::DecryptedMetadata; + +fn get_decrypted_metadata_handle_map_dimensions() -> HandleMapDimensions { + HandleMapDimensions { num_shards: global_num_shards(), max_active_handles: DEFAULT_MAX_HANDLES } +} + +/// The pointer and length of the decrypted metadata byte buffer +#[repr(C)] +pub struct MetadataBufferParts { + ptr: *const u8, + len: usize, +} + +#[repr(C)] +#[allow(missing_docs)] +pub enum GetMetadataBufferPartsResult { + Success(MetadataBufferParts), + Error, +} + +impl GetMetadataBufferPartsResult { + declare_enum_cast! {into_success, Success, MetadataBufferParts} +} + +#[repr(u8)] +#[allow(missing_docs)] +pub enum GetMetadataBufferPartsResultKind { + Success = 0, + Error = 1, +} + +impl FfiEnum for GetMetadataBufferPartsResult { + type Kind = GetMetadataBufferPartsResultKind; + + fn kind(&self) -> Self::Kind { + match self { + GetMetadataBufferPartsResult::Success(_) => GetMetadataBufferPartsResultKind::Success, + GetMetadataBufferPartsResult::Error => GetMetadataBufferPartsResultKind::Error, + } + } +} + +fn allocate_decrypted_metadata_handle(metadata: Vec<u8>) -> DecryptMetadataResult { + let allocate_result = DecryptedMetadata::allocate(move || DecryptedMetadataInternals { + decrypted_bytes: metadata.into_boxed_slice(), + }); + match allocate_result { + Ok(decrypted) => DecryptMetadataResult::Success(decrypted), + Err(_) => DecryptMetadataResult::Error, + } +} + +impl DecryptedMetadata { + /// Gets the raw parts, pointer + length representation of the metadata byte buffer + pub fn get_metadata_buffer_parts(&self) -> GetMetadataBufferPartsResult { + match self.get() { + Ok(metadata_internals) => { + let result = MetadataBufferParts { + ptr: metadata_internals.decrypted_bytes.as_ptr(), + len: metadata_internals.decrypted_bytes.len(), + }; + GetMetadataBufferPartsResult::Success(result) + } + Err(_) => GetMetadataBufferPartsResult::Error, + } + } + + /// Frees the underlying decrypted metadata buffer + pub fn deallocate_metadata(&self) -> DeallocateResult { + self.deallocate().map(|_| ()).into() + } +} diff --git a/nearby/presence/np_ffi_core/src/deserialize/v0.rs b/nearby/presence/np_ffi_core/src/deserialize/v0.rs index a07b9d8..14214c4 100644 --- a/nearby/presence/np_ffi_core/src/deserialize/v0.rs +++ b/nearby/presence/np_ffi_core/src/deserialize/v0.rs @@ -16,7 +16,9 @@ use crate::common::*; use crate::credentials::credential_book::CredentialBook; use crate::credentials::MatchedCredential; -use crate::deserialize::DecryptMetadataError; +use crate::deserialize::{ + allocate_decrypted_metadata_handle, DecryptMetadataError, DecryptMetadataResult, +}; use crate::utils::{FfiEnum, LocksLongerThan}; use crypto_provider_default::CryptoProviderImpl; use handle_map::{declare_handle_map, HandleLike, HandleMapDimensions, HandleMapFullError}; @@ -399,7 +401,7 @@ impl V0Payload { } /// Gets the identity details for this V0 payload, - /// if this payload was associted with an identity + /// if this payload was associated with an identity /// (i.e: non-public advertisements). pub fn get_identity_details(&self) -> GetV0IdentityDetailsResult { match self.get() { @@ -410,17 +412,13 @@ impl V0Payload { /// Attempts to decrypt the metadata for the matched /// credential for this V0 payload (if any) - /// - /// Note that while this method is publicly exposed - /// from `np_ffi_core`, since it involves the (FFI-layer-unexpressed) - /// type `Vec<u8>`, a direct wrapper will not suffice, - /// and instead a language-specific binding will need to - /// be generated for this method which respects the - /// expected memory-management semantics of the target language. - pub fn decrypt_metadata(&self) -> Result<Vec<u8>, DecryptMetadataError> { + pub fn decrypt_metadata(&self) -> DecryptMetadataResult { match self.get() { - Ok(read_guard) => read_guard.decrypt_metadata(), - Err(_) => Err(DecryptMetadataError::EncryptedMetadataNotAvailable), + Ok(read_guard) => match read_guard.decrypt_metadata() { + Ok(decrypted_metadata) => allocate_decrypted_metadata_handle(decrypted_metadata), + Err(_) => DecryptMetadataResult::Error, + }, + Err(_) => DecryptMetadataResult::Error, } } diff --git a/nearby/presence/np_ffi_core/src/deserialize/v1.rs b/nearby/presence/np_ffi_core/src/deserialize/v1.rs index 4684f55..cb56b33 100644 --- a/nearby/presence/np_ffi_core/src/deserialize/v1.rs +++ b/nearby/presence/np_ffi_core/src/deserialize/v1.rs @@ -17,8 +17,9 @@ use super::DeserializeAdvertisementError; use crate::common::*; use crate::credentials::credential_book::CredentialBook; use crate::credentials::MatchedCredential; -use crate::deserialize::DecryptMetadataError; +use crate::deserialize::{allocate_decrypted_metadata_handle, DecryptMetadataResult}; use crate::utils::*; +use crate::v1::V1VerificationMode; use array_view::ArrayView; use crypto_provider_default::CryptoProviderImpl; use handle_map::{declare_handle_map, HandleLike, HandleMapDimensions}; @@ -229,12 +230,15 @@ pub enum GetV1DE16ByteSaltResultKind { /// The result of attempting to get a derived 16-byte salt /// for a given DE within a section. -#[derive(Copy, Clone)] #[repr(C)] #[allow(missing_docs)] pub enum GetV1DE16ByteSaltResult { Error, - Success([u8; 16]), + Success(FixedSizeArray<16>), +} + +impl GetV1DE16ByteSaltResult { + declare_enum_cast! {into_success, Success, FixedSizeArray<16>} } impl FfiEnum for GetV1DE16ByteSaltResult { @@ -258,6 +262,7 @@ impl DeserializedV1SectionInternals { fn num_des(&self) -> u8 { self.des.len() as u8 } + /// Gets the enum tag of the identity used for this section. fn identity_kind(&self) -> DeserializedV1IdentityKind { if self.identity.is_some() { @@ -266,6 +271,7 @@ impl DeserializedV1SectionInternals { DeserializedV1IdentityKind::Plaintext } } + /// Attempts to get the DE with the given index in this section. fn get_de(&self, index: u8) -> GetV1DEResult { match self.des.get(index as usize) { @@ -273,6 +279,7 @@ impl DeserializedV1SectionInternals { None => GetV1DEResult::Error, } } + /// Attempts to get the directly-transmissible details about /// the deserialized V1 identity for this section. Does /// not include decrypted metadata bytes nor the section salt. @@ -282,16 +289,19 @@ impl DeserializedV1SectionInternals { None => GetV1IdentityDetailsResult::Error, } } + /// Attempts to decrypt the metadata for the matched /// credential for this V1 section (if any). - pub(crate) fn decrypt_metadata(&self) -> Result<Vec<u8>, DecryptMetadataError> { + pub(crate) fn decrypt_metadata(&self) -> DecryptMetadataResult { match &self.identity { - None => Err(DecryptMetadataError::EncryptedMetadataNotAvailable), - Some(identity) => { - identity.decrypt_metadata().ok_or(DecryptMetadataError::DecryptionFailed) - } + None => DecryptMetadataResult::Error, + Some(identity) => match identity.decrypt_metadata() { + None => DecryptMetadataResult::Error, + Some(metadata) => allocate_decrypted_metadata_handle(metadata), + }, } } + /// Attempts to derive a 16-byte DE salt for a DE in this section /// with the given DE offset. This operation may fail if the /// passed offset is 255 (causes overflow) or if the section @@ -411,32 +421,13 @@ impl DeserializedV1IdentityInternals { } /// For a given data-element offset, derives a 16-byte DE salt /// for a DE in that position within this section. - pub(crate) fn derive_16_byte_salt_for_offset(&self, de_offset: u8) -> Option<[u8; 16]> { + pub(crate) fn derive_16_byte_salt_for_offset( + &self, + de_offset: u8, + ) -> Option<FixedSizeArray<16>> { let section_salt = np_hkdf::v1_salt::V1Salt::<CryptoProviderImpl>::from(self.salt); let de_offset = np_hkdf::v1_salt::DataElementOffset::from(de_offset); - section_salt.derive::<16>(Some(de_offset)) - } -} - -/// Information about the verification scheme used -/// for verifying the integrity of the contents -/// of a decrypted section. -#[derive(Clone, Copy)] -#[repr(u8)] -pub enum V1VerificationMode { - /// Message integrity code verification. - Mic = 0, - /// Signature verification. - Signature = 1, -} - -impl From<np_adv::extended::deserialize::VerificationMode> for V1VerificationMode { - fn from(verification_mode: np_adv::extended::deserialize::VerificationMode) -> Self { - use np_adv::extended::deserialize::VerificationMode; - match verification_mode { - VerificationMode::Mic => Self::Mic, - VerificationMode::Signature => Self::Signature, - } + section_salt.derive::<16>(Some(de_offset)).map(FixedSizeArray::from_array) } } @@ -550,23 +541,6 @@ impl DeserializedV1Section { self.identity_tag } - fn apply_to_section_internals<R>( - &self, - func: impl FnOnce(&DeserializedV1SectionInternals) -> R, - lookup_failure_result: R, - ) -> R { - // TODO: Once the `FromResidual` trait is stabilized, this can be simplified. - match self.legible_sections_handle.get() { - Ok(legible_sections_read_guard) => { - match legible_sections_read_guard.get_section_internals(self.legible_section_index) - { - Some(section_ref) => func(section_ref), - None => lookup_failure_result, - } - } - Err(_) => lookup_failure_result, - } - } /// Gets the DE with the given index in this section. pub fn get_de(&self, de_index: u8) -> GetV1DEResult { self.apply_to_section_internals( @@ -587,10 +561,10 @@ impl DeserializedV1Section { /// Attempts to decrypt the metadata for the matched /// credential for the V1 section referenced by /// this handle (if any). - pub fn decrypt_metadata(&self) -> Result<Vec<u8>, DecryptMetadataError> { + pub fn decrypt_metadata(&self) -> DecryptMetadataResult { self.apply_to_section_internals( DeserializedV1SectionInternals::decrypt_metadata, - Err(DecryptMetadataError::EncryptedMetadataNotAvailable), + DecryptMetadataResult::Error, ) } /// Attempts to derive a 16-byte DE salt for a DE in this section @@ -604,6 +578,24 @@ impl DeserializedV1Section { GetV1DE16ByteSaltResult::Error, ) } + + fn apply_to_section_internals<R>( + &self, + func: impl FnOnce(&DeserializedV1SectionInternals) -> R, + lookup_failure_result: R, + ) -> R { + // TODO: Once the `FromResidual` trait is stabilized, this can be simplified. + match self.legible_sections_handle.get() { + Ok(legible_sections_read_guard) => { + match legible_sections_read_guard.get_section_internals(self.legible_section_index) + { + Some(section_ref) => func(section_ref), + None => lookup_failure_result, + } + } + Err(_) => lookup_failure_result, + } + } } /// Discriminant for the `GetV1DEResult` enum. diff --git a/nearby/presence/np_ffi_core/src/lib.rs b/nearby/presence/np_ffi_core/src/lib.rs index 0c25168..f3bb7a3 100644 --- a/nearby/presence/np_ffi_core/src/lib.rs +++ b/nearby/presence/np_ffi_core/src/lib.rs @@ -22,3 +22,5 @@ pub mod utils; pub mod common; pub mod credentials; pub mod deserialize; +pub mod serialize; +pub mod v1; diff --git a/nearby/presence/np_ffi_core/src/serialize/mod.rs b/nearby/presence/np_ffi_core/src/serialize/mod.rs new file mode 100644 index 0000000..aeb68a0 --- /dev/null +++ b/nearby/presence/np_ffi_core/src/serialize/mod.rs @@ -0,0 +1,38 @@ +// 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. +//! Core NP Rust FFI structures and methods for advertisement serialization. + +pub mod v1; + +/// Enum common to V0 and V1 serialization expressing +/// what kind of advertisement builder (public/encrypted) +/// is in use. +#[derive(Clone, Copy)] +#[repr(u8)] +pub enum AdvertisementBuilderKind { + /// The builder is for a public advertisement. + Public = 0, + /// The builder is for an encrypted advertisement. + Encrypted = 1, +} + +impl AdvertisementBuilderKind { + pub(crate) fn as_internal_v1(&self) -> np_adv::extended::serialize::AdvertisementType { + use np_adv::extended::serialize::AdvertisementType; + match self { + Self::Public => AdvertisementType::Plaintext, + Self::Encrypted => AdvertisementType::Encrypted, + } + } +} diff --git a/nearby/presence/np_ffi_core/src/serialize/v1.rs b/nearby/presence/np_ffi_core/src/serialize/v1.rs new file mode 100644 index 0000000..ccc6ef7 --- /dev/null +++ b/nearby/presence/np_ffi_core/src/serialize/v1.rs @@ -0,0 +1,589 @@ +// 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. + +//! NP Rust FFI structures and methods for V1 advertisement serialization. + +use crate::common::*; +use crate::credentials::V1BroadcastCredential; +use crate::serialize::AdvertisementBuilderKind; +use crate::utils::FfiEnum; +use crate::v1::V1VerificationMode; +use crypto_provider_default::CryptoProviderImpl; +use handle_map::{declare_handle_map, HandleLike, HandleMapDimensions, HandleMapFullError}; +use np_adv; +use np_adv_dynamic; + +/// A handle to a builder for V1 advertisements. +#[derive(Clone, Copy)] +#[repr(C)] +pub struct V1AdvertisementBuilder { + kind: AdvertisementBuilderKind, + handle: V1AdvertisementBuilderHandle, +} + +impl V1AdvertisementBuilder { + /// Attempts to create a builder for a new public section within + /// this advertisement, returning a handle to the newly-created + /// section builder if successful. + /// + /// This method may fail if there is another currently-active + /// section builder for the same advertisement builder, if the + /// kind of section being added does not match the advertisement + /// type (public/encrypted), or if the section would not manage + /// to fit within the enclosing advertisement. + pub fn public_section_builder(&self) -> CreateV1SectionBuilderResult { + self.section_builder_internals(|internals| internals.public_section_builder()) + } + /// Attempts to create a builder for a new encrypted section within + /// this advertisement, returning a handle to the newly-created + /// section builder if successful. + /// + /// The identity details for the new section builder may be specified + /// via providing the broadcast credential data, the kind of encrypted + /// identity being broadcast (private/trusted/provisioned), and the + /// verification mode (MIC/Signature) to be used for the encrypted section. + /// + /// This method may fail if there is another currently-active + /// section builder for the same advertisement builder, if the + /// kind of section being added does not match the advertisement + /// type (public/encrypted), or if the section would not manage + /// to fit within the enclosing advertisement. + pub fn encrypted_section_builder( + &self, + broadcast_cred: V1BroadcastCredential, + identity_type: EncryptedIdentityType, + verification_mode: V1VerificationMode, + ) -> CreateV1SectionBuilderResult { + self.section_builder_internals(move |internals| { + internals.encrypted_section_builder(broadcast_cred, identity_type, verification_mode) + }) + } + + fn section_builder_internals( + &self, + builder_supplier: impl FnOnce( + &mut V1AdvertisementBuilderInternals, + ) -> Result<usize, SectionBuilderError>, + ) -> CreateV1SectionBuilderResult { + match self.handle.get_mut() { + Ok(mut adv_builder_write_guard) => { + match builder_supplier(&mut adv_builder_write_guard) { + Ok(section_index) => CreateV1SectionBuilderResult::Success(V1SectionBuilder { + adv_builder: *self, + section_index: section_index as u8, + }), + Err(e) => e.into(), + } + } + Err(_) => CreateV1SectionBuilderResult::InvalidAdvBuilderHandle, + } + } +} + +/// Discriminant for `CreateV1AdvertisementBuilderResult` + +#[derive(Copy, Clone)] +#[repr(u8)] +pub enum CreateV1AdvertisementBuilderResultKind { + /// The attempt to create a new advertisement builder + /// failed since there are no more available + /// slots for V1 advertisement builders in their handle-map. + NoSpaceLeft = 0, + /// The attempt succeeded. The wrapped advertisement builder + /// may be obtained via + /// `CreateV1AdvertisementBuilderResult#into_success`. + Success = 1, +} + +/// The result of attempting to create a new V1 advertisement builder. +#[repr(C)] +#[allow(missing_docs)] +pub enum CreateV1AdvertisementBuilderResult { + NoSpaceLeft, + Success(V1AdvertisementBuilder), +} + +impl From<Result<V1AdvertisementBuilder, HandleMapFullError>> + for CreateV1AdvertisementBuilderResult +{ + fn from(result: Result<V1AdvertisementBuilder, HandleMapFullError>) -> Self { + match result { + Ok(builder) => CreateV1AdvertisementBuilderResult::Success(builder), + Err(_) => CreateV1AdvertisementBuilderResult::NoSpaceLeft, + } + } +} + +impl FfiEnum for CreateV1AdvertisementBuilderResult { + type Kind = CreateV1AdvertisementBuilderResultKind; + fn kind(&self) -> Self::Kind { + match self { + CreateV1AdvertisementBuilderResult::NoSpaceLeft => { + CreateV1AdvertisementBuilderResultKind::NoSpaceLeft + } + CreateV1AdvertisementBuilderResult::Success(_) => { + CreateV1AdvertisementBuilderResultKind::Success + } + } + } +} + +impl CreateV1AdvertisementBuilderResult { + declare_enum_cast! {into_success, Success, V1AdvertisementBuilder } +} + +/// Creates a new V1 advertisement builder for the given advertisement +/// kind (public/encrypted). +pub fn create_v1_advertisement_builder( + kind: AdvertisementBuilderKind, +) -> CreateV1AdvertisementBuilderResult { + V1AdvertisementBuilderHandle::allocate(move || V1AdvertisementBuilderInternals::new(kind)) + .map(|handle| V1AdvertisementBuilder { kind, handle }) + .into() +} + +impl V1AdvertisementBuilder { + /// Gets the kind of advertisement builder (public/encrypted) + pub fn kind(&self) -> AdvertisementBuilderKind { + self.kind + } +} + +pub(crate) enum V1AdvertisementBuilderState { + /// Internal state for when we have an active advertisement + /// builder, but no currently-active section builder. + Advertisement(np_adv_dynamic::extended::BoxedAdvBuilder), + /// Internal state for when we have both an active advertisement + /// builder and an active section builder. + Section( + np_adv_dynamic::extended::BoxedSectionBuilder< + np_adv::extended::serialize::AdvBuilder, + CryptoProviderImpl, + >, + ), +} + +/// Internal version of errors which may be raised when +/// attempting to derive a new section builder from an +/// advertisement builder. +pub(crate) enum SectionBuilderError { + /// We're currently in the middle of building a section. + UnclosedActiveSection, + /// We're attempting to build a section with an identity + /// kind (public/encrypted) which doesn't match the kind + /// for the entire advertisement. + IdentityKindMismatch, + /// There isn't enough space for a new section, either + /// because the maximum section count has been exceeded + /// or because the advertisement is almost full, and + /// the minimum size of a section wouldn't fit. + NoSpaceLeft, +} + +impl From<np_adv_dynamic::extended::BoxedAddSectionError> for SectionBuilderError { + fn from(err: np_adv_dynamic::extended::BoxedAddSectionError) -> Self { + use np_adv::extended::serialize::AddSectionError; + use np_adv_dynamic::extended::BoxedAddSectionError; + match err { + BoxedAddSectionError::IdentityRequiresSaltError + | BoxedAddSectionError::Underlying(AddSectionError::IncompatibleSectionType) => { + SectionBuilderError::IdentityKindMismatch + } + BoxedAddSectionError::Underlying(AddSectionError::InsufficientAdvSpace) + | BoxedAddSectionError::Underlying(AddSectionError::MaxSectionCountExceeded) => { + SectionBuilderError::NoSpaceLeft + } + } + } +} + +/// Internal, Rust-side implementation of a V1 advertisement builder. +pub struct V1AdvertisementBuilderInternals { + // Note: This is actually always populated from an external + // perspective in the absence of panics. We only need + // the `Option` in order to be able to take ownership + // and perform a state transition when needed. + state: Option<V1AdvertisementBuilderState>, +} + +impl V1AdvertisementBuilderInternals { + pub(crate) fn new(kind: AdvertisementBuilderKind) -> Self { + let adv_type = kind.as_internal_v1(); + let builder = np_adv::extended::serialize::AdvBuilder::new(adv_type); + let builder = builder.into(); + let state = Some(V1AdvertisementBuilderState::Advertisement(builder)); + Self { state } + } + /// Internals of section_builder-type routines. Upon success, yields the index + /// of the newly-added section builder. + pub(crate) fn section_builder_internal( + &mut self, + identity: np_adv_dynamic::extended::BoxedIdentity<CryptoProviderImpl>, + ) -> Result<usize, SectionBuilderError> { + let state = self.state.take(); + match state { + Some(V1AdvertisementBuilderState::Advertisement(adv_builder)) => { + match adv_builder.into_section_builder::<CryptoProviderImpl>(identity) { + Ok(section_builder) => { + let section_index = section_builder.section_index(); + self.state = Some(V1AdvertisementBuilderState::Section(section_builder)); + Ok(section_index) + } + Err((adv_builder, err)) => { + self.state = Some(V1AdvertisementBuilderState::Advertisement(adv_builder)); + Err(err.into()) + } + } + } + x => { + // Note: Technically, this case also would leave the `None` state + // if we ever entered into it, but we never transition to that + // state during normal operation. + self.state = x; + Err(SectionBuilderError::UnclosedActiveSection) + } + } + } + + pub(crate) fn public_section_builder(&mut self) -> Result<usize, SectionBuilderError> { + let identity = np_adv_dynamic::extended::BoxedIdentity::PublicIdentity; + self.section_builder_internal(identity) + } + pub(crate) fn encrypted_section_builder( + &mut self, + broadcast_cred: V1BroadcastCredential, + identity_type: EncryptedIdentityType, + verification_mode: V1VerificationMode, + ) -> Result<usize, SectionBuilderError> { + let mut rng = get_global_crypto_rng(); + let rng = rng.get_rng(); + let identity_type = identity_type.into(); + let internal_broadcast_cred = broadcast_cred.into_internal(); + let identity = match verification_mode { + V1VerificationMode::Mic => { + let encoder = np_adv::extended::serialize::MicEncryptedSectionEncoder::< + CryptoProviderImpl, + >::new_random_salt( + rng, identity_type, &internal_broadcast_cred + ); + np_adv_dynamic::extended::BoxedIdentity::MicEncrypted(encoder) + } + V1VerificationMode::Signature => { + let encoder = np_adv::extended::serialize::SignedEncryptedSectionEncoder::< + CryptoProviderImpl, + >::new_random_salt( + rng, identity_type, &internal_broadcast_cred + ); + np_adv_dynamic::extended::BoxedIdentity::SignedEncrypted(encoder) + } + }; + self.section_builder_internal(identity) + } +} + +fn get_v1_advertisement_builder_handle_map_dimensions() -> HandleMapDimensions { + HandleMapDimensions { + num_shards: global_num_shards(), + max_active_handles: global_max_num_v1_advertisement_builders(), + } +} + +declare_handle_map! { + mod advertisement_builder { + #[dimensions = super::get_v1_advertisement_builder_handle_map_dimensions()] + type V1AdvertisementBuilderHandle: HandleLike<Object = super::V1AdvertisementBuilderInternals>; + } +} +use crate::serialize::v1::advertisement_builder::V1AdvertisementBuilderHandle; + +/// Discriminant for `CreateV1SectionBuilderResult` +#[derive(Copy, Clone)] +#[repr(u8)] +pub enum CreateV1SectionBuilderResultKind { + /// The attempt to create a new section builder succeeded. + Success = 0, + /// We're currently in the middle of building a section. + UnclosedActiveSection = 1, + /// The advertisement builder handle was invalid. + InvalidAdvBuilderHandle = 2, + /// We're attempting to build a section with an identity + /// kind (public/encrypted) which doesn't match the kind + /// for the entire advertisement. + IdentityKindMismatch = 3, + /// There isn't enough space for a new section, either + /// because the maximum section count has been exceeded + /// or because the advertisement is almost full, and + /// the minimum size of a section wouldn't fit. + NoSpaceLeft = 4, +} + +/// The result of attempting to create a new V1 section builder. +#[repr(C)] +#[allow(missing_docs)] +pub enum CreateV1SectionBuilderResult { + Success(V1SectionBuilder), + UnclosedActiveSection, + InvalidAdvBuilderHandle, + IdentityKindMismatch, + NoSpaceLeft, +} + +impl FfiEnum for CreateV1SectionBuilderResult { + type Kind = CreateV1SectionBuilderResultKind; + fn kind(&self) -> Self::Kind { + match self { + Self::Success(_) => CreateV1SectionBuilderResultKind::Success, + Self::UnclosedActiveSection => CreateV1SectionBuilderResultKind::UnclosedActiveSection, + Self::InvalidAdvBuilderHandle => { + CreateV1SectionBuilderResultKind::InvalidAdvBuilderHandle + } + Self::IdentityKindMismatch => CreateV1SectionBuilderResultKind::IdentityKindMismatch, + Self::NoSpaceLeft => CreateV1SectionBuilderResultKind::NoSpaceLeft, + } + } +} + +impl CreateV1SectionBuilderResult { + declare_enum_cast! {into_success, Success, V1SectionBuilder} +} + +impl From<SectionBuilderError> for CreateV1SectionBuilderResult { + fn from(err: SectionBuilderError) -> Self { + match err { + SectionBuilderError::UnclosedActiveSection => Self::UnclosedActiveSection, + SectionBuilderError::IdentityKindMismatch => Self::IdentityKindMismatch, + SectionBuilderError::NoSpaceLeft => Self::NoSpaceLeft, + } + } +} + +/// Result code for [`V1SectionBuilder#add_to_advertisement`]. +#[derive(Clone, Copy)] +#[repr(u8)] +pub enum AddV1SectionToAdvertisementResult { + /// The section referenced by the given handle + /// couldn't be added to the containing advertisement, + /// possibly because the handle is invalid or the section + /// has already been added to the containing section. + Error = 0, + /// The section referenced by the given handle + /// was successfully added to the containing advertisement. + /// After obtaining this result code, the section + /// handle will no longer be valid. + Success = 1, +} + +/// Result code for operations adding DEs to a section builder. +#[derive(Clone, Copy)] +#[repr(u8)] +pub enum AddV1DEResult { + /// The DE was successfully added to the section builder + /// behind the given handle. + Success = 0, + /// The handle for the section builder was invalid. + InvalidSectionHandle = 1, + /// There was no more space left in the advertisement + /// to fit the DE in the containing section. + InsufficientSectionSpace = 2, + /// The data element itself had invalid characteristics, + /// most likely a length above 127. + InvalidDataElement = 3, +} + +/// Discriminant for `NextV1DE16ByteSaltResult`. +#[derive(Clone, Copy)] +#[repr(u8)] +pub enum NextV1DE16ByteSaltResultKind { + /// We couldn't return a 16-byte DE salt, possibly + /// because the handle to the section builder + /// was invalid, or possibly because the section + /// builder was for a public section. + Error = 0, + /// A 16-byte DE salt was returned successfully. + Success = 1, +} + +/// The result of attempting to get the derived V1 DE +/// 16-byte salt for the next-added DE to the section +/// builder behind the given handle. +#[derive(Clone, Copy)] +#[repr(C)] +#[allow(missing_docs)] +pub enum NextV1DE16ByteSaltResult { + Error, + Success([u8; 16]), +} + +impl FfiEnum for NextV1DE16ByteSaltResult { + type Kind = NextV1DE16ByteSaltResultKind; + fn kind(&self) -> Self::Kind { + match self { + Self::Error => NextV1DE16ByteSaltResultKind::Error, + Self::Success(_) => NextV1DE16ByteSaltResultKind::Success, + } + } +} + +impl NextV1DE16ByteSaltResult { + declare_enum_cast! {into_success, Success, [u8; 16] } +} + +impl From<Option<np_adv::extended::serialize::DeSalt<CryptoProviderImpl>>> + for NextV1DE16ByteSaltResult +{ + fn from(maybe_salt: Option<np_adv::extended::serialize::DeSalt<CryptoProviderImpl>>) -> Self { + match maybe_salt.and_then(|salt| salt.derive::<16>()) { + Some(salt) => NextV1DE16ByteSaltResult::Success(salt), + None => NextV1DE16ByteSaltResult::Error, + } + } +} + +/// A handle to a builder for V1 sections. +#[derive(Clone, Copy)] +#[repr(C)] +pub struct V1SectionBuilder { + adv_builder: V1AdvertisementBuilder, + section_index: u8, +} + +impl V1SectionBuilder { + /// Attempts to add the section constructed behind this handle + /// to a section builder to the containing advertisement it + /// originated from. + pub fn add_to_advertisement(self) -> AddV1SectionToAdvertisementResult { + match self.adv_builder.handle.get_mut() { + Ok(mut adv_builder) => { + let state = adv_builder.state.take(); + match state { + Some(V1AdvertisementBuilderState::Section(section_builder)) => { + // Make sure the index of the section we're trying to close + // matches the index of the section currently under construction. + let actual_section_index = section_builder.section_index() as u8; + if self.section_index == actual_section_index { + let updated_adv_builder = section_builder.add_to_advertisement(); + adv_builder.state = Some(V1AdvertisementBuilderState::Advertisement( + updated_adv_builder, + )); + AddV1SectionToAdvertisementResult::Success + } else { + adv_builder.state = + Some(V1AdvertisementBuilderState::Section(section_builder)); + AddV1SectionToAdvertisementResult::Error + } + } + x => { + adv_builder.state = x; + AddV1SectionToAdvertisementResult::Error + } + } + } + Err(_) => AddV1SectionToAdvertisementResult::Error, + } + } + + /// Attempts to get the derived 16-byte V1 DE salt for the next + /// DE to be added to this section builder. May fail if this + /// section builder handle is invalid, or if the section + /// is a public section. + pub fn next_de_salt(&self) -> NextV1DE16ByteSaltResult { + self.try_apply_to_internals( + |section_builder| section_builder.next_de_salt().into(), + NextV1DE16ByteSaltResult::Error, + ) + } + + /// Attempts to add the given DE to the section builder behind + /// this handle. The passed DE may have a payload of up to 127 + /// bytes, the maximum for a V1 DE. + pub fn add_127_byte_buffer_de(&self, de: V1DE127ByteBuffer) -> AddV1DEResult { + match de.into_internal() { + Some(generic_de) => self + .add_de_internals(np_adv_dynamic::extended::BoxedWriteDataElement::new(generic_de)), + None => AddV1DEResult::InvalidDataElement, + } + } + + fn add_de_internals( + &self, + de: np_adv_dynamic::extended::BoxedWriteDataElement, + ) -> AddV1DEResult { + self.try_apply_to_internals( + move |section_builder| match section_builder.add_de(move |_| de) { + Ok(_) => AddV1DEResult::Success, + Err(_) => AddV1DEResult::InsufficientSectionSpace, + }, + AddV1DEResult::InvalidSectionHandle, + ) + } + + fn try_apply_to_internals<R>( + &self, + func: impl FnOnce( + &mut np_adv_dynamic::extended::BoxedSectionBuilder< + np_adv::extended::serialize::AdvBuilder, + CryptoProviderImpl, + >, + ) -> R, + invalid_handle_error: R, + ) -> R { + match self.adv_builder.handle.get_mut() { + Ok(mut adv_builder) => { + match adv_builder.state.as_mut() { + Some(V1AdvertisementBuilderState::Section(ref mut section_builder)) => { + // Check to make sure that the section index matches, otherwise + // we have an invalid handle. + let current_section_index = section_builder.section_index() as u8; + if current_section_index == self.section_index { + func(section_builder) + } else { + invalid_handle_error + } + } + Some(V1AdvertisementBuilderState::Advertisement(_)) => invalid_handle_error, + None => invalid_handle_error, + } + } + Err(_) => invalid_handle_error, + } + } +} + +/// Represents the contents of a V1 DE whose payload +/// is stored in a buffer which may contain up to 127 bytes, +/// which is the maximum for any V1 DE. +/// +/// This representation is stable, and so you may directly +/// reference this struct's fields if you wish. +#[repr(C)] +//TODO: Partial unification with `deserialize::v1::GenericV1DataElement`? +pub struct V1DE127ByteBuffer { + /// The DE type code of this generic data-element. + pub de_type: u32, + /// The raw data-element byte payload, up to + /// 127 bytes in length. + pub payload: ByteBuffer<127>, +} + +impl V1DE127ByteBuffer { + /// Attempts to convert this FFI-friendly DE with a byte-buffer size of 127 + /// to the internal representation of a generic DE. May fail in the case + /// where the underlying payload byte-buffer has an invalid length above 127. + fn into_internal(self) -> Option<np_adv::extended::data_elements::GenericDataElement> { + let de_type = np_adv::extended::de_type::DeType::from(self.de_type); + self.payload.as_slice().and_then(move |payload_slice| { + np_adv::extended::data_elements::GenericDataElement::try_from(de_type, payload_slice) + .ok() + }) + } +} diff --git a/nearby/presence/np_ffi_core/src/utils.rs b/nearby/presence/np_ffi_core/src/utils.rs index e547a89..b1495b9 100644 --- a/nearby/presence/np_ffi_core/src/utils.rs +++ b/nearby/presence/np_ffi_core/src/utils.rs @@ -37,6 +37,7 @@ pub trait FfiEnum { /// /// If the enclosing enum turns out to not be the requested /// variant, the generated method will return `None`. +#[macro_export] macro_rules! declare_enum_cast { ($projection_method_name:ident, $variant_enum_name:ident, $variant_type_name:ty) => { #[doc = concat!("Attempts to cast `self` to the `", stringify!($variant_enum_name), diff --git a/nearby/presence/np_ffi_core/src/v1.rs b/nearby/presence/np_ffi_core/src/v1.rs new file mode 100644 index 0000000..c7b564d --- /dev/null +++ b/nearby/presence/np_ffi_core/src/v1.rs @@ -0,0 +1,38 @@ +// 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. + +//! Common externally-acessible V1 constructs for both of the +//! serialization+deserialization flows. + +/// Information about the verification scheme used +/// for verifying the integrity of the contents +/// of a decrypted section. +#[derive(Clone, Copy)] +#[repr(u8)] +pub enum V1VerificationMode { + /// Message integrity code verification. + Mic = 0, + /// Signature verification. + Signature = 1, +} + +impl From<np_adv::extended::deserialize::VerificationMode> for V1VerificationMode { + fn from(verification_mode: np_adv::extended::deserialize::VerificationMode) -> Self { + use np_adv::extended::deserialize::VerificationMode; + match verification_mode { + VerificationMode::Mic => Self::Mic, + VerificationMode::Signature => Self::Signature, + } + } +} diff --git a/nearby/presence/xts_aes/fuzz/Cargo.lock b/nearby/presence/xts_aes/fuzz/Cargo.lock index 1844bd3..a08ab7c 100644 --- a/nearby/presence/xts_aes/fuzz/Cargo.lock +++ b/nearby/presence/xts_aes/fuzz/Cargo.lock @@ -279,14 +279,15 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "sha2", + "subtle", ] [[package]] @@ -559,9 +560,9 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", diff --git a/nearby/rustfmt.toml b/nearby/rustfmt.toml index 10c1698..d45a5bf 100644 --- a/nearby/rustfmt.toml +++ b/nearby/rustfmt.toml @@ -1,3 +1,3 @@ edition = "2021" newline_style = "Unix" -use_small_heuristics = "Max" +use_small_heuristics = "Max"
\ No newline at end of file diff --git a/nearby/src/jni.rs b/nearby/src/jni.rs index 22a1da2..efd6e6c 100644 --- a/nearby/src/jni.rs +++ b/nearby/src/jni.rs @@ -28,3 +28,9 @@ pub fn run_kotlin_tests(root: &path::Path) -> anyhow::Result<()> { run_cmd_shell(&kotlin_lib_path, "./gradlew :test")?; Ok(()) } + +pub fn run_ukey2_jni_tests(root: &path::Path) -> anyhow::Result<()> { + let ukey2_jni_path = root.to_path_buf().join("connections/ukey2/ukey2_jni/java"); + run_cmd_shell(&ukey2_jni_path, "./gradlew :test")?; + Ok(()) +} diff --git a/nearby/src/license.rs b/nearby/src/license.rs index e479526..387ca27 100644 --- a/nearby/src/license.rs +++ b/nearby/src/license.rs @@ -108,5 +108,6 @@ fn license_ignore_dirs() -> Vec<&'static str> { "**/.editorconfig", "**/*.class", "**/fuzz/artifacts/**", + "**/cmake-build-debug/**", ] } diff --git a/nearby/src/main.rs b/nearby/src/main.rs index 3d698e2..1d1ac16 100644 --- a/nearby/src/main.rs +++ b/nearby/src/main.rs @@ -54,6 +54,7 @@ fn main() -> anyhow::Result<()> { Subcommand::AddLicenseHeaders => license::add_license_headers(&root_dir)?, Subcommand::CheckLdtFfi => ffi::check_ldt_ffi_rust(&root_dir)?, Subcommand::CheckUkey2Ffi(ref options) => ukey2::check_ukey2_ffi(&root_dir, options)?, + Subcommand::RunUkey2JniTests => jni::run_ukey2_jni_tests(&root_dir)?, Subcommand::CheckLdtJni => jni::check_ldt_jni(&root_dir)?, Subcommand::CheckNpFfi(ref options) => ffi::check_np_ffi_rust(&root_dir, options)?, Subcommand::CheckLdtCmake(ref options) => ffi::check_ldt_cmake(&root_dir, options)?, @@ -106,6 +107,7 @@ pub fn check_everything(root: &path::Path, check_options: &CheckOptions) -> anyh ffi::check_everything(root, &check_options.cargo_options)?; jni::check_ldt_jni(root)?; jni::run_kotlin_tests(root)?; + jni::run_ukey2_jni_tests(root)?; ukey2::check_ukey2_ffi(root, &check_options.cargo_options)?; fuzzers::run_rust_fuzzers(root)?; fuzzers::build_ffi_fuzzers(root)?; @@ -177,6 +179,8 @@ enum Subcommand { CheckLdtJni, /// Runs the kotlin tests of the LDT Jni API RunKotlinTests, + /// Checks the build of the ukey2_jni wrapper and runs tests + RunUkey2JniTests, } #[derive(clap::Args, Debug, Clone, Default)] |