diff --git a/Cargo.lock b/Cargo.lock index bfae1821..a5e8477b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -19,9 +19,9 @@ checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e" [[package]] name = "android_logger" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e9dd62f37dea550caf48c77591dc50bd1a378ce08855be1a0c42a97b7550fb" +checksum = "8619b80c242aa7bd638b5c7ddd952addeecb71f69c75e33f1d47b2804f8f883a" dependencies = [ "android_log-sys", "env_logger", @@ -37,9 +37,15 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" [[package]] name = "bitflags" @@ -49,21 +55,21 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "bytes" -version = "1.2.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cesu8" @@ -105,18 +111,18 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "encoding_rs" -version = "0.8.31" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if", ] [[package]] name = "env_logger" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ "log", "regex", @@ -139,36 +145,36 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.24" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.24" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-sink" -version = "0.3.24" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.24" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.24" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", "futures-task", @@ -178,9 +184,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.14" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" +checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" dependencies = [ "bytes", "fnv", @@ -203,18 +209,18 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -246,9 +252,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.20" +version = "0.14.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" dependencies = [ "bytes", "futures-channel", @@ -270,9 +276,8 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +version = "0.23.2" +source = "git+https://github.com/cpu/hyper-rustls?branch=cpu-rustls-0.21.0-prep#76cda54c32e1a8aacd5456dd1797f6c0386262b1" dependencies = [ "http", "hyper", @@ -293,9 +298,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", @@ -303,15 +308,15 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.5.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "jni" @@ -335,24 +340,18 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] -[[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.133" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "log" @@ -371,20 +370,20 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mio" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -419,9 +418,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ "hermit-abi", "libc", @@ -429,9 +428,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.15.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl-probe" @@ -459,27 +458,27 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.6.0" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ "aho-corasick", "memchr", @@ -488,17 +487,16 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "reqwest" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" +version = "0.11.16" +source = "git+https://github.com/cpu/reqwest?branch=cpu-rustls-0.21.0-prep#c0e00ee714b88de0951f6a3e60733f0d1cee278a" dependencies = [ - "base64", + "base64 0.21.0", "bytes", "encoding_rs", "futures-core", @@ -547,14 +545,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.6" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +checksum = "07180898a28ed6a7f7ba2311594308f595e3dd2e3c3812fa0a80a47b45f17e5d" dependencies = [ "log", "ring", + "rustls-webpki", "sct", - "webpki", ] [[package]] @@ -571,11 +569,11 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64", + "base64 0.21.0", ] [[package]] @@ -583,7 +581,7 @@ name = "rustls-platform-verifier" version = "0.1.0" dependencies = [ "android_logger", - "base64", + "base64 0.13.1", "core-foundation", "core-foundation-sys", "jni", @@ -592,19 +590,29 @@ dependencies = [ "reqwest", "rustls", "rustls-native-certs", + "rustls-webpki", "security-framework", "security-framework-sys", "tokio", - "webpki", "webpki-roots", "winapi", ] +[[package]] +name = "rustls-webpki" +version = "0.100.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "same-file" @@ -617,12 +625,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -637,9 +644,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.7.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", "core-foundation", @@ -651,9 +658,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", @@ -661,15 +668,15 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.145" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" dependencies = [ "itoa", "ryu", @@ -690,18 +697,18 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -715,9 +722,20 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "syn" -version = "1.0.100" +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.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" +checksum = "21e3787bb71465627110e7d87ed4faaa36c1f61042ee67badb9e2ef173accc40" dependencies = [ "proc-macro2", "quote", @@ -726,22 +744,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.35" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c53f98874615aea268107765aa1ed8f6116782501d18e53d08b471733bea6c85" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.35" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8b463991b4eab2d801e724172285ec4195c650e8ec79b149e6c2a8e6dd3f783" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.11", ] [[package]] @@ -755,56 +773,52 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.21.1" +version = "1.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" +checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" dependencies = [ "autocfg", "bytes", "libc", - "memchr", "mio", "num_cpus", - "once_cell", "pin-project-lite", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.45.0", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.11", ] [[package]] name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +version = "0.24.0" +source = "git+https://github.com/tokio-rs/tls#7ea7a17831691e8b0a9cfae3132d2d2f0f64221c" dependencies = [ "rustls", "tokio", - "webpki", ] [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" dependencies = [ "bytes", "futures-core", @@ -822,9 +836,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.36" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", @@ -833,30 +847,30 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", ] [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -886,12 +900,11 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -913,9 +926,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -923,24 +936,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" dependencies = [ "cfg-if", "js-sys", @@ -950,9 +963,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -960,28 +973,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" dependencies = [ "js-sys", "wasm-bindgen", @@ -999,9 +1012,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.4" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ "webpki", ] @@ -1039,46 +1052,84 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.36.1" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +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", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +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", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "winreg" diff --git a/Cargo.toml b/Cargo.toml index 56b4abb1..925b9873 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ cert-logging = ["base64"] docsrs = ["jni", "once_cell"] [dependencies] -rustls = { version = "0.20", features = ["dangerous_configuration", "tls12", "logging"] } +rustls = { version = "0.21.0", features = ["dangerous_configuration", "tls12", "logging"] } log = { version = "0.4" } base64 = { version = "0.13", optional = true } # Only used when the `cert-logging` feature is enabled. jni = { version = "0.19", default-features = false, optional = true } # Only used during doc generation @@ -47,10 +47,11 @@ once_cell = { version = "1.9", optional = true } # Only used during doc generati rustls-native-certs = "0.6" once_cell = "1.9" webpki-roots = "0.22" # Fallback when `openssl-probe` can't find anything. +webpki = { package = "rustls-webpki", version = "0.100.0", features = ["alloc", "std"] } [target.'cfg(target_os = "android")'.dependencies] jni = { version = "0.19", default-features = false } -webpki = "0.22" +webpki = { package = "rustls-webpki", version = "0.100.0", features = ["alloc", "std"] } once_cell = "1.9" android_logger = { version = "0.11", optional = true } # Only used during testing. @@ -69,8 +70,14 @@ winapi = { version = "0.3", features = ["wincrypt", "winerror"] } [dev-dependencies] tokio = { version = "1.5", features = ["macros", "rt-multi-thread"] } -reqwest = { version = "0.11", default-features = false, features = ["rustls-tls-manual-roots"] } +reqwest = { version = "0.11.16", default-features = false, features = ["rustls-tls-manual-roots"] } [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] features = ["dbg", "docsrs"] + +[patch.crates-io] +tokio-rustls = { git = 'https://github.com/tokio-rs/tls', package='tokio-rustls' } +hyper-rustls = { git = 'https://github.com/cpu/hyper-rustls', branch = 'cpu-rustls-0.21.0-prep' } +reqwest = { git = 'https://github.com/cpu/reqwest', branch = 'cpu-rustls-0.21.0-prep' } + diff --git a/src/tests/mod.rs b/src/tests/mod.rs index b38d5cfd..f42f7f8f 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -1,11 +1,15 @@ #[cfg(feature = "ffi-testing")] pub mod ffi; +use std::error::Error as StdError; + mod verification_real_world; mod verification_mock; -struct TestCase<'a> { +use rustls::{CertificateError, Error as TlsError, Error::InvalidCertificate}; + +struct TestCase<'a, E: StdError> { /// The name of the server we're connecting to. pub reference_id: &'a str, @@ -15,5 +19,30 @@ struct TestCase<'a> { /// The stapled OCSP response given to us by Rustls, if any. pub stapled_ocsp: Option<&'a [u8]>, - pub expected_result: Result<(), rustls::Error>, + pub expected_result: Result<(), TlsError>, + + /// An error that should be present inside an expected `CertificateError::Other` variant. + /// + /// Set this if the error being tested uses `CertificateError::Other` and not statically known + /// variants in [TlsError] + #[allow(dead_code)] + pub other_error: Option, +} + +pub fn assert_cert_error_eq( + result: &Result<(), TlsError>, + expected: &Result<(), TlsError>, + expected_err: Option<&E>, +) { + // If the expected error is an "Other" CertificateError we can't directly assert equality, we rely + // on the test caller to provide the correct value to compare. + if let Err(InvalidCertificate(CertificateError::Other(err))) = &expected { + let expected_err = expected_err.expect("error not provided for `Other` case handling"); + let err: &E = err + .downcast_ref() + .expect("incorrect `Other` inner error kind"); + assert_eq!(err, expected_err); + } else { + assert_eq!(result, expected); + } } diff --git a/src/tests/verification_mock/mod.rs b/src/tests/verification_mock/mod.rs index db3680e1..ddfa5d60 100644 --- a/src/tests/verification_mock/mod.rs +++ b/src/tests/verification_mock/mod.rs @@ -21,10 +21,12 @@ ))] use super::TestCase; -use crate::verification::{error_messages, Verifier}; -use rustls::{client::ServerCertVerifier, Error as TlsError}; +use crate::tests::assert_cert_error_eq; +use crate::verification::{EkuError, Verifier}; +use rustls::{client::ServerCertVerifier, CertificateError, Error as TlsError}; use std::convert::TryFrom; use std::net::IpAddr; +use std::sync::Arc; macro_rules! mock_root_test_cases { { $( $name:ident [ $target:meta ] => $test_case:expr ),+ , } => { @@ -61,6 +63,12 @@ macro_rules! mock_root_test_cases { }; } +macro_rules! no_error { + () => { + None:: + }; +} + const ROOT1: &[u8] = include_bytes!("root1.crt"); const ROOT1_INT1: &[u8] = include_bytes!("root1-int1.crt"); const ROOT1_INT1_EXAMPLE_COM_GOOD: &[u8] = include_bytes!("root1-int1-ee_example.com-good.crt"); @@ -96,9 +104,9 @@ pub(super) fn verification_without_mock_root() { assert_eq!( result.map(|_| ()), - Err(TlsError::InvalidCertificateData(String::from( - error_messages::UNKNOWN_CERT - ))) + Err(TlsError::InvalidCertificate( + CertificateError::UnknownIssuer + )) ); } @@ -117,36 +125,42 @@ mock_root_test_cases! { chain: &[ROOT1_INT1_EXAMPLE_COM_GOOD, ROOT1_INT1], stapled_ocsp: None, expected_result: Ok(()), + other_error: no_error!(), }, valid_no_stapling_ipv4 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV4, chain: &[ROOT1_INT1_LOCALHOST_IPV4_GOOD, ROOT1_INT1], stapled_ocsp: None, expected_result: Ok(()), + other_error: no_error!(), }, valid_no_stapling_ipv6 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV6, chain: &[ROOT1_INT1_LOCALHOST_IPV6_GOOD, ROOT1_INT1], stapled_ocsp: None, expected_result: Ok(()), + other_error: no_error!(), }, valid_stapled_good_dns [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase { reference_id: EXAMPLE_COM, chain: &[ROOT1_INT1_EXAMPLE_COM_GOOD, ROOT1_INT1], stapled_ocsp: Some(include_bytes!("root1-int1-ee_example.com-good.ocsp")), expected_result: Ok(()), + other_error: no_error!(), }, valid_stapled_good_ipv4 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV4, chain: &[ROOT1_INT1_LOCALHOST_IPV4_GOOD, ROOT1_INT1], stapled_ocsp: Some(include_bytes!("root1-int1-ee_127.0.0.1-good.ocsp")), expected_result: Ok(()), + other_error: no_error!(), }, valid_stapled_good_ipv6 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV6, chain: &[ROOT1_INT1_LOCALHOST_IPV6_GOOD, ROOT1_INT1], stapled_ocsp: Some(include_bytes!("root1-int1-ee_1-good.ocsp")), expected_result: Ok(()), + other_error: no_error!(), }, // Uses a separate certificate from the one used in the "good" case to deal // with operating systems with validation data caches (e.g. Windows). @@ -154,19 +168,22 @@ mock_root_test_cases! { reference_id: EXAMPLE_COM, chain: &[include_bytes!("root1-int1-ee_example.com-revoked.crt"), ROOT1_INT1], stapled_ocsp: Some(include_bytes!("root1-int1-ee_example.com-revoked.ocsp")), - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::REVOKED))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::Revoked)), + other_error: no_error!(), }, stapled_revoked_ipv4 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV4, chain: &[include_bytes!("root1-int1-ee_127.0.0.1-revoked.crt"), ROOT1_INT1], stapled_ocsp: Some(include_bytes!("root1-int1-ee_127.0.0.1-revoked.ocsp")), - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::REVOKED))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::Revoked)), + other_error: no_error!(), }, stapled_revoked_ipv6 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV6, chain: &[include_bytes!("root1-int1-ee_1-revoked.crt"), ROOT1_INT1], stapled_ocsp: Some(include_bytes!("root1-int1-ee_1-revoked.ocsp")), - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::REVOKED))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::Revoked)), + other_error: no_error!(), }, // Validation fails with no intermediate (that can't be fetched // with AIA because there's no AIA issuer field in the certificate). @@ -177,60 +194,72 @@ mock_root_test_cases! { reference_id: EXAMPLE_COM, chain: &[ROOT1_INT1_EXAMPLE_COM_GOOD], stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::UNKNOWN_CERT))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::UnknownIssuer)), + other_error: no_error!(), }, ee_only_ipv4 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV4, chain: &[ROOT1_INT1_LOCALHOST_IPV4_GOOD], stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::UNKNOWN_CERT))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::UnknownIssuer)), + other_error: no_error!(), }, ee_only_ipv6 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV6, chain: &[ROOT1_INT1_LOCALHOST_IPV6_GOOD], stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::UNKNOWN_CERT))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::UnknownIssuer)), + other_error: no_error!(), }, // Validation fails when the certificate isn't valid for the reference ID. domain_mismatch_dns [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase { reference_id: "example.org", chain: &[ROOT1_INT1_EXAMPLE_COM_GOOD, ROOT1_INT1], stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::WRONG_NAME))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::NotValidForName)), + other_error: no_error!(), }, domain_mismatch_ipv4 [ any(windows, target_os = "macos") ] => TestCase { reference_id: "198.168.0.1", chain: &[ROOT1_INT1_LOCALHOST_IPV4_GOOD, ROOT1_INT1], stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::WRONG_NAME))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::NotValidForName)), + other_error: no_error!(), }, domain_mismatch_ipv6 [ any(windows, target_os = "macos") ] => TestCase { reference_id: "::ffff:c6a8:1", chain: &[ROOT1_INT1_LOCALHOST_IPV6_GOOD, ROOT1_INT1], stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::WRONG_NAME))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::NotValidForName)), + other_error: no_error!(), }, wrong_eku_dns [ any(windows, target_os = "android", target_os = "macos", target_os = "linux") ] => TestCase { reference_id: EXAMPLE_COM, chain: &[include_bytes!("root1-int1-ee_example.com-wrong_eku.crt"), ROOT1_INT1], stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::INVALID_EXTENSIONS))), + expected_result: Err(TlsError::InvalidCertificate( + CertificateError::Other(Arc::from(EkuError)))), + other_error: Some(EkuError), }, wrong_eku_ipv4 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV4, chain: &[include_bytes!("root1-int1-ee_127.0.0.1-wrong_eku.crt"), ROOT1_INT1], stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::INVALID_EXTENSIONS))), + expected_result: Err(TlsError::InvalidCertificate( + CertificateError::Other(Arc::from(EkuError)))), + other_error: Some(EkuError), }, wrong_eku_ipv6 [ any(windows, target_os = "macos") ] => TestCase { reference_id: LOCALHOST_IPV6, chain: &[include_bytes!("root1-int1-ee_1-wrong_eku.crt"), ROOT1_INT1], stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::INVALID_EXTENSIONS))), + expected_result: Err(TlsError::InvalidCertificate( + CertificateError::Other(Arc::from(EkuError)))), + other_error: Some(EkuError), }, } -fn test_with_mock_root(test_case: &TestCase) { +fn test_with_mock_root(test_case: &TestCase) { log::info!("verifying {:?}", test_case.expected_result); let verifier = Verifier::new_with_fake_root(ROOT1); // TODO: time @@ -264,6 +293,11 @@ fn test_with_mock_root(test_case: &TestCase) { test_case.stapled_ocsp.unwrap_or(&[]), std::time::SystemTime::now(), ); - assert_eq!(result.map(|_| ()), test_case.expected_result); + + assert_cert_error_eq( + &result.map(|_| ()), + &test_case.expected_result, + test_case.other_error.as_ref(), + ); // TODO: get into specifics of errors returned when it fails. } diff --git a/src/tests/verification_real_world/mod.rs b/src/tests/verification_real_world/mod.rs index 427e0f60..d8ae8b40 100644 --- a/src/tests/verification_real_world/mod.rs +++ b/src/tests/verification_real_world/mod.rs @@ -42,8 +42,8 @@ //! Thus we don't expect these tests to be flaky w.r.t. that, except for //! potentially poor performance. use super::TestCase; -use crate::verification::error_messages; -use rustls::Error as TlsError; +use crate::tests::assert_cert_error_eq; +use rustls::{CertificateError, Error as TlsError}; use std::convert::TryFrom; const SHARED_CHAIN: &[&[u8]] = &[ @@ -113,7 +113,13 @@ macro_rules! real_world_test_cases { } } -fn real_world_test(test_case: &TestCase) { +macro_rules! no_error { + () => { + None:: + }; +} + +fn real_world_test(test_case: &TestCase) { log::info!("verifying {:?}", test_case.expected_result); let verifier = crate::verifier_for_testing(); @@ -141,18 +147,11 @@ fn real_world_test(test_case: &TestCase) { ) .map(|_| ()); - // Note: Linux is special-cased becuse it uses the defaukt `webpki` verifier, meaning - // that we have no control over the error strings used. - if test_case.expected_result.is_err() && cfg!(target_os = "linux") { - assert_eq!( - result, - Err(TlsError::InvalidCertificateData(String::from( - "invalid peer certificate: CertNotValidForName" - ))) - ) - } else { - assert_eq!(result.map(|_| ()), test_case.expected_result); - } + assert_cert_error_eq( + &result.map(|_| ()), + &test_case.expected_result, + None::<&std::convert::Infallible>, + ); // TODO: get into specifics of errors returned when it fails. } @@ -165,6 +164,7 @@ real_world_test_cases! { chain: VALID_1PASSWORD_COM_CHAIN, stapled_ocsp: None, expected_result: Ok(()), + other_error: no_error!(), }, // Same as above but without stapled OCSP. my_1password_com_valid_no_stapled => TestCase { @@ -172,6 +172,7 @@ real_world_test_cases! { chain: VALID_1PASSWORD_COM_CHAIN, stapled_ocsp: None, expected_result: Ok(()), + other_error: no_error!(), }, // Valid also for 1password.com (no subdomain). _1password_com_valid => TestCase { @@ -179,13 +180,15 @@ real_world_test_cases! { chain: VALID_1PASSWORD_COM_CHAIN, stapled_ocsp: None, expected_result: Ok(()), + other_error: no_error!(), }, // The certificate isn't valid for an unrelated subdomain. unrelated_domain_invalid => TestCase { reference_id: VALID_UNRELATED_DOMAIN, chain: VALID_1PASSWORD_COM_CHAIN, stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::WRONG_NAME))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::NotValidForName)), + other_error: no_error!(), }, // The certificate chain for the unrelated domain is valid for that // unrelated domain. @@ -194,6 +197,7 @@ real_world_test_cases! { chain: VALID_UNRELATED_CHAIN, stapled_ocsp: None, expected_result: Ok(()), + other_error: no_error!(), }, // The certificate chain for the unrelated domain is not valid for // my.1password.com. @@ -201,7 +205,8 @@ real_world_test_cases! { reference_id: MY_1PASSWORD_COM, chain: VALID_UNRELATED_CHAIN, stapled_ocsp: None, - expected_result: Err(TlsError::InvalidCertificateData(String::from(error_messages::WRONG_NAME))), + expected_result: Err(TlsError::InvalidCertificate(CertificateError::NotValidForName)), + other_error: no_error!(), }, // OCSP stapling works. diff --git a/src/verification/android.rs b/src/verification/android.rs index f5800d27..9bd0ff15 100644 --- a/src/verification/android.rs +++ b/src/verification/android.rs @@ -3,13 +3,13 @@ use jni::{ strings::JavaStr, JNIEnv, }; -use rustls::{client::ServerCertVerifier, Error as TlsError}; +use rustls::Error::InvalidCertificate; +use rustls::{client::ServerCertVerifier, CertificateError, Error as TlsError}; use std::time::SystemTime; -use super::{ - error_messages, invalid_certificate, log_server_cert, unsupported_server_name, ALLOWED_EKUS, -}; +use super::{log_server_cert, unsupported_server_name, ALLOWED_EKUS}; use crate::android::{with_context, CachedClass}; +use crate::verification::invalid_certificate; static CERT_VERIFIER_CLASS: CachedClass = CachedClass::new("com/onepassword/rustls_platform_verifier/CertificateVerifier"); @@ -191,30 +191,34 @@ impl Verifier { // If everything else was OK, check the hostname. let cert = webpki::EndEntityCert::try_from(end_entity.as_ref()) .map_err(pki_name_error)?; - // This unwrap can't fail since it was already validated before. - let name = webpki::DnsNameRef::try_from_ascii_str(server_name).unwrap(); - if cert.verify_is_valid_for_dns_name(name).is_ok() { + let name = webpki::SubjectNameRef::DnsName( + // This unwrap can't fail since it was already validated before. + webpki::DnsNameRef::try_from_ascii_str(server_name).unwrap(), + ); + if cert.verify_is_valid_for_subject_name(name).is_ok() { Ok(()) } else { - Err(invalid_certificate(error_messages::WRONG_NAME)) + Err(InvalidCertificate(CertificateError::NotValidForName)) } } VerifierStatus::Unavailable => Err(TlsError::General(String::from( "No system trust stores available", ))), - VerifierStatus::Expired => Err(invalid_certificate(error_messages::EXPIRED)), + VerifierStatus::Expired => Err(InvalidCertificate(CertificateError::Expired)), VerifierStatus::UnknownCert => { log::warn!("certificate was not trusted: {}", maybe_msg.unwrap()); - Err(invalid_certificate(error_messages::UNKNOWN_CERT)) + Err(InvalidCertificate(CertificateError::UnknownIssuer)) } VerifierStatus::Revoked => { log::warn!("certificate was revoked: {}", maybe_msg.unwrap()); - Err(invalid_certificate(error_messages::REVOKED)) + Err(InvalidCertificate(CertificateError::Revoked)) } - VerifierStatus::InvalidEncoding => Err(TlsError::InvalidCertificateEncoding), - VerifierStatus::InvalidExtension => { - Err(invalid_certificate(error_messages::INVALID_EXTENSIONS)) + VerifierStatus::InvalidEncoding => { + Err(InvalidCertificate(CertificateError::BadEncoding)) } + VerifierStatus::InvalidExtension => Err(InvalidCertificate( + CertificateError::Other(std::sync::Arc::new(super::EkuError)), + )), } } Err(e) => Err(TlsError::General(format!( @@ -256,8 +260,8 @@ fn extract_result_info(env: &JNIEnv<'_>, result: JObject<'_>) -> (VerifierStatus fn pki_name_error(error: webpki::Error) -> TlsError { use webpki::Error::*; match error { - BadDer | BadDerTime => TlsError::InvalidCertificateEncoding, - e => TlsError::InvalidCertificateData(format!("invalid peer certificate: {}", e)), + BadDer | BadDerTime => InvalidCertificate(CertificateError::BadEncoding), + e => invalid_certificate(format!("invalid peer certificate: {}", e)), } } diff --git a/src/verification/apple.rs b/src/verification/apple.rs index 4cfda33f..02edb68f 100644 --- a/src/verification/apple.rs +++ b/src/verification/apple.rs @@ -1,7 +1,8 @@ -use super::{error_messages, invalid_certificate, log_server_cert, unsupported_server_name}; +use super::{log_server_cert, unsupported_server_name}; +use crate::verification::invalid_certificate; use core_foundation::date::CFDate; use core_foundation_sys::date::kCFAbsoluteTimeIntervalSince1970; -use rustls::{client::ServerCertVerifier, Error as TlsError}; +use rustls::{client::ServerCertVerifier, CertificateError, Error as TlsError}; use security_framework::{ certificate::SecCertificate, policy::SecPolicy, secure_transport::SslProtocolSide, trust::SecTrust, @@ -74,7 +75,8 @@ impl Verifier { let certificates: Vec = std::iter::once(end_entity.0.as_slice()) .chain(intermediates.iter().map(|cert| cert.0.as_slice())) .map(|cert| { - SecCertificate::from_der(cert).map_err(|_| TlsError::InvalidCertificateEncoding) + SecCertificate::from_der(cert) + .map_err(|_| TlsError::InvalidCertificate(CertificateError::BadEncoding)) }) .collect::, _>>()?; @@ -103,13 +105,13 @@ impl Verifier { let now = system_time_to_cfdate(now)?; trust_evaluation .set_trust_verify_date(&now) - .map_err(|e| TlsError::InvalidCertificateData(e.to_string()))?; + .map_err(|e| invalid_certificate(e.to_string()))?; // If we have OCSP response data, make sure the system makes use of it. if let Some(ocsp_response) = ocsp_response { trust_evaluation .set_trust_ocsp_response(std::iter::once(ocsp_response)) - .map_err(|e| TlsError::InvalidCertificateData(e.to_string()))?; + .map_err(|e| invalid_certificate(e.to_string()))?; } // When testing, support using fake roots and ignoring values present on the system. @@ -155,17 +157,25 @@ impl Verifier { .map_err(|_| ()) .and_then(|code| { // Only map the errors we need for tests. - Ok(invalid_certificate(match code { - errors::errSecHostNameMismatch => error_messages::WRONG_NAME, - errors::errSecCreateChainFailed => error_messages::UNKNOWN_CERT, - errors::errSecInvalidExtendedKeyUsage => error_messages::INVALID_EXTENSIONS, - errors::errSecCertificateRevoked => error_messages::REVOKED, - _ => return Err(()), - })) + match code { + errors::errSecHostNameMismatch => Ok(TlsError::InvalidCertificate( + CertificateError::NotValidForName, + )), + errors::errSecCreateChainFailed => Ok(TlsError::InvalidCertificate( + CertificateError::UnknownIssuer, + )), + errors::errSecInvalidExtendedKeyUsage => Ok(TlsError::InvalidCertificate( + CertificateError::Other(std::sync::Arc::new(super::EkuError)), + )), + errors::errSecCertificateRevoked => { + Ok(TlsError::InvalidCertificate(CertificateError::Revoked)) + } + _ => Err(()), + } }) // Fallback to an error containing the description and specific error code so that // the exact error cause can be looked up easily. - .unwrap_or_else(|_| invalid_certificate(format!("{} ({})", trust_error, err_code))); + .unwrap_or_else(|_| invalid_certificate(format!("{}: {}", trust_error, err_code))); Err(err) } diff --git a/src/verification/mod.rs b/src/verification/mod.rs index 8ffd4921..ef0631a2 100644 --- a/src/verification/mod.rs +++ b/src/verification/mod.rs @@ -22,29 +22,20 @@ mod windows; #[cfg(windows)] pub use windows::Verifier; -#[cfg(any(windows, target_os = "android", target_os = "macos", target_os = "ios"))] -/// Error messages for errors that are the same across non-WebPKI verification platforms. -pub mod error_messages { - pub const INVALID_EXTENSIONS: &str = "certificate had invalid extensions"; - #[allow(dead_code)] // Not used on Apple platforms yet. - pub const EXPIRED: &str = "certificate has expired"; - pub const UNKNOWN_CERT: &str = "no trust chain found for certificate"; - pub const WRONG_NAME: &str = "certificate CN does not match the provided name"; - pub const REVOKED: &str = "certificate has been revoked"; -} +/// An EKU was invalid for the use case of verifying a server certificate. +/// +/// This error is used primarily for tests. +#[derive(Debug, PartialEq)] +pub(crate) struct EkuError; -#[cfg(all(any(test, feature = "ffi-testing"), target_os = "linux"))] -/// Error messages for WebPKI verification platforms (used only for testing). -pub mod error_messages { - pub const INVALID_EXTENSIONS: &str = "invalid peer certificate: RequiredEkuNotFound"; // Specific to current test case. - #[allow(dead_code)] // Not covered by test cases yet, due to lack of support on Apple platforms. - pub const EXPIRED: &str = "certificate has expired"; - pub const UNKNOWN_CERT: &str = "invalid peer certificate: UnknownIssuer"; - pub const WRONG_NAME: &str = "invalid peer certificate: CertNotValidForName"; - #[allow(dead_code)] // Not supported by `WebPkiVerifier` yet. - pub const REVOKED: &str = "certificate has been revoked"; +impl std::fmt::Display for EkuError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("certificate had invalid extensions") + } } +impl std::error::Error for EkuError {} + // Log the certificate we are verifying so that we can try and find what may be wrong with it // if we need to debug a user's situation. fn log_server_cert(_end_entity: &rustls::Certificate) { @@ -58,10 +49,13 @@ fn unsupported_server_name() -> rustls::Error { rustls::Error::UnsupportedNameType } -// Certificate data error shorthand +// Unknown certificate error shorthand. Used when we need to construct an "Other" certificate +// error with a platform specific error message. #[cfg(any(windows, target_os = "android", target_os = "macos", target_os = "ios"))] fn invalid_certificate(reason: impl Into) -> rustls::Error { - rustls::Error::InvalidCertificateData(reason.into()) + rustls::Error::InvalidCertificate(rustls::CertificateError::Other(std::sync::Arc::from( + Box::from(reason.into()), + ))) } #[cfg(any(windows, target_os = "android"))] diff --git a/src/verification/others.rs b/src/verification/others.rs index 3505eae6..427c02b0 100644 --- a/src/verification/others.rs +++ b/src/verification/others.rs @@ -2,7 +2,7 @@ use super::log_server_cert; use once_cell::sync::OnceCell; use rustls::{ client::{ServerCertVerifier, WebPkiVerifier}, - Error as TlsError, RootCertStore, + CertificateError, Error as TlsError, RootCertStore, }; #[derive(Default)] @@ -119,6 +119,7 @@ impl ServerCertVerifier for Verifier { ocsp_response, now, ) + .map_err(map_webpki_errors) // This only contains information from the system or other public // bits of the TLS handshake, so it can't leak anything. .map_err(|e| { @@ -128,6 +129,19 @@ impl ServerCertVerifier for Verifier { } } +fn map_webpki_errors(err: TlsError) -> TlsError { + if let TlsError::InvalidCertificate(CertificateError::Other(other_err)) = &err { + if let Some(webpki::Error::RequiredEkuNotFound) = other_err.downcast_ref::() + { + return TlsError::InvalidCertificate(CertificateError::Other(std::sync::Arc::new( + super::EkuError, + ))); + } + } + + err +} + /// Loads the static `webpki-roots` into the provided certificate store. fn load_webpki_roots(store: &mut RootCertStore) { use rustls::OwnedTrustAnchor; diff --git a/src/verification/windows.rs b/src/verification/windows.rs index 6f77f109..22fbe440 100644 --- a/src/verification/windows.rs +++ b/src/verification/windows.rs @@ -18,13 +18,11 @@ //! [Microsoft's Documentation]: //! [Microsoft's Example]: -use super::{ - error_messages, invalid_certificate, log_server_cert, unsupported_server_name, ALLOWED_EKUS, -}; +use super::{log_server_cert, unsupported_server_name, ALLOWED_EKUS}; use crate::windows::{ c_void_from_ref, c_void_from_ref_mut, nonnull_from_const_ptr, ZeroedWithSize, }; -use rustls::{client::ServerCertVerifier, Error as TlsError}; +use rustls::{client::ServerCertVerifier, CertificateError, Error as TlsError}; use winapi::{ shared::{ minwindef::{DWORD, FILETIME, TRUE}, @@ -46,6 +44,7 @@ use winapi::{ }, }; +use rustls::Error::InvalidCertificate; use std::{ convert::TryInto, mem::{self, MaybeUninit}, @@ -53,6 +52,7 @@ use std::{ time::SystemTime, }; +use crate::verification::invalid_certificate; #[cfg(any(test, feature = "ffi-testing", feature = "dbg"))] use winapi::um::wincrypt::CERT_CHAIN_ENGINE_CONFIG; @@ -308,7 +308,7 @@ impl CertificateStore { cert.as_ptr(), cert.len() .try_into() - .map_err(|_| TlsError::InvalidCertificateEncoding)?, + .map_err(|_| InvalidCertificate(CertificateError::BadEncoding))?, CERT_STORE_ADD_ALWAYS, &mut cert_context, ) @@ -318,7 +318,7 @@ impl CertificateStore { // created with the right flags; see the `CertificateStore` docs. match (res, nonnull_from_const_ptr(cert_context)) { (TRUE, Some(cert)) => Ok(Certificate { inner: cert }), - _ => Err(TlsError::InvalidCertificateEncoding), + _ => Err(InvalidCertificate(CertificateError::BadEncoding)), } } @@ -447,7 +447,7 @@ fn map_trust_error_status(unfiltered_status: DWORD) -> Result<(), TlsError> { // If the certificate is revoked, then return that, ignoring other errors, // as we consider revocation to be super critical. if (status & wincrypt::CERT_TRUST_IS_REVOKED) != 0 { - return Err(invalid_certificate(error_messages::REVOKED)); + return Err(InvalidCertificate(CertificateError::Revoked)); } if only_flags_set( @@ -455,7 +455,9 @@ fn map_trust_error_status(unfiltered_status: DWORD) -> Result<(), TlsError> { wincrypt::CERT_TRUST_IS_NOT_VALID_FOR_USAGE | wincrypt::CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE, ) { - return Err(invalid_certificate(error_messages::INVALID_EXTENSIONS)); + return Err(InvalidCertificate(CertificateError::Other( + std::sync::Arc::new(super::EkuError), + ))); } // Otherwise, if there is only one class of error, map that class to @@ -464,7 +466,7 @@ fn map_trust_error_status(unfiltered_status: DWORD) -> Result<(), TlsError> { status, wincrypt::CERT_TRUST_IS_NOT_TIME_VALID | wincrypt::CERT_TRUST_CTL_IS_NOT_TIME_VALID, ) { - return Err(invalid_certificate(error_messages::EXPIRED)); + return Err(InvalidCertificate(CertificateError::Expired)); } // XXX: winapi doesn't expose this. @@ -475,7 +477,7 @@ fn map_trust_error_status(unfiltered_status: DWORD) -> Result<(), TlsError> { | CERT_TRUST_IS_EXPLICIT_DISTRUST | wincrypt::CERT_TRUST_IS_PARTIAL_CHAIN, ) { - return Err(invalid_certificate(error_messages::UNKNOWN_CERT)); + return Err(InvalidCertificate(CertificateError::UnknownIssuer)); } // Return an error that contains exactly what Windows told us. @@ -542,9 +544,7 @@ impl Verifier { #[allow(clippy::as_conversions)] let data = CRYPT_DATA_BLOB { cbData: ocsp_data.len().try_into().map_err(|_| { - invalid_certificate( - "Malformed OCSP response stapled to server certificate".to_string(), - ) + invalid_certificate("Malformed OCSP response stapled to server certificate") })?, pbData: ocsp_data.as_ptr() as *mut u8, }; @@ -575,9 +575,9 @@ impl Verifier { let win_error = status.dwError as i32; Err(match win_error { CERT_E_CN_NO_MATCH | CERT_E_INVALID_NAME => { - invalid_certificate(error_messages::WRONG_NAME) + InvalidCertificate(CertificateError::NotValidForName) } - CRYPT_E_REVOKED => invalid_certificate(error_messages::REVOKED), + CRYPT_E_REVOKED => InvalidCertificate(CertificateError::Revoked), error_num => { let err = std::io::Error::from_raw_os_error(error_num); // The included error message has both the description and raw OS error code.