diff --git a/Cargo.lock b/Cargo.lock index 23e7230..4907642 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -14,27 +23,324 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" + [[package]] name = "byteorder" version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "time", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "4.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d928d978dbec61a1167414f5ec534f24bea0d7a0d24dd9b6233d3d8223e585" +dependencies = [ + "cfg-if", + "digest", + "fiat-crypto", + "packed_simd_2", + "platforms", + "subtle", + "zeroize", +] + +[[package]] +name = "cxx" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.15", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "der" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e58dffcdcc8ee7b22f0c1f71a69243d7c2d9ad87b5a14361f2424a1565c219" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "ed25519" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "798f704d128510932661a3489b08e3f4c934a01d61c5def59ae7b8e48f19665a" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core", + "serde", + "sha2", + "zeroize", +] + +[[package]] +name = "fiat-crypto" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" + [[package]] name = "libepf" version = "0.1.0" dependencies = [ + "chrono", + "ed25519-dalek", "hex", "pem", + "rand", "rmp-serde", "serde", "serde_arrays", + "sha2", + "x25519-dalek", +] + +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[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]] @@ -46,6 +352,22 @@ dependencies = [ "autocfg", ] +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "packed_simd_2" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" +dependencies = [ + "cfg-if", + "libm", +] + [[package]] name = "paste" version = "1.0.12" @@ -62,6 +384,28 @@ dependencies = [ "serde", ] +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "platforms" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" version = "1.0.56" @@ -80,6 +424,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "rmp" version = "0.8.11" @@ -102,6 +476,12 @@ dependencies = [ "serde", ] +[[package]] +name = "scratch" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" + [[package]] name = "serde" version = "1.0.160" @@ -128,7 +508,51 @@ checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" + +[[package]] +name = "spki" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a5be806ab6f127c3da44b7378837ebf01dadca8510a0e572460216b228bd0e" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] @@ -142,8 +566,241 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + [[package]] name = "unicode-ident" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +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.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "x25519-dalek" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabd6e16dd08033932fc3265ad4510cc2eab24656058a6dcb107ffe274abcc95" +dependencies = [ + "curve25519-dalek", + "rand_core", + "serde", + "zeroize", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +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 2.0.15", +] diff --git a/libepf/Cargo.toml b/libepf/Cargo.toml index 2aa1016..d8d0b79 100644 --- a/libepf/Cargo.toml +++ b/libepf/Cargo.toml @@ -10,4 +10,9 @@ serde = { version = "1", features = ["derive"] } serde_arrays = "0.1" # TODO: Remove. Pending on serde supporting const generics rmp-serde = "1" pem = "2" -hex = "0.4" \ No newline at end of file +hex = "0.4" +sha2 = "0.10" +ed25519-dalek = { version = "2.0.0-rc.2", features = ["rand_core"] } +rand = "0.8" +x25519-dalek = "2.0.0-rc.2" +chrono = "0.4" \ No newline at end of file diff --git a/libepf/src/ca_pool.rs b/libepf/src/ca_pool.rs new file mode 100644 index 0000000..dcd7002 --- /dev/null +++ b/libepf/src/ca_pool.rs @@ -0,0 +1,28 @@ +use std::collections::HashMap; +use crate::pki::{EPFCertificate, EpfPublicKey}; + +pub struct EpfCaPool { + pub ca_lookup_table: HashMap +} + +pub trait EpfCaPoolOps { + fn new() -> Self; + fn get_ca(&self, public_key: &EpfPublicKey) -> Option<&EPFCertificate>; + fn insert(&mut self, cert: &EPFCertificate); +} + +impl EpfCaPoolOps for EpfCaPool { + fn new() -> Self { + Self { + ca_lookup_table: HashMap::new() + } + } + + fn get_ca(&self, public_key: &EpfPublicKey) -> Option<&EPFCertificate> { + self.ca_lookup_table.get(public_key) + } + + fn insert(&mut self, cert: &EPFCertificate) { + self.ca_lookup_table.insert(cert.details.public_key, cert.clone()); + } +} \ No newline at end of file diff --git a/libepf/src/lib.rs b/libepf/src/lib.rs index aa1c855..cf2a922 100644 --- a/libepf/src/lib.rs +++ b/libepf/src/lib.rs @@ -1 +1,3 @@ -pub mod pki; \ No newline at end of file +pub mod pki; +pub mod util; +pub mod ca_pool; \ No newline at end of file diff --git a/libepf/src/pki.rs b/libepf/src/pki.rs index c967d50..fa45715 100644 --- a/libepf/src/pki.rs +++ b/libepf/src/pki.rs @@ -1,16 +1,23 @@ use std::collections::HashMap; use std::error::Error; use std::fmt::{Display, Formatter}; +use std::time::{SystemTime}; +use ed25519_dalek::{Signature, SignatureError, Signer, SigningKey, Verifier, VerifyingKey}; use pem::Pem; use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; +use crate::ca_pool::{EpfCaPool, EpfCaPoolOps}; +use crate::util::{pretty_print_date, u64_to_st}; pub const EPFPKI_PUBLIC_KEY_LENGTH: usize = 32; pub const EPFPKI_SIGNATURE_LENGTH: usize = 64; +pub const EPFPKI_SELF_SIGNED_CERTIFICATE: &str = "0000000000000000000000000000000000000000000000000000000000000000"; + pub type EpfPublicKey = [u8; 32]; pub type EpfPrivateKey = [u8; 64]; -#[derive(Serialize, Deserialize, PartialEq, Debug, Eq)] +#[derive(Serialize, Deserialize, PartialEq, Debug, Eq, Clone)] pub struct EPFCertificate { pub details: EPFCertificateDetails, pub fingerprint: String, @@ -18,7 +25,7 @@ pub struct EPFCertificate { pub signature: [u8; EPFPKI_SIGNATURE_LENGTH] } -#[derive(Serialize, Deserialize, PartialEq, Debug, Eq)] +#[derive(Serialize, Deserialize, PartialEq, Debug, Eq, Clone)] pub struct EPFCertificateDetails { pub name: String, @@ -27,8 +34,7 @@ pub struct EPFCertificateDetails { pub public_key: [u8; EPFPKI_PUBLIC_KEY_LENGTH], - pub issuer_name: String, - pub issuer_fingerprint: String, + pub issuer_public_key: [u8; EPFPKI_PUBLIC_KEY_LENGTH], pub claims: HashMap } @@ -43,19 +49,155 @@ pub trait EpfPkiSerializable { fn from_pem(bytes: &[u8]) -> Result> where Self: Sized; } +pub fn fingerprint(cert: &EPFCertificateDetails) -> Result { + let cert_bytes = rmp_serde::to_vec(cert)?; + let mut hasher = Sha256::new(); + hasher.update(cert_bytes); + let hash = hasher.finalize(); + Ok(hex::encode(hash)) +} + +fn load_signing_key(b: &[u8; 64]) -> Result { + SigningKey::from_keypair_bytes(b) +} + +#[derive(Debug)] +pub enum EpfPkiCertificateValidationError { + NoLongerValid { expired_at: SystemTime }, + NotValidYet { valid_at: SystemTime }, + InvalidCertificateData { e: rmp_serde::encode::Error }, + FingerprintDoesNotMatch { expected: String, got: String }, + InvalidSignature { e: SignatureError }, + ExpiresAfterSigner, + ValidAfterSigner +} + +impl Display for EpfPkiCertificateValidationError { + #[cfg_attr(tarpaulin, ignore)] + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + EpfPkiCertificateValidationError::NoLongerValid { expired_at } => write!(f, "Certificate no longer valid (expired at {})", pretty_print_date(expired_at)), + EpfPkiCertificateValidationError::NotValidYet { valid_at } => write!(f, "Certificate not valid yet (valid at {})", pretty_print_date(valid_at)), + EpfPkiCertificateValidationError::InvalidCertificateData { e } => write!(f, "Unable to serialize cert data: {}", e), + EpfPkiCertificateValidationError::FingerprintDoesNotMatch { expected, got } => write!(f, "Fingerprint mismatch (expected {}, got {})", expected, got), + EpfPkiCertificateValidationError::InvalidSignature { e } => write!(f, "Certificate validation error: {}", e), + EpfPkiCertificateValidationError::ExpiresAfterSigner => write!(f, "Certificate expires after it's signing certificate"), + EpfPkiCertificateValidationError::ValidAfterSigner => write!(f, "Certificate is valid longer than it's signing certificate") + } + } +} + +pub trait EpfPkiCertificateOps { + fn recalculate_fingerprint(&mut self) -> Result<(), rmp_serde::encode::Error>; + fn sign(&mut self, private_key: &EpfPrivateKey) -> Result<(), Box>; + fn verify_with_time(&self, time: SystemTime, ca_pool: &EpfCaPool) -> Result; + fn verify(&self, ca_pool: &EpfCaPool) -> Result; +} +impl EpfPkiCertificateOps for EPFCertificate { + fn recalculate_fingerprint(&mut self) -> Result<(), rmp_serde::encode::Error> { + self.fingerprint = fingerprint(&self.details)?; + Ok(()) + } + + fn sign(&mut self, private_key: &EpfPrivateKey) -> Result<(), Box> { + self.recalculate_fingerprint()?; + + let signing_key = load_signing_key(private_key)?; + self.details.issuer_public_key = *signing_key.verifying_key().as_bytes(); + + let cert_data_bytes = rmp_serde::to_vec(&self.details)?; + + let signature = signing_key.sign(&cert_data_bytes).to_vec(); + + self.signature = signature.try_into().unwrap(); + + self.recalculate_fingerprint()?; + + Ok(()) + } + + fn verify_with_time(&self, time: SystemTime, ca_pool: &EpfCaPool) -> Result { + // Is it expired + if u64_to_st(self.details.not_after) < time { + return Err(EpfPkiCertificateValidationError::NoLongerValid {expired_at: u64_to_st(self.details.not_after)}) + } + + // Is it valid yet + if u64_to_st(self.details.not_before) > time { + return Err(EpfPkiCertificateValidationError::NotValidYet {valid_at: u64_to_st(self.details.not_before)}) + } + + let fingerprint_on_cert = fingerprint(&self.details).map_err(|e| EpfPkiCertificateValidationError::InvalidCertificateData { e })?; + + // Does the fingerprint match + if fingerprint_on_cert != self.fingerprint { + return Err(EpfPkiCertificateValidationError::FingerprintDoesNotMatch { expected: self.fingerprint.clone(), got: fingerprint_on_cert}) + } + + // Does the signature match + let signature = Signature::from_slice(&self.signature).map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?; + + let is_self_signed; + + println!("{}: {:?} {:?}", self.details.name, self.details.issuer_public_key, self.details.public_key); + + let verifying_key = if self.details.issuer_public_key == self.details.public_key { + // self-signed certificate + is_self_signed = true; + VerifyingKey::from_bytes(&self.details.public_key).map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })? + } else { + is_self_signed = false; + VerifyingKey::from_bytes(&self.details.issuer_public_key).map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })? + }; + + let cert_data_bytes = rmp_serde::to_vec(&self.details).map_err(|e| EpfPkiCertificateValidationError::InvalidCertificateData { e })?; + + verifying_key.verify(&cert_data_bytes, &signature).map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?; + + // Signature OK + + // Is the signer trusted? + let ca_cert = if is_self_signed { + if let Some(cert) = ca_pool.get_ca(&self.details.public_key) { + cert + } else { + return Ok(false); + } + } else if let Some(cert) = ca_pool.get_ca(&self.details.issuer_public_key) { + cert + } else { + return Ok(false); + }; + // Yes. + // Make sure this cert wasnt valid before the CA + if ca_cert.details.not_after < self.details.not_after { + return Err(EpfPkiCertificateValidationError::ExpiresAfterSigner); + } + // Make sure this cert isnt valid after the root + if ca_cert.details.not_before > self.details.not_before { + return Err(EpfPkiCertificateValidationError::ValidAfterSigner) + } + + // Cert OK + + Ok(true) + } + + fn verify(&self, ca_pool: &EpfCaPool) -> Result { + self.verify_with_time(SystemTime::now(), ca_pool) + } +} + #[cfg_attr(tarpaulin, ignore)] impl Display for EPFCertificate { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { writeln!(f, "EPFCertificate {{")?; writeln!(f, "\tDetails: {{")?; writeln!(f, "\t\tName: {}", self.details.name)?; - writeln!(f, "\t\tNot Before: {}", self.details.not_before)?; - writeln!(f, "\t\tNot After: {}", self.details.not_after)?; + writeln!(f, "\t\tNot Before: {}", pretty_print_date(&u64_to_st(self.details.not_before)))?; + writeln!(f, "\t\tNot After: {}", pretty_print_date(&u64_to_st(self.details.not_after)))?; writeln!(f, "\t\tPublic Key: {}", hex::encode(self.details.public_key))?; - writeln!(f, "\t\tIssuer: {{")?; - writeln!(f, "\t\t\tName: {}", self.details.issuer_name)?; - writeln!(f, "\t\t\tFingerprint: {}", self.details.issuer_fingerprint)?; - writeln!(f, "\t\t}}")?; + writeln!(f, "\t\tIssuer Fingerprint: {}", hex::encode(self.details.issuer_public_key))?; writeln!(f, "\t}}")?; writeln!(f, "\tFingerprint: {}", self.fingerprint)?; writeln!(f, "\tSignature: {}", hex::encode(self.signature))?; @@ -138,7 +280,11 @@ impl EpfPkiSerializable for EpfPrivateKey { #[cfg(test)] mod tests { use std::collections::HashMap; - use crate::pki::{EPFCertificate, EPFCertificateDetails, EPFPKI_PUBLIC_KEY_LENGTH, EPFPKI_SIGNATURE_LENGTH, EpfPkiSerializable, EpfPrivateKey, EpfPublicKey}; + use std::time::{SystemTime, UNIX_EPOCH}; + use ed25519_dalek::{SignatureError, SigningKey}; + use rand::rngs::OsRng; + use crate::ca_pool::{EpfCaPool, EpfCaPoolOps}; + use crate::pki::{EPFCertificate, EPFCertificateDetails, EPFPKI_PUBLIC_KEY_LENGTH, EPFPKI_SIGNATURE_LENGTH, EpfPkiCertificateOps, EpfPkiCertificateValidationError, EpfPkiSerializable, EpfPrivateKey, EpfPublicKey}; #[test] pub fn certificate_serialization() { @@ -212,15 +358,240 @@ mod tests { assert_eq!(EpfPrivateKey::from_pem(&null_private_key_pem()).unwrap(), [0u8; 64]) } + #[test] + #[should_panic] + pub fn privkey_deserialization_pem_wrong_tag() { + assert_eq!(EpfPrivateKey::from_pem(&null_public_key_pem()).unwrap(), [0u8; 64]) + } + #[test] pub fn cert_display() { println!("{}", cert()); } #[test] - #[should_panic] - pub fn privkey_deserialization_pem_wrong_tag() { - EPFCertificate::from_pem(&null_public_key_pem()).unwrap(); + pub fn cert_fingerprinting() { + let mut cert = cert(); + cert.recalculate_fingerprint().unwrap(); + assert_eq!(cert.fingerprint, "922c5cb83633b214d19d9aebf387314fcde67210ff92bd9691fbd059141d6adf"); + } + + #[test] + pub fn cert_validation() { + let private_key = SigningKey::generate(&mut OsRng); + let public_key = private_key.verifying_key(); + + let private_key2 = SigningKey::generate(&mut OsRng); + let public_key2 = private_key2.verifying_key(); + + let mut ca_pool = EpfCaPool::new(); + + let mut ca_cert = EPFCertificate { + details: EPFCertificateDetails { + name: "Testing CA".to_string(), + not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10, + not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 60, + public_key: *public_key.as_bytes(), + issuer_public_key: [0u8; 32], + claims: Default::default(), + }, + fingerprint: "".to_string(), + signature: [0u8; EPFPKI_SIGNATURE_LENGTH], + }; + + println!("{}", ca_cert); + + assert!(ca_cert.verify(&ca_pool).is_err()); + + ca_cert.sign(&private_key.to_keypair_bytes()).unwrap(); + + assert!(!ca_cert.verify(&ca_pool).unwrap()); + + ca_pool.insert(&ca_cert); + + assert!(ca_cert.verify(&ca_pool).unwrap()); + + ca_pool.insert(&ca_cert); + + let mut not_ca_cert = EPFCertificate { + details: EPFCertificateDetails { + name: "Testing Certificate".to_string(), + not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10, + not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 60, + public_key: *public_key2.as_bytes(), + issuer_public_key: [0u8; 32], + claims: Default::default(), + }, + fingerprint: "".to_string(), + signature: [0u8; EPFPKI_SIGNATURE_LENGTH], + }; + + assert!(not_ca_cert.verify(&ca_pool).is_err()); + not_ca_cert.sign(&private_key.to_keypair_bytes()).unwrap(); + assert!(not_ca_cert.verify(&ca_pool).unwrap()); + } + + #[test] + pub fn certificate_verification_expired() { + let expired_cert = EPFCertificate { + details: EPFCertificateDetails { + name: "Testing Certificate - Expired".to_string(), + not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(), + not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() -20, + public_key: [0u8; 32], + issuer_public_key: [0u8; 32], + claims: Default::default(), + }, + fingerprint: "".to_string(), + signature: [0u8; EPFPKI_SIGNATURE_LENGTH], + }; + + let ca_pool = EpfCaPool::new(); + + assert!(matches!(expired_cert.verify(&ca_pool).unwrap_err(), EpfPkiCertificateValidationError::NoLongerValid { .. })) + } + + #[test] + pub fn certificate_verification_not_valid_yet() { + let not_yet_valid_cert = EPFCertificate { + details: EPFCertificateDetails { + name: "Testing Certificate - Not Yet Valid".to_string(), + not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 20, + not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 30, + public_key: [0u8; 32], + issuer_public_key: [0u8; 32], + claims: Default::default(), + }, + fingerprint: "".to_string(), + signature: [0u8; EPFPKI_SIGNATURE_LENGTH], + }; + + let ca_pool = EpfCaPool::new(); + + assert!(matches!(not_yet_valid_cert.verify(&ca_pool).unwrap_err(), EpfPkiCertificateValidationError::NotValidYet { .. })) + } + + #[test] + pub fn certificate_verification_not_trusted() { + let private_key = SigningKey::generate(&mut OsRng); + let public_key = private_key.verifying_key(); + + let mut not_trusted_cert = EPFCertificate { + details: EPFCertificateDetails { + name: "Testing Certificate - Not Trusted".to_string(), + not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 20, + not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 30, + public_key: [0u8; 32], + issuer_public_key: *public_key.as_bytes(), + claims: Default::default(), + }, + fingerprint: "".to_string(), + signature: [0u8; EPFPKI_SIGNATURE_LENGTH], + }; + not_trusted_cert.sign(&private_key.to_keypair_bytes()).unwrap(); + + let ca_pool = EpfCaPool::new(); + + assert!(!not_trusted_cert.verify(&ca_pool).unwrap()); + } + + #[test] + pub fn cert_validation_expires_after_signer() { + let private_key = SigningKey::generate(&mut OsRng); + let public_key = private_key.verifying_key(); + + let private_key2 = SigningKey::generate(&mut OsRng); + let public_key2 = private_key2.verifying_key(); + + let mut ca_pool = EpfCaPool::new(); + + let mut ca_cert = EPFCertificate { + details: EPFCertificateDetails { + name: "Testing CA".to_string(), + not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10, + not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 60, + public_key: *public_key.as_bytes(), + issuer_public_key: [0u8; 32], + claims: Default::default(), + }, + fingerprint: "".to_string(), + signature: [0u8; EPFPKI_SIGNATURE_LENGTH], + }; + + ca_cert.sign(&private_key.to_keypair_bytes()).unwrap(); + ca_pool.insert(&ca_cert); + + let mut not_ca_cert = EPFCertificate { + details: EPFCertificateDetails { + name: "Testing Certificate - Valid After Signer".to_string(), + not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10, + not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 120, + public_key: *public_key2.as_bytes(), + issuer_public_key: [0u8; 32], + claims: Default::default(), + }, + fingerprint: "".to_string(), + signature: [0u8; EPFPKI_SIGNATURE_LENGTH], + }; + + assert!(not_ca_cert.verify(&ca_pool).is_err()); + not_ca_cert.sign(&private_key.to_keypair_bytes()).unwrap(); + assert!(matches!(not_ca_cert.verify(&ca_pool).unwrap_err(), EpfPkiCertificateValidationError::ExpiresAfterSigner)); + } + + #[test] + pub fn cert_validation_valid_after_signer() { + let private_key = SigningKey::generate(&mut OsRng); + let public_key = private_key.verifying_key(); + + let private_key2 = SigningKey::generate(&mut OsRng); + let public_key2 = private_key2.verifying_key(); + + let mut ca_pool = EpfCaPool::new(); + + let mut ca_cert = EPFCertificate { + details: EPFCertificateDetails { + name: "Testing CA".to_string(), + not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10, + not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 60, + public_key: *public_key.as_bytes(), + issuer_public_key: [0u8; 32], + claims: Default::default(), + }, + fingerprint: "".to_string(), + signature: [0u8; EPFPKI_SIGNATURE_LENGTH], + }; + + ca_cert.sign(&private_key.to_keypair_bytes()).unwrap(); + ca_pool.insert(&ca_cert); + + let mut not_ca_cert = EPFCertificate { + details: EPFCertificateDetails { + name: "Testing Certificate - Valid After Signer".to_string(), + not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 200, + not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 10, + public_key: *public_key2.as_bytes(), + issuer_public_key: [0u8; 32], + claims: Default::default(), + }, + fingerprint: "".to_string(), + signature: [0u8; EPFPKI_SIGNATURE_LENGTH], + }; + + assert!(not_ca_cert.verify(&ca_pool).is_err()); + not_ca_cert.sign(&private_key.to_keypair_bytes()).unwrap(); + assert!(matches!(not_ca_cert.verify(&ca_pool).unwrap_err(), EpfPkiCertificateValidationError::ValidAfterSigner)); + } + + #[test] + pub fn verifying_error_display() { + println!("{}", EpfPkiCertificateValidationError::NoLongerValid { expired_at: SystemTime::now() }); + println!("{}", EpfPkiCertificateValidationError::NotValidYet { valid_at: SystemTime::now() }); + println!("{}", EpfPkiCertificateValidationError::InvalidCertificateData { e: rmp_serde::encode::Error::UnknownLength}); + println!("{}", EpfPkiCertificateValidationError::FingerprintDoesNotMatch { expected: "".to_string(), got: "".to_string() }); + println!("{}", EpfPkiCertificateValidationError::InvalidSignature { e: SignatureError::new() }); + println!("{}", EpfPkiCertificateValidationError::ExpiresAfterSigner); + println!("{}", EpfPkiCertificateValidationError::ValidAfterSigner); } fn cert() -> EPFCertificate { @@ -230,8 +601,7 @@ mod tests { not_before: 0, not_after: 0, public_key: [0u8; EPFPKI_PUBLIC_KEY_LENGTH], - issuer_name: "Invalid Testing Certificate Issuer".to_string(), - issuer_fingerprint: "0000000000000000000000000000000000000000000000000000000000000000".to_string(), + issuer_public_key: [0u8; EPFPKI_PUBLIC_KEY_LENGTH], claims: HashMap::new() }, fingerprint: "0000000000000000000000000000000000000000000000000000000000000000".to_string(), @@ -239,10 +609,10 @@ mod tests { } } fn cert_bytes() -> Vec { - vec![147, 151, 187, 73, 110, 118, 97, 108, 105, 100, 32, 84, 101, 115, 116, 105, 110, 103, 32, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 0, 0, 220, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 34, 73, 110, 118, 97, 108, 105, 100, 32, 84, 101, 115, 116, 105, 110, 103, 32, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 32, 73, 115, 115, 117, 101, 114, 217, 64, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 128, 217, 64, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 220, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + vec![147, 150, 187, 73, 110, 118, 97, 108, 105, 100, 32, 84, 101, 115, 116, 105, 110, 103, 32, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 0, 0, 220, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 217, 64, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 220, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] } fn cert_pem() -> Vec { - vec![45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 67, 69, 82, 84, 73, 70, 73, 67, 65, 84, 69, 45, 45, 45, 45, 45, 13, 10, 107, 53, 101, 55, 83, 87, 53, 50, 89, 87, 120, 112, 90, 67, 66, 85, 90, 88, 78, 48, 97, 87, 53, 110, 73, 69, 78, 108, 99, 110, 82, 112, 90, 109, 108, 106, 89, 88, 82, 108, 65, 65, 68, 99, 65, 67, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 78, 107, 105, 83, 87, 53, 50, 89, 87, 120, 112, 90, 67, 66, 85, 90, 88, 78, 48, 97, 87, 53, 110, 73, 69, 78, 108, 99, 110, 82, 112, 90, 109, 108, 106, 89, 88, 82, 108, 13, 10, 73, 69, 108, 122, 99, 51, 86, 108, 99, 116, 108, 65, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 13, 10, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 73, 68, 90, 81, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 13, 10, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 68, 99, 65, 69, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 69, 80, 70, 32, 67, 69, 82, 84, 73, 70, 73, 67, 65, 84, 69, 45, 45, 45, 45, 45, 13, 10] + vec![45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 67, 69, 82, 84, 73, 70, 73, 67, 65, 84, 69, 45, 45, 45, 45, 45, 13, 10, 107, 53, 97, 55, 83, 87, 53, 50, 89, 87, 120, 112, 90, 67, 66, 85, 90, 88, 78, 48, 97, 87, 53, 110, 73, 69, 78, 108, 99, 110, 82, 112, 90, 109, 108, 106, 89, 88, 82, 108, 65, 65, 68, 99, 65, 67, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 78, 119, 65, 73, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 103, 78, 108, 65, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 13, 10, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 78, 119, 65, 81, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 61, 13, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 69, 80, 70, 32, 67, 69, 82, 84, 73, 70, 73, 67, 65, 84, 69, 45, 45, 45, 45, 45, 13, 10] } fn null_public_key_pem() -> Vec { vec![45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 61, 13, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 69, 80, 70, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10] diff --git a/libepf/src/util.rs b/libepf/src/util.rs new file mode 100644 index 0000000..f2f5aae --- /dev/null +++ b/libepf/src/util.rs @@ -0,0 +1,12 @@ +use std::ops::Add; +use std::time::{Duration, SystemTime}; +use chrono::{DateTime, Utc}; + +pub fn pretty_print_date(date: &SystemTime) -> String { + let datetime: DateTime = (*date).into(); + datetime.format("%Y-%m-%dT%H:%M:%S%.f%:z").to_string() +} + +pub fn u64_to_st(unix: u64) -> SystemTime { + SystemTime::UNIX_EPOCH.add(Duration::from_secs(unix)) +} \ No newline at end of file diff --git a/tarpaulin-report.html b/tarpaulin-report.html index dbd85a4..ca50d5b 100644 --- a/tarpaulin-report.html +++ b/tarpaulin-report.html @@ -107,8 +107,8 @@