diff --git a/Cargo.lock b/Cargo.lock index 680d95c..060b340 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,15 @@ dependencies = [ "libc", ] +[[package]] +name = "async-signature" +version = "0.6.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c897aed69d0c15f782c3ae93cfc51c97cac8a45c28585f26a31255b1f03312ed" +dependencies = [ + "signature", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -44,19 +53,25 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "a4c69fae65a523209d34240b60abe0c42d33d1045d445c0839d8a4894a736e2d" dependencies = [ "bitflags", "cexpr", "clang-sys", - "itertools", "lazy_static", "lazycell", "log", + "peeking_take_while", "prettyplease", "proc-macro2", "quote", @@ -69,21 +84,39 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.5.0" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "block-buffer" +version = "0.11.0-pre.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "3ded684142010808eb980d9974ef794da2bcf97d13396143b1515e9f0fb4a10e" +dependencies = [ + "crypto-common", +] [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cexpr" @@ -102,9 +135,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" dependencies = [ "android-tzdata", "iana-time-zone", @@ -112,7 +145,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets", + "windows-targets 0.52.0", ] [[package]] @@ -126,21 +159,47 @@ dependencies = [ "libloading", ] +[[package]] +name = "const-oid" +version = "0.10.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e3352a27098ba6b09546e5f13b15165e6a88b5c2723afecb3ea9576b27e3ea" + [[package]] name = "core-foundation-sys" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] +[[package]] +name = "crypto-common" +version = "0.2.0-pre.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e" +dependencies = [ + "getrandom", + "hybrid-array", + "rand_core", +] + [[package]] name = "darling" version = "0.20.8" @@ -182,6 +241,30 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +[[package]] +name = "der" +version = "0.8.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b489fd2221710c1dd46637d66b984161fb66134f81437a8489800306bcc2ecea" +dependencies = [ + "const-oid", + "der_derive", + "flagset", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der_derive" +version = "0.8.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd1ee9778ac378876dc78f546d2821fae40a1b69ec8d82f3745392d69ff89ce6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "derive_builder" version = "0.20.0" @@ -213,11 +296,22 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.11.0-pre.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065d93ead7c220b85d5b4be4795d8398eac4ff68b5ee63895de0a3c1fb6edf25" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", +] + [[package]] name = "either" -version = "1.10.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "errno" @@ -226,9 +320,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] +[[package]] +name = "flagset" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a7e408202050813e6f1d9addadcaafef3dca7530c7ddfb005d4081cce6779" + [[package]] name = "flate2" version = "1.0.28" @@ -292,14 +392,23 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "hybrid-array" +version = "0.2.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e63b66aee2df5599ba69b17a48113dfc68d2e143ea387ef836509e433bbd7e" +dependencies = [ + "typenum", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -334,20 +443,11 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -357,6 +457,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin", +] [[package]] name = "lazycell" @@ -372,14 +475,20 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if", - "windows-targets", + "windows-sys 0.48.0", ] +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libxml" version = "0.3.3" @@ -399,9 +508,9 @@ checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "log" -version = "0.4.21" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" @@ -417,9 +526,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -434,13 +543,52 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -451,9 +599,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" dependencies = [ "bitflags", "cfg-if", @@ -483,9 +631,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.101" +version = "0.9.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" dependencies = [ "cc", "libc", @@ -493,17 +641,53 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem-rfc7468" +version = "1.0.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a65e1c27d1680f8805b3f8c9949f08d6aa5d6cbd088c9896e64a53821dc27d" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pkcs1" +version = "0.8.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f6af6e88ac39402f67488e22faa9eb15cf065f520cf4a09419393691a6d0133" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.11.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "935c09e0aecb0cb8f8907b57438b19a068cb74a25189b06724f061170b2465ff" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "ppv-lite86" @@ -523,9 +707,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -593,9 +777,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -608,6 +792,27 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "rsa" +version = "0.10.0-pre.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43e0089f12e510517c97e1adc17d0f8374efbabdd021dfb7645d6619f85633e9" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "sha2", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -624,7 +829,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -646,49 +851,112 @@ dependencies = [ "pkg-config", "quick-xml", "rand", + "rsa", "serde", + "sha2", "thiserror", "url", "uuid", + "x509-cert", ] [[package]] name = "serde" -version = "1.0.197" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "sha1" +version = "0.11.0-pre.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3885de8cb916f223718c1ccd47a840b91f806333e76002dc5cb3862154b4fed3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.11.0-pre.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f33549bf3064b62478926aa89cbfc7c109aab66ae8f0d5d2ef839e482cc30d6" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signature" +version = "2.3.0-pre.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1700c22ba9ce32c7b0a1495068a906c3552e7db386af7cf865162e0dea498523" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spki" +version = "0.8.0-pre.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb2b56670f5ef52934c97efad30bf42585de0c33ec3e2a886e38b80d2db67243" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" -version = "2.0.53" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -697,18 +965,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", @@ -730,6 +998,33 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tls_codec" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e78c9c330f8c85b2bae7c8368f2739157db9991235123aa1b15ef9502bfb6a" +dependencies = [ + "tls_codec_derive", + "zeroize", +] + +[[package]] +name = "tls_codec_derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9ef545650e79f30233c0003bcc2504d7efac6dad25fca40744de773fe2049c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -744,9 +1039,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] @@ -764,9 +1059,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.8.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ "getrandom", ] @@ -785,9 +1080,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -795,9 +1090,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -810,9 +1105,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -820,9 +1115,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -833,9 +1128,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "which" @@ -855,7 +1150,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets", + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", ] [[package]] @@ -864,62 +1168,153 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.0", ] [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 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.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 = "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]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +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" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +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" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +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.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +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 = "x509-cert" +version = "0.3.0-pre" +source = "git+https://github.com/RustCrypto/formats.git?rev=809df65b20d61e88afb7f514b5cfdd3d1958a40f#809df65b20d61e88afb7f514b5cfdd3d1958a40f" +dependencies = [ + "async-signature", + "const-oid", + "der", + "sha1", + "signature", + "spki", + "tls_codec", +] + +[[package]] +name = "zeroize" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 84b20c5..da26323 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,9 @@ doctest = false crate-type = ["staticlib", "rlib"] [features] +default = ["openssl", "xmlsec"] +openssl = ["dep:openssl", "openssl-sys", "openssl-probe"] +rustcrypto = ["rsa", "sha2", "x509-cert"] xmlsec = ["libc", "lazy_static", "libxml"] [build-dependencies] @@ -24,9 +27,6 @@ pkg-config = "^0.3.17" bindgen = "^0.69.1" [dependencies] -openssl = "^0.10.0" -openssl-sys = "^0.9.0" -openssl-probe = "^0.1.2" url = "^2.1.1" quick-xml = { version = "^0.31.0", features = ["serialize"] } serde = { version = "^1.0.0", features = ["derive"] } @@ -41,3 +41,17 @@ data-encoding = "2.2.0" libc = { version = "^0.2.66", optional = true } lazy_static = { version = "^1.4.0", optional = true } thiserror = "^1.0.40" + +# openssl +openssl = { version = "0.10", optional = true } +openssl-probe = { version = "0.1", optional = true } +openssl-sys = { version = "0.9", optional = true } + +# rustcrypto +rsa = { version = "0.10.0-pre.1", features = ["sha2"], optional = true } +sha2 = { version = "0.11.0-pre.3", optional = true } +x509-cert = { git = "https://github.com/RustCrypto/formats.git", rev = "809df65b20d61e88afb7f514b5cfdd3d1958a40f", features = [ + "pem", + "builder", + "std", +], optional = true, default-features = false } diff --git a/src/crypto.rs b/src/crypto/mod.rs similarity index 94% rename from src/crypto.rs rename to src/crypto/mod.rs index 5815d2c..aeca926 100644 --- a/src/crypto.rs +++ b/src/crypto/mod.rs @@ -1,15 +1,28 @@ use base64::{engine::general_purpose, Engine as _}; use std::collections::HashMap; -use std::convert::TryInto; +// use std::convert::TryInto; +#[cfg(feature = "xmlsec")] use std::ffi::CString; + use std::str::FromStr; use thiserror::Error; +#[cfg(not(any(feature = "rustcrypto", feature = "openssl")))] +compile_error!("No crypto backend is enabled! Please enable either rustcrypto or openssl."); + +#[cfg(all(feature = "rustcrypto", feature = "openssl"))] +compile_error!("Only one crypto backend may be enabled!"); + +pub mod rsa; +pub mod x509; + #[cfg(feature = "xmlsec")] use crate::xmlsec::{self, XmlSecKey, XmlSecKeyFormat, XmlSecSignatureContext}; #[cfg(feature = "xmlsec")] use libxml::parser::Parser as XmlParser; +use self::{rsa::PublicKeyLike, x509::CertificateLike}; + #[cfg(feature = "xmlsec")] const XMLNS_XML_DSIG: &str = "http://www.w3.org/2000/09/xmldsig#"; #[cfg(feature = "xmlsec")] @@ -61,7 +74,7 @@ pub enum Error { error: Box, }, - #[cfg(feature = "xmlsec")] + #[cfg(all(feature = "xmlsec", feature = "openssl"))] #[error("OpenSSL error stack: {}", error)] OpenSSLError { #[from] @@ -403,7 +416,7 @@ fn remove_unverified_elements(node: &mut libxml::tree::Node) { #[cfg(feature = "xmlsec")] pub(crate) fn reduce_xml_to_signed( xml_str: &str, - certs: &[openssl::x509::X509], + certs: &Vec, ) -> Result { let mut xml = XmlParser::default().parse_string(xml_str)?; let mut root_elem = xml.get_root_element().ok_or(Error::XmlMissingRootElement)?; @@ -418,7 +431,7 @@ pub(crate) fn reduce_xml_to_signed( let mut verified = false; for openssl_key in certs { let mut sig_ctx = XmlSecSignatureContext::new()?; - let key_data = openssl_key.to_der()?; + let key_data = openssl_key.public_key(); let key = XmlSecKey::from_memory(&key_data, XmlSecKeyFormat::CertDer)?; sig_ctx.insert_key(key); verified = sig_ctx.verify_node(&sig_node)?; @@ -509,32 +522,30 @@ pub enum UrlVerifierError { } pub struct UrlVerifier { - keypair: openssl::pkey::PKey, + keypair: rsa::PublicKey, } impl UrlVerifier { pub fn from_rsa_pem(public_key_pem: &[u8]) -> Result> { - let public = openssl::rsa::Rsa::public_key_from_pem(public_key_pem)?; - let keypair = openssl::pkey::PKey::from_rsa(public)?; + let keypair =rsa::PublicKey::from_pem(public_key_pem)?; Ok(Self { keypair }) } pub fn from_rsa_der(public_key_der: &[u8]) -> Result> { - let public = openssl::rsa::Rsa::public_key_from_der(public_key_der)?; - let keypair = openssl::pkey::PKey::from_rsa(public)?; + let keypair = rsa::PublicKey::from_der(public_key_der)?; Ok(Self { keypair }) } pub fn from_x509_cert_pem(public_cert_pem: &str) -> Result> { - let x509 = openssl::x509::X509::from_pem(public_cert_pem.as_bytes())?; - let keypair = x509.public_key()?; + let pubkey = x509::Certificate::from_pem(public_cert_pem.as_bytes()).unwrap().public_key(); + let keypair = rsa::PublicKey::from_der(pubkey)?; Ok(Self { keypair }) } pub fn from_x509( - public_cert: &openssl::x509::X509, + public_cert: &x509::Certificate, ) -> Result> { - let keypair = public_cert.public_key()?; + let keypair = rsa::PublicKey::from_pem(public_cert.public_key())?; Ok(Self { keypair }) } @@ -622,7 +633,7 @@ impl UrlVerifier { signed_url.scheme(), signed_url.host_str().unwrap(), ) - .as_str(), + .as_str(), )?; // Section 3.4.4.1 of @@ -654,20 +665,11 @@ impl UrlVerifier { fn verify_signature( &self, data: &[u8], + #[allow(unused_variables)] sig_alg: SigAlg, signature: &[u8], ) -> Result> { - let mut verifier = openssl::sign::Verifier::new( - match sig_alg { - SigAlg::RsaSha256 => openssl::hash::MessageDigest::sha256(), - _ => panic!("sig_alg is bad!"), - }, - &self.keypair, - )?; - - verifier.update(data)?; - - Ok(verifier.verify(signature)?) + self.keypair.verify_sha256(signature, data) } } @@ -680,13 +682,13 @@ mod test { #[test] fn test_verify_uri() { let private_key = include_bytes!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/test_vectors/private.der" + env!("CARGO_MANIFEST_DIR"), + "/test_vectors/private.der" )); let idp_metadata_xml = include_str!(concat!( - env!("CARGO_MANIFEST_DIR"), - "/test_vectors/idp_2_metadata.xml" + env!("CARGO_MANIFEST_DIR"), + "/test_vectors/idp_2_metadata.xml" )); let response_instant = "2014-07-17T01:01:48Z".parse::>().unwrap(); diff --git a/src/crypto/rsa/mod.rs b/src/crypto/rsa/mod.rs new file mode 100644 index 0000000..9f0994f --- /dev/null +++ b/src/crypto/rsa/mod.rs @@ -0,0 +1,42 @@ +#[cfg(feature = "openssl")] +mod openssl; +#[cfg(feature = "openssl")] +pub use self::openssl::*; + +#[cfg(feature = "rustcrypto")] +pub mod rustcrypto; + +#[cfg(feature = "rustcrypto")] +pub use rustcrypto::*; + +pub trait PrivateKeyLike + where + Self: Sized, +{ + fn new(bit_size: usize) -> Result>; + + fn from_pem(pem: &str) -> Result>; + + fn from_der(der: &[u8]) -> Result>; + + fn to_der(&self) -> Result, Box>; + + fn sign_sha256(&self, content_to_sign: String) -> Result, Box>; +} + +pub trait PublicKeyLike + where + Self: Sized, +{ + fn from_pem(pem: &[u8]) -> Result>; + + fn from_der(der: &[u8]) -> Result>; + + fn to_der(&self) -> Result, Box>; + + fn verify_sha256( + &self, + signature: &[u8], + data: &[u8], + ) -> Result>; +} \ No newline at end of file diff --git a/src/crypto/rsa/openssl.rs b/src/crypto/rsa/openssl.rs new file mode 100644 index 0000000..41f59a8 --- /dev/null +++ b/src/crypto/rsa/openssl.rs @@ -0,0 +1,60 @@ +use openssl::hash::MessageDigest; +use openssl::pkey::{PKey, Private, Public}; +use openssl::rsa::Rsa; +use openssl::sign::Signer; +use openssl::sign::Verifier; + +use crate::crypto::rsa::{PrivateKeyLike, PublicKeyLike}; + +pub type PrivateKey = Rsa; +pub type PublicKey = Rsa; + +impl PrivateKeyLike for PrivateKey { + fn new(bit_size: usize) -> Result> { + Ok(Self::generate(bit_size as u32)?) + } + + fn from_pem(pem: &str) -> Result> { + Ok(Self::private_key_from_pem(pem.as_bytes())?) + } + + fn from_der(der: &[u8]) -> Result> { + Ok(Self::private_key_from_der(der)?) + } + + fn to_der(&self) -> Result, Box> { + Ok(self.private_key_to_der()?) + } + + fn sign_sha256(&self, content_to_sign: String) -> Result, Box> { + let pkey = PKey::from_rsa(self.clone())?; + let mut signer = Signer::new(MessageDigest::sha256(), pkey.as_ref())?; + signer.update(content_to_sign.as_bytes())?; + Ok(signer.sign_to_vec()?) + } +} + +impl PublicKeyLike for PublicKey { + fn from_pem(pem: &[u8]) -> Result> { + Ok(Rsa::public_key_from_pem(pem)?) + } + + fn from_der(der: &[u8]) -> Result> { + Ok(Rsa::public_key_from_der(der)?) + } + + fn to_der(&self) -> Result, Box> { + Ok(self.public_key_to_der()?) + } + + fn verify_sha256( + &self, + signature: &[u8], + data: &[u8], + ) -> Result> { + let pkey = PKey::from_rsa(self.clone())?; + let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey)?; + verifier.update(data)?; + Ok(verifier.verify(signature)?) + } +} \ No newline at end of file diff --git a/src/crypto/rsa/rustcrypto.rs b/src/crypto/rsa/rustcrypto.rs new file mode 100644 index 0000000..927ddad --- /dev/null +++ b/src/crypto/rsa/rustcrypto.rs @@ -0,0 +1,66 @@ +use rsa::{ + pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey}, + pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey}, +}; + +use rsa::{Pkcs1v15Sign}; +use sha2::{Digest, Sha256}; + +use super::{PrivateKeyLike, PublicKeyLike}; + +pub use rsa::RsaPrivateKey as PrivateKey; +pub use rsa::RsaPublicKey as PublicKey; + +impl PrivateKeyLike for PrivateKey { + fn new(bit_size: usize) -> Result> { + let mut rng = rand::thread_rng(); + + Ok(PrivateKey::new(&mut rng, bit_size)?) + } + + fn from_pem(pem: &str) -> Result> { + Ok(Self::from_pkcs8_pem(pem).or_else(|_| Self::from_pkcs1_pem(pem))?) + } + + fn from_der(der: &[u8]) -> Result> { + Ok(Self::from_pkcs8_der(der).or_else(|_| Self::from_pkcs1_der(der))?) + } + + fn to_der(&self) -> Result, Box> { + Ok(self.to_pkcs8_der()?.to_bytes().to_vec()) + } + + fn sign_sha256(&self, content_to_sign: String) -> Result, Box> { + let digest = Sha256::digest(content_to_sign.as_bytes()); + let scheme = Pkcs1v15Sign::new::(); + let signature = self.sign(scheme,&digest[..])?; + Ok(signature) + } +} + +impl PublicKeyLike for PublicKey { + fn from_pem(pem: &[u8]) -> Result> { + Ok(Self::from_public_key_pem(std::str::from_utf8(pem)?) + .or_else(|_| Self::from_pkcs1_der(pem))?) + } + + fn from_der(der: &[u8]) -> Result> { + Ok(Self::from_public_key_der(der).or_else(|_| Self::from_pkcs1_der(der))?) + } + + fn to_der(&self) -> Result, Box> { + Ok(self.to_public_key_der()?.as_ref().to_vec()) + } + + fn verify_sha256( + &self, + signature: &[u8], + data: &[u8], + ) -> Result> { + //let padding = PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_256)); + let scheme = Pkcs1v15Sign::new::(); + self.verify(scheme, data, signature)?; + + Ok(true) + } +} \ No newline at end of file diff --git a/src/crypto/x509/mod.rs b/src/crypto/x509/mod.rs new file mode 100644 index 0000000..367b480 --- /dev/null +++ b/src/crypto/x509/mod.rs @@ -0,0 +1,33 @@ +use crate::crypto::rsa; +use crate::idp::CertificateParams; + +#[cfg(feature = "openssl")] +mod openssl; +#[cfg(feature = "openssl")] +pub use self::openssl::*; + +#[cfg(feature = "rustcrypto")] +mod rustcrypto; + +#[cfg(feature = "rustcrypto")] +pub use rustcrypto::*; + +pub trait CertificateLike + where + Self: Sized, +{ + fn new( + private_key: &Key, + params: &CertificateParams, + ) -> Result>; + + fn to_vec(&self) -> Result, Box>; + + fn from_der(der: &[u8]) -> Result>; + + fn public_key(&self) -> &[u8]; + + fn from_pem(pem: &[u8]) -> Result>; + + fn to_der(&self) -> Result, Box>; +} \ No newline at end of file diff --git a/src/crypto/x509/openssl.rs b/src/crypto/x509/openssl.rs new file mode 100644 index 0000000..a5ec51e --- /dev/null +++ b/src/crypto/x509/openssl.rs @@ -0,0 +1,73 @@ +use std::error::Error; +use openssl::asn1::Asn1Time; +use openssl::bn::{BigNum, MsbOption}; +use openssl::hash::MessageDigest; +use openssl::nid::Nid; +use openssl::pkey::{PKey}; +use openssl::x509::{X509Name as Name, X509}; +pub use openssl::x509::X509 as Certificate; + +use crate::crypto::rsa; +use crate::idp::CertificateParams; + +use crate::crypto::x509::CertificateLike; + +impl CertificateLike for Certificate { + fn new( + private_key: &Key, + params: &CertificateParams, + ) -> Result> { + let mut name = Name::builder()?; + name.append_entry_by_nid(Nid::COMMONNAME, params.common_name)?; + let name = name.build(); + + let mut iss = Name::builder()?; + iss.append_entry_by_nid(Nid::COMMONNAME, params.issuer_name)?; + let iss = iss.build(); + + let mut builder = X509::builder()?; + + let serial_number = { + let mut serial = BigNum::new()?; + serial.rand(159, MsbOption::MAYBE_ZERO, false)?; + serial.to_asn1_integer()? + }; + + + builder.set_serial_number(&serial_number)?; + builder.set_version(2)?; + builder.set_subject_name(&name)?; + builder.set_issuer_name(&iss)?; + let pk = PKey::private_key_from_der(private_key.to_der().unwrap().as_slice())?; + builder.set_pubkey(&pk)?; + + let starts = Asn1Time::days_from_now(0)?; // now + builder.set_not_before(&starts)?; + + let expires = Asn1Time::days_from_now(params.days_until_expiration)?; + builder.set_not_after(&expires)?; + + builder.sign(&pk, MessageDigest::sha256())?; + Ok(builder.build()) + } + + fn to_vec(&self) -> Result, Box> { + Ok(self.as_ref().to_der()?) + } + + fn from_der(der: &[u8]) -> Result> { + Ok(X509::from_der(der)?) + } + + fn public_key(&self) -> &[u8] { + self.as_ref().public_key().unwrap().public_key_to_der().unwrap().as_slice() + } + + fn from_pem(pem: &[u8]) -> Result> { + Ok(X509::from_pem(pem)?) + } + + fn to_der(&self) -> Result, Box> { + Ok(self.as_ref().to_der()?) + } +} \ No newline at end of file diff --git a/src/crypto/x509/rustcrypto.rs b/src/crypto/x509/rustcrypto.rs new file mode 100644 index 0000000..15b0bb1 --- /dev/null +++ b/src/crypto/x509/rustcrypto.rs @@ -0,0 +1,56 @@ +use std::str::FromStr; +use std::time::Duration; +use sha2::Sha256; +use rsa::pkcs1v15::SigningKey; +use x509_cert::{ + der::{Decode, Encode}, + builder::{Builder, CertificateBuilder, Profile}, + name::Name, + serial_number::SerialNumber, + spki::SubjectPublicKeyInfoOwned, + time::Validity +}; + +use super::CertificateLike; +use crate::idp::CertificateParams; +use crate::crypto::rsa::PublicKeyLike; +pub use x509_cert::Certificate; +use x509_cert::der::DecodePem; + +impl<'a> CertificateLike for Certificate { + fn new( + private_key: &crate::crypto::rsa::PrivateKey, + params: &CertificateParams, + ) -> Result> { + // Create a new certificate + let profile = Profile::Root; + let serial_number = SerialNumber::from(rand::random::()); + let validity = Validity::from_now(Duration::from_secs((params.days_until_expiration / 24 / 60 / 60) as u64)).unwrap(); + let subject = Name::from_str(format!("CN={},O={},C={}", params.common_name,params.issuer_name,params.issuer_country_code).as_str()).unwrap(); + let public_key_der = private_key.to_public_key().to_der().unwrap(); + let public_key = SubjectPublicKeyInfoOwned::from_der(&public_key_der).unwrap(); + let signer = SigningKey::::new(private_key.clone()); + let builder = CertificateBuilder::new(profile,serial_number,validity,subject,public_key).unwrap(); + Ok(builder.build(&signer).unwrap()) + } + + fn to_vec(&self) -> Result, Box> { + Ok(Encode::to_der(self)?) + } + + fn from_der(der: &[u8]) -> Result> { + Ok(Decode::from_der(der)?) + } + + fn public_key(&self) -> &[u8] { + self.tbs_certificate.subject_public_key_info.subject_public_key.raw_bytes() + } + + fn from_pem(pem: &[u8]) -> Result> { + Ok(DecodePem::from_pem(pem)?) + } + + fn to_der(&self) -> Result, Box> { + Ok(Encode::to_der(self)?) + } +} \ No newline at end of file diff --git a/src/idp/error.rs b/src/idp/error.rs index 496585c..6b41329 100644 --- a/src/idp/error.rs +++ b/src/idp/error.rs @@ -37,6 +37,7 @@ pub enum Error { error: crate::schema::authn_request::Error, }, + #[cfg(feature = "openssl")] #[error("OpenSSL Error: {}", stack)] OpenSSLError { #[from] @@ -48,4 +49,6 @@ pub enum Error { #[from] error: crate::crypto::Error, }, + #[error("Unknown Error")] + Unknown, } diff --git a/src/idp/mod.rs b/src/idp/mod.rs index c9835dd..d1ac04d 100644 --- a/src/idp/mod.rs +++ b/src/idp/mod.rs @@ -8,20 +8,29 @@ pub mod verified_request; #[cfg(test)] mod tests; -use openssl::bn::{BigNum, MsbOption}; -use openssl::nid::Nid; -use openssl::pkey::Private; -use openssl::{asn1::Asn1Time, pkey, rsa::Rsa, x509}; -use std::str::FromStr; +use crate::crypto::rsa::{PrivateKey, PrivateKeyLike}; +#[cfg(feature = "xmlsec")] +use crate::crypto; -use crate::crypto::{self}; +use crate::crypto::x509::{Certificate, CertificateLike}; +use crate::crypto::x509; -use crate::idp::response_builder::{build_response_template, ResponseAttribute}; + +#[cfg(feature = "xmlsec")] use crate::schema::Response; +#[cfg(feature = "xmlsec")] use crate::traits::ToXml; +#[cfg(feature = "xmlsec")] +use crate::idp::response_builder::{build_response_template, ResponseAttribute}; +#[cfg(feature = "xmlsec")] +use std::str::FromStr; + -pub struct IdentityProvider { - private_key: pkey::PKey, +pub struct IdentityProvider + where + PrivateKey: PrivateKeyLike, +{ + private_key: PrivateKey, } pub enum KeyType { @@ -43,64 +52,31 @@ impl KeyType { pub struct CertificateParams<'a> { pub common_name: &'a str, pub issuer_name: &'a str, + pub issuer_country_code: &'a str, pub days_until_expiration: u32, } -impl IdentityProvider { +impl IdentityProvider { pub fn generate_new(key_type: KeyType) -> Result { - let rsa = Rsa::generate(key_type.bit_length())?; - let private_key = pkey::PKey::from_rsa(rsa)?; - + let private_key = PrivateKeyLike::new(usize::try_from(key_type.bit_length()).unwrap()).unwrap(); Ok(IdentityProvider { private_key }) } pub fn from_private_key_der(der_bytes: &[u8]) -> Result { - let rsa = Rsa::private_key_from_der(der_bytes)?; - let private_key = pkey::PKey::from_rsa(rsa)?; - + let private_key = PrivateKey::from_der(der_bytes).unwrap(); Ok(IdentityProvider { private_key }) } pub fn export_private_key_der(&self) -> Result, Error> { - let rsa: Rsa = self.private_key.rsa()?; - Ok(rsa.private_key_to_der()?) + Ok(self.private_key.to_der().unwrap()) } pub fn create_certificate(&self, params: &CertificateParams) -> Result, Error> { - let mut name = x509::X509Name::builder()?; - name.append_entry_by_nid(Nid::COMMONNAME, params.common_name)?; - let name = name.build(); - - let mut iss = x509::X509Name::builder()?; - iss.append_entry_by_nid(Nid::COMMONNAME, params.issuer_name)?; - let iss = iss.build(); - - let mut builder = x509::X509::builder()?; - - let serial_number = { - let mut serial = BigNum::new()?; - serial.rand(159, MsbOption::MAYBE_ZERO, false)?; - serial.to_asn1_integer()? - }; - - builder.set_serial_number(&serial_number)?; - builder.set_version(2)?; - builder.set_subject_name(&name)?; - builder.set_issuer_name(&iss)?; - builder.set_pubkey(&self.private_key)?; - - let starts = Asn1Time::days_from_now(0)?; // now - builder.set_not_before(&starts)?; - - let expires = Asn1Time::days_from_now(params.days_until_expiration)?; - builder.set_not_after(&expires)?; - - builder.sign(&self.private_key, openssl::hash::MessageDigest::sha256())?; - - let certificate: x509::X509 = builder.build(); - Ok(certificate.to_der()?) + let cert = x509::Certificate::new(&self.private_key, params).unwrap(); + Ok(cert.to_vec().unwrap()) } + #[cfg(feature = "xmlsec")] pub fn sign_authn_response( &self, idp_x509_cert_der: &[u8], diff --git a/src/idp/tests.rs b/src/idp/tests.rs index 792a418..9f0fd36 100644 --- a/src/idp/tests.rs +++ b/src/idp/tests.rs @@ -46,6 +46,7 @@ fn test_signed_response() { common_name: "https://idp.example.com", issuer_name: "https://idp.example.com", days_until_expiration: 3650, + issuer_country_code: "IN", }; let idp_cert = idp.create_certificate(¶ms).expect("idp cert error"); @@ -144,6 +145,7 @@ fn test_signed_response_fingerprint() { common_name: "https://idp.example.com", issuer_name: "https://idp.example.com", days_until_expiration: 3650, + issuer_country_code: "IN", }; let idp_cert = idp.create_certificate(¶ms).expect("idp cert error"); diff --git a/src/idp/verified_request.rs b/src/idp/verified_request.rs index 11919bc..7e50616 100644 --- a/src/idp/verified_request.rs +++ b/src/idp/verified_request.rs @@ -1,12 +1,15 @@ use quick_xml::events::Event; -use crate::crypto::{self, verify_signed_xml}; +use crate::crypto; use crate::schema::AuthnRequest; - use super::error::Error; +#[cfg(feature = "xmlsec")] +use crate::crypto::verify_signed_xml; + pub struct UnverifiedAuthnRequest<'a> { pub request: AuthnRequest, + #[allow(dead_code)] xml: &'a str, } @@ -43,6 +46,7 @@ impl<'a> UnverifiedAuthnRequest<'a> { Ok(x509_certs) } + #[cfg(feature = "xmlsec")] pub fn try_verify_self_signed(self) -> Result { let xml = self.xml.as_bytes(); self.get_certs_der()? @@ -53,6 +57,7 @@ impl<'a> UnverifiedAuthnRequest<'a> { .map(|()| VerifiedAuthnRequest(self.request)) } + #[cfg(feature = "xmlsec")] pub fn try_verify_with_cert(self, der_cert: &[u8]) -> Result { verify_signed_xml(self.xml.as_bytes(), der_cert, Some("ID"))?; Ok(VerifiedAuthnRequest(self.request)) @@ -85,6 +90,7 @@ impl TryFrom<&VerifiedAuthnRequest> for Event<'_> { } #[cfg(test)] +#[cfg(feature = "xmlsec")] mod test { use super::UnverifiedAuthnRequest; use crate::traits::ToXml; diff --git a/src/lib.rs b/src/lib.rs index a4d14f8..ffb707b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,6 @@ pub mod attribute; #[cfg(feature = "xmlsec")] mod bindings; pub mod crypto; -#[cfg(feature = "xmlsec")] pub mod idp; pub mod key_info; pub mod metadata; diff --git a/src/schema/mod.rs b/src/schema/mod.rs index 5a30181..781ece3 100644 --- a/src/schema/mod.rs +++ b/src/schema/mod.rs @@ -1,9 +1,11 @@ -pub mod authn_request; -mod conditions; -mod issuer; -mod name_id_policy; -mod response; -mod subject; +use std::io::Cursor; +use std::str::FromStr; + +use chrono::prelude::*; +use quick_xml::events::{BytesDecl, BytesEnd, BytesStart, BytesText, Event}; +use quick_xml::Writer; +use serde::Deserialize; +use thiserror::Error; pub use authn_request::AuthnRequest; pub use conditions::*; @@ -14,16 +16,13 @@ pub use subject::*; use crate::attribute::Attribute; use crate::signature::Signature; -use chrono::prelude::*; -use serde::Deserialize; - -use quick_xml::events::{BytesDecl, BytesEnd, BytesStart, BytesText, Event}; -use quick_xml::Writer; - -use std::io::Cursor; -use std::str::FromStr; -use thiserror::Error; +pub mod authn_request; +mod conditions; +mod issuer; +mod name_id_policy; +mod response; +mod subject; #[derive(Clone, Debug, Deserialize, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct NameID { @@ -672,9 +671,7 @@ impl LogoutResponse { #[cfg(test)] mod test { - use super::issuer::Issuer; - use super::{LogoutRequest, LogoutResponse, NameID, Status, StatusCode}; - use chrono::TimeZone; + use super::{LogoutRequest, LogoutResponse}; #[test] fn test_deserialize_serialize_logout_request() { diff --git a/src/service_provider/mod.rs b/src/service_provider/mod.rs index a237052..23665bb 100644 --- a/src/service_provider/mod.rs +++ b/src/service_provider/mod.rs @@ -1,4 +1,5 @@ -use crate::crypto; +use crate::crypto::rsa::PrivateKeyLike; +use crate::crypto::{self, rsa, x509}; use crate::metadata::{Endpoint, IndexedEndpoint, KeyDescriptor, NameIdFormat, SpSsoDescriptor}; use crate::schema::{Assertion, Response}; use crate::traits::ToXml; @@ -11,8 +12,6 @@ use base64::{engine::general_purpose, Engine as _}; use chrono::prelude::*; use chrono::Duration; use flate2::{write::DeflateEncoder, Compression}; -use openssl::pkey::Private; -use openssl::{rsa, x509}; use std::fmt::Debug; use std::io::Write; use thiserror::Error; @@ -23,6 +22,7 @@ mod tests; #[cfg(feature = "xmlsec")] use crate::crypto::reduce_xml_to_signed; +use crate::crypto::x509::{Certificate, CertificateLike}; #[cfg(not(feature = "xmlsec"))] fn reduce_xml_to_signed(xml_str: &str, _keys: &Vec) -> Result { @@ -101,11 +101,14 @@ pub enum Error { #[derive(Builder, Clone)] #[builder(default, setter(into))] -pub struct ServiceProvider { +pub struct ServiceProvider + where + ServiceProvider: Default, +{ pub entity_id: Option, - pub key: Option>, - pub certificate: Option, - pub intermediates: Option>, + pub key: Option, + pub certificate: Option, + pub intermediates: Option>, pub metadata_url: Option, pub acs_url: Option, pub slo_url: Option, @@ -119,7 +122,7 @@ pub struct ServiceProvider { pub max_clock_skew: Duration, } -impl Default for ServiceProvider { +impl Default for ServiceProvider { fn default() -> Self { ServiceProvider { entity_id: None, @@ -141,7 +144,7 @@ impl Default for ServiceProvider { } } -impl ServiceProvider { +impl ServiceProvider { pub fn metadata(&self) -> Result> { let valid_duration = if let Some(duration) = self.metadata_valid_duration { Some(duration) @@ -159,6 +162,7 @@ impl ServiceProvider { let mut key_descriptors = vec![]; if let Some(cert) = &self.certificate { + let cert = cert as &Certificate; let mut cert_bytes: Vec = cert.to_der()?; if let Some(intermediates) = &self.intermediates { for intermediate in intermediates { @@ -273,7 +277,7 @@ impl ServiceProvider { None } - pub fn idp_signing_certs(&self) -> Result>, Error> { + pub fn idp_signing_certs(&self) -> Result>, Error> { let mut result = vec![]; if let Some(idp_sso_descriptors) = &self.idp_metadata.idp_sso_descriptors { for idp_sso_descriptor in idp_sso_descriptors { @@ -489,7 +493,7 @@ impl ServiceProvider { } } -fn parse_certificates(key_descriptor: &KeyDescriptor) -> Result, Error> { +fn parse_certificates(key_descriptor: &KeyDescriptor) -> Result, Error> { key_descriptor .key_info .x509_data @@ -500,7 +504,7 @@ fn parse_certificates(key_descriptor: &KeyDescriptor) -> Result, .map(|cert| { crypto::decode_x509_cert(cert) .ok() - .and_then(|decoded| openssl::x509::X509::from_der(&decoded).ok()) + .and_then(|decoded| x509::Certificate::from_der(&decoded).ok()) .ok_or_else(|| Error::FailedToParseCert { cert: cert.to_string(), }) @@ -584,24 +588,17 @@ impl AuthnRequest { // http://some.idp.com?SAMLRequest=value&RelayState=value&SigAlg=value // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // - // then add the "Signature" query parameter afterwards. + // then add the "Signature" query parameter afterward. let string_to_sign: String = unsigned_url .query() .ok_or(Error::UnexpectedError)? .to_string(); - // Use openssl's bindings to sign - let pkey = openssl::rsa::Rsa::private_key_from_der(private_key_der)?; - let pkey = openssl::pkey::PKey::from_rsa(pkey)?; - - let mut signer = - openssl::sign::Signer::new(openssl::hash::MessageDigest::sha256(), pkey.as_ref())?; - - signer.update(string_to_sign.as_bytes())?; + let private_key = rsa::PrivateKey::from_der(private_key_der)?; unsigned_url.query_pairs_mut().append_pair( "Signature", - &general_purpose::STANDARD.encode(signer.sign_to_vec()?), + &general_purpose::STANDARD.encode(private_key.sign_sha256(string_to_sign)?), ); // Past this point, it's a signed url :) diff --git a/src/xmlsec/backend.rs b/src/xmlsec/backend.rs index d1d948e..2127ee2 100644 --- a/src/xmlsec/backend.rs +++ b/src/xmlsec/backend.rs @@ -9,8 +9,8 @@ use crate::bindings as backend; mod backend { pub use crate::bindings::{ xmlSecOpenSSLAppInit as xmlSecCryptoAppInit, - xmlSecOpenSSLAppKeyCertLoad as xmlSecCryptoAppKeyCertLoad, - xmlSecOpenSSLAppKeyCertLoadMemory as xmlSecCryptoAppKeyCertLoadMemory, + // xmlSecOpenSSLAppKeyCertLoad as xmlSecCryptoAppKeyCertLoad, + // xmlSecOpenSSLAppKeyCertLoadMemory as xmlSecCryptoAppKeyCertLoadMemory, xmlSecOpenSSLAppKeyLoadMemory as xmlSecCryptoAppKeyLoadMemory, xmlSecOpenSSLAppShutdown as xmlSecCryptoAppShutdown, xmlSecOpenSSLInit as xmlSecCryptoInit, xmlSecOpenSSLShutdown as xmlSecCryptoShutdown, diff --git a/src/xmlsec/mod.rs b/src/xmlsec/mod.rs index b28d644..e614023 100644 --- a/src/xmlsec/mod.rs +++ b/src/xmlsec/mod.rs @@ -12,7 +12,7 @@ #[doc(hidden)] pub use libxml::tree::document::Document as XmlDocument; #[doc(hidden)] -pub use libxml::tree::node::Node as XmlNode; +// pub use libxml::tree::node::Node as XmlNode; mod backend; mod error;