New structure
- [server] Reworked for new Coffer trait, common keyring implementation and tokio - [companion] Certificate generation - [common] Keyring implementation Signed-off-by: Armin Friedl <dev@friedl.net>
This commit is contained in:
parent
86212f244f
commit
076447cce7
20 changed files with 348 additions and 297 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
||||||
/target
|
**target/
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
*.cbor
|
*.cbor
|
||||||
*.yaml
|
*.yaml
|
48
Cargo.lock
generated
48
Cargo.lock
generated
|
@ -103,13 +103,16 @@ dependencies = [
|
||||||
"seckey 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"seckey 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_cbor 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_cbor 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "coffer-companion"
|
name = "coffer-companion"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"coffer-common 0.1.0",
|
||||||
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -127,13 +130,14 @@ dependencies = [
|
||||||
"coffer-common 0.1.0",
|
"coffer-common 0.1.0",
|
||||||
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_cbor 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_cbor 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"sodiumoxide 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -354,6 +358,11 @@ dependencies = [
|
||||||
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel32-sys"
|
name = "kernel32-sys"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -596,6 +605,11 @@ name = "rle-decode-fast"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "seckey"
|
name = "seckey"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
|
@ -632,6 +646,16 @@ dependencies = [
|
||||||
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_yaml"
|
name = "serde_yaml"
|
||||||
version = "0.8.11"
|
version = "0.8.11"
|
||||||
|
@ -756,7 +780,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "0.2.6"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -773,19 +797,27 @@ dependencies = [
|
||||||
"pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-macros 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "0.2.1"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
|
@ -926,6 +958,7 @@ dependencies = [
|
||||||
"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120"
|
"checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120"
|
||||||
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
|
||||||
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
|
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
|
||||||
|
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
|
"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
|
||||||
|
@ -956,10 +989,12 @@ dependencies = [
|
||||||
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
|
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
|
||||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||||
"checksum rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
|
"checksum rle-decode-fast 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
|
||||||
|
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
|
||||||
"checksum seckey 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c819d0a699db7622e4ee55a651f992242f754481f97de3024dc548adcce13237"
|
"checksum seckey 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c819d0a699db7622e4ee55a651f992242f754481f97de3024dc548adcce13237"
|
||||||
"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0"
|
"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0"
|
||||||
"checksum serde_cbor 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7081ed758ec726a6ed8ee7e92f5d3f6e6f8c3901b1f972e3a4a2f2599fad14f"
|
"checksum serde_cbor 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7081ed758ec726a6ed8ee7e92f5d3f6e6f8c3901b1f972e3a4a2f2599fad14f"
|
||||||
"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8"
|
"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8"
|
||||||
|
"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7"
|
||||||
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
|
"checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
|
||||||
"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
|
"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
|
||||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||||
|
@ -974,8 +1009,9 @@ dependencies = [
|
||||||
"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e"
|
"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e"
|
||||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||||
"checksum tokio 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1bef565a52394086ecac0a6fa3b8ace4cb3a138ee1d96bd2b93283b56824e3"
|
"checksum tokio 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "a9d5acfe1b1130d50ac2286a2f1f8cf49309680366ceb7609ce369b75c9058d4"
|
||||||
"checksum tokio-macros 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7de6c21a09bab0ce34614bb1071403ad9996db62715eb61e63be5d82f91342bc"
|
"checksum tokio-macros 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "50a61f268a3db2acee8dcab514efc813dc6dbe8a00e86076f935f94304b59a7a"
|
||||||
|
"checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf"
|
||||||
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||||
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
|
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
|
||||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||||
|
|
|
@ -12,6 +12,8 @@ log = "^0.4"
|
||||||
env_logger = "^0.7"
|
env_logger = "^0.7"
|
||||||
serde = { version = "^1.0", features = ["derive"]}
|
serde = { version = "^1.0", features = ["derive"]}
|
||||||
serde_cbor = "^0.10"
|
serde_cbor = "^0.10"
|
||||||
|
serde_json = "^1.0"
|
||||||
|
toml = "^0.5"
|
||||||
quick-error = "^1.2"
|
quick-error = "^1.2"
|
||||||
# Key management/Cryptography
|
# Key management/Cryptography
|
||||||
sodiumoxide = "^0.2"
|
sodiumoxide = "^0.2"
|
||||||
|
|
|
@ -40,6 +40,9 @@ pub struct Certificate {
|
||||||
inner: SecKey<CertificateInner>
|
inner: SecKey<CertificateInner>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for Certificate {}
|
||||||
|
unsafe impl Sync for Certificate {}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct CertificateInner {
|
struct CertificateInner {
|
||||||
public_key: box_::PublicKey,
|
public_key: box_::PublicKey,
|
||||||
|
@ -73,21 +76,19 @@ impl Certificate {
|
||||||
Ok(Certificate{inner})
|
Ok(Certificate{inner})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_cbor(&self) -> Result<Vec<u8>, CertificateError> {
|
||||||
|
let inner_cert = &*self.inner.read();
|
||||||
|
let cbor = serde_cbor::to_vec(inner_cert)?;
|
||||||
|
Ok(cbor)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn open(&self, c: &[u8]) -> Result<Vec<u8>, CertificateError> {
|
pub fn open(&self, c: &[u8]) -> Result<Vec<u8>, CertificateError> {
|
||||||
let pk = &self.inner.read().public_key;
|
let pk = &self.inner.read().public_key;
|
||||||
let sk = &self.inner.read().private_key;
|
let sk = &self.inner.read().private_key;
|
||||||
|
|
||||||
debug!{"Opening sealed box"};
|
|
||||||
sealedbox::open(c, pk, sk)
|
sealedbox::open(c, pk, sk)
|
||||||
.map_err(|_| CertificateError::Crypto)
|
.map_err(|_| CertificateError::Crypto)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn seal(&self, m: &[u8]) -> Vec<u8> {
|
|
||||||
let pk = &self.inner.read().public_key;
|
|
||||||
|
|
||||||
debug!{"Sealing box"}
|
|
||||||
sealedbox::seal(m, pk)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T: AsRef<Path>> From<T> for Certificate {
|
impl <T: AsRef<Path>> From<T> for Certificate {
|
||||||
|
|
|
@ -8,13 +8,20 @@ use quick_error::quick_error;
|
||||||
quick_error! {
|
quick_error! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CofferError {
|
pub enum CofferError {
|
||||||
Coffer
|
Msg(err: &'static str) {
|
||||||
|
from(err)
|
||||||
|
display("{}", err)
|
||||||
|
}
|
||||||
|
Other(err: Box<dyn std::error::Error>) {
|
||||||
|
cause(&**err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CofferResult<T> = Result<T, CofferError>;
|
pub type CofferResult<T> = Result<T, CofferError>;
|
||||||
|
|
||||||
/// Values supported by a `Coffer`
|
/// Values supported by a `Coffer`
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub enum CofferValue {
|
pub enum CofferValue {
|
||||||
/// A UTF-8 encoded string
|
/// A UTF-8 encoded string
|
||||||
String(String),
|
String(String),
|
||||||
|
@ -25,22 +32,33 @@ pub enum CofferValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A path to a value
|
/// A path to a value
|
||||||
|
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
|
||||||
pub struct CofferPath(Vec<String>);
|
pub struct CofferPath(Vec<String>);
|
||||||
|
|
||||||
/// Interface for interacting with a `Coffer`
|
/// Interface for interacting with a `Coffer`
|
||||||
pub trait Coffer {
|
pub trait Coffer {
|
||||||
/// Put `value` at `path`. Errors if there is already a value at `path`.
|
/// Put `value` at `path`. Errors if there is already a value at `path`.
|
||||||
fn put(path: CofferPath, value: CofferValue) -> CofferResult<()>;
|
fn put(&mut self, path: CofferPath, value: CofferValue) -> CofferResult<()>;
|
||||||
|
|
||||||
/// Push `value` to `path`. Replaces existing values silently.
|
/// Push `value` to `path`. Replaces existing values silently.
|
||||||
fn push(path: CofferPath, value: CofferValue);
|
fn push(&mut self, path: CofferPath, value: CofferValue);
|
||||||
|
|
||||||
/// Retrieve `value` at path. Errors if there is no `value` at path.
|
/// Retrieve `value` at path. Errors if there is no `value` at path.
|
||||||
fn get(path: CofferPath) -> CofferResult<CofferValue>;
|
fn get(&self, path: CofferPath) -> CofferResult<CofferValue>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T> From<&[T]> for CofferPath
|
impl <T> From<Vec<T>> for CofferPath
|
||||||
where T: AsRef<str>
|
where T: AsRef<str>
|
||||||
{
|
{
|
||||||
fn from(val: &[T]) -> Self {
|
fn from(val: Vec<T>) -> Self {
|
||||||
|
CofferPath::from(&val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <T> From<&Vec<T>> for CofferPath
|
||||||
|
where T: AsRef<str>
|
||||||
|
{
|
||||||
|
fn from(val: &Vec<T>) -> Self {
|
||||||
let col = val.iter().map(|p| {(*p).as_ref().to_owned()}).collect();
|
let col = val.iter().map(|p| {(*p).as_ref().to_owned()}).collect();
|
||||||
CofferPath(col)
|
CofferPath(col)
|
||||||
}
|
}
|
||||||
|
|
62
coffer-common/src/keyring.rs
Normal file
62
coffer-common/src/keyring.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use quick_error::quick_error;
|
||||||
|
use sodiumoxide::crypto::box_;
|
||||||
|
use sodiumoxide::crypto::sealedbox;
|
||||||
|
|
||||||
|
use crate::certificate::{Certificate, CertificateError};
|
||||||
|
|
||||||
|
quick_error! {
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum KeyringError {
|
||||||
|
UnkownClientKey
|
||||||
|
InvalidClientKey
|
||||||
|
Certificate(err: CertificateError) {
|
||||||
|
from()
|
||||||
|
}
|
||||||
|
Msg(err: &'static str) {
|
||||||
|
from(err)
|
||||||
|
display("{}", err)
|
||||||
|
}
|
||||||
|
Other(err: Box<dyn std::error::Error>) {
|
||||||
|
cause(&**err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Keyring {
|
||||||
|
certificate: Certificate,
|
||||||
|
known_keys: HashMap<Vec<u8>, box_::PublicKey>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Keyring {
|
||||||
|
pub fn new(certificate: Certificate) -> Keyring {
|
||||||
|
Keyring {
|
||||||
|
certificate: certificate,
|
||||||
|
known_keys: HashMap::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_known_key(&mut self, key: &[u8]) -> Result<(), KeyringError> {
|
||||||
|
let public_key = box_::PublicKey::from_slice(key)
|
||||||
|
.ok_or(KeyringError::InvalidClientKey)?;
|
||||||
|
|
||||||
|
self.known_keys.insert(Vec::from(key), public_key);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open(&self, message: &[u8]) -> Result<Vec<u8>, KeyringError> {
|
||||||
|
self.certificate.open(message)
|
||||||
|
.map_err(|e| KeyringError::from(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn seal(&self, client: &[u8], message: &[u8]) -> Result<Vec<u8>, KeyringError> {
|
||||||
|
let client_key = self.known_keys.get(client)
|
||||||
|
.ok_or(KeyringError::UnkownClientKey)?;
|
||||||
|
|
||||||
|
Ok(sealedbox::seal(message, client_key))
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
pub mod certificate;
|
pub mod certificate;
|
||||||
pub mod coffer;
|
pub mod coffer;
|
||||||
|
pub mod keyring;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -18,3 +18,5 @@ sodiumoxide = "0.2.5"
|
||||||
serde = { version = "1.0", features = ["derive"]}
|
serde = { version = "1.0", features = ["derive"]}
|
||||||
serde_cbor = "0.10.2"
|
serde_cbor = "0.10.2"
|
||||||
serde_yaml = "0.8"
|
serde_yaml = "0.8"
|
||||||
|
|
||||||
|
coffer-common = { path = "../coffer-common" }
|
|
@ -1,26 +0,0 @@
|
||||||
use sodiumoxide::crypto::sealedbox;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{Write};
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use crate::generate::MasterKey;
|
|
||||||
|
|
||||||
type Secrets = HashMap<String, String>;
|
|
||||||
|
|
||||||
pub fn generate_encrypted_secrets(yaml: PathBuf, out: PathBuf, masterkey: PathBuf) {
|
|
||||||
let reader = File::open(&yaml)
|
|
||||||
.expect(&format!{"Could not read file {}", masterkey.display()});
|
|
||||||
|
|
||||||
let secrets: Secrets = serde_yaml::from_reader(reader)
|
|
||||||
.expect(&format!{"Could not deserialize secrets from {}", &yaml.display()});
|
|
||||||
|
|
||||||
let masterkey: MasterKey = (&masterkey).into();
|
|
||||||
|
|
||||||
let secrets_bin = serde_cbor::to_vec(&secrets).unwrap();
|
|
||||||
let sealed_secrets_bin = sealedbox::seal(&secrets_bin, &masterkey.public_key);
|
|
||||||
|
|
||||||
File::create(&out)
|
|
||||||
.and_then(|mut f| f.write(&sealed_secrets_bin))
|
|
||||||
.expect(&format!{"Could not create out file {}", &out.display()});
|
|
||||||
}
|
|
|
@ -1,33 +1,17 @@
|
||||||
use sodiumoxide::crypto::box_;
|
use coffer_common::certificate::Certificate;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct MasterKey {
|
|
||||||
pub public_key: box_::PublicKey,
|
|
||||||
secret_key: box_::SecretKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_key(out: PathBuf) {
|
pub fn generate_key(out: PathBuf) {
|
||||||
let keypair = box_::gen_keypair();
|
let certificate = Certificate::new().unwrap();
|
||||||
let masterkey: MasterKey = MasterKey {
|
|
||||||
public_key: keypair.0,
|
|
||||||
secret_key: keypair.1,
|
|
||||||
};
|
|
||||||
|
|
||||||
let writer = File::create(&out)
|
let cert = certificate.to_cbor().unwrap();
|
||||||
|
|
||||||
|
let mut writer = File::create(&out)
|
||||||
.expect(&format!{"Could not create out file {}", &out.display()});
|
.expect(&format!{"Could not create out file {}", &out.display()});
|
||||||
|
|
||||||
serde_cbor::to_writer(writer, &masterkey)
|
writer.write_all(&cert);
|
||||||
.expect(&format!{"Couldn't deserialize to key file {}", &out.display()});
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&PathBuf> for MasterKey {
|
|
||||||
fn from(masterkey: &PathBuf) -> Self {
|
|
||||||
let reader = File::open(masterkey)
|
|
||||||
.expect(&format!{"Could not read file {}", masterkey.display()});
|
|
||||||
|
|
||||||
serde_cbor::from_reader(reader).unwrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,6 @@ fn main() {
|
||||||
|
|
||||||
match args {
|
match args {
|
||||||
Args::Generate {out} => generate::generate_key(out),
|
Args::Generate {out} => generate::generate_key(out),
|
||||||
Args::Encrypt {yaml, out, masterkey} => encrypt::generate_encrypted_secrets(yaml, out, masterkey)
|
Args::Encrypt {yaml, out, masterkey} => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,12 @@ log = "^0.4"
|
||||||
env_logger = "^0.7"
|
env_logger = "^0.7"
|
||||||
structopt = "^0.3"
|
structopt = "^0.3"
|
||||||
quick-error = "^1.2"
|
quick-error = "^1.2"
|
||||||
|
lazy_static = "^1.4"
|
||||||
|
|
||||||
# Key management/Cryptography
|
# Key management/Cryptography
|
||||||
sodiumoxide = "^0.2"
|
sodiumoxide = "^0.2"
|
||||||
# Communication
|
# Communication
|
||||||
tokio = { version="^0.2", features = ["full"]}
|
tokio = { version="^0.2.8", features = ["full"]}
|
||||||
serde = { version = "^1.0", features = ["derive"]}
|
serde = { version = "^1.0", features = ["derive"]}
|
||||||
serde_cbor = "^0.10.2"
|
serde_cbor = "^0.10.2"
|
||||||
futures = { version = "0.3.1", features = ["thread-pool"]}
|
futures = { version = "0.3.1", features = ["thread-pool"]}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
#[allow(unused_imports)]
|
|
||||||
use log::{debug, error, info, trace, warn};
|
|
||||||
|
|
||||||
use coffer_common::certificate::Certificate;
|
|
||||||
|
|
||||||
pub struct Coffer {
|
|
||||||
certificate: Certificate,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Coffer {
|
|
||||||
/// Create a new, empty `Coffer` with a generated certificate
|
|
||||||
pub fn new() -> Coffer {
|
|
||||||
Coffer {certificate: Certificate::new()}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new `Coffer` with certificate
|
|
||||||
pub fn new_with_certificate (certificate: Certificate) {
|
|
||||||
Coffer {certificate.into()}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
#[allow(unused_imports)]
|
|
||||||
use log::{debug, error, info, trace, warn};
|
|
||||||
use quick_error::quick_error;
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use sodiumoxide::crypto::sealedbox;
|
|
||||||
use sodiumoxide::crypto::box_;
|
|
||||||
|
|
||||||
quick_error! {
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum KeyringError {
|
|
||||||
Io(err: std::io::Error) {
|
|
||||||
from()
|
|
||||||
}
|
|
||||||
Cbor(err: serde_cbor::Error) {
|
|
||||||
from()
|
|
||||||
}
|
|
||||||
Crypto
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct MasterKey {
|
|
||||||
public_key: box_::PublicKey,
|
|
||||||
secret_key: box_::SecretKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MasterKey {
|
|
||||||
pub fn decrypt(&self, c: &[u8]) -> Result<Vec<u8>, KeyringError> {
|
|
||||||
sealedbox::open(c, &self.public_key, &self.secret_key)
|
|
||||||
.map_err(|_| KeyringError::Crypto)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encrypt(&self, m: &[u8]) -> Vec<u8> {
|
|
||||||
sealedbox::seal(m, &self.public_key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct ClientKey {
|
|
||||||
id: String,
|
|
||||||
public_key: box_::PublicKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Keyring {
|
|
||||||
pub master: MasterKey,
|
|
||||||
pub clients: HashMap<String, ClientKey>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Keyring {
|
|
||||||
pub fn new_from_path(path: &PathBuf) -> Result<Keyring, KeyringError> {
|
|
||||||
let keyring = Keyring {
|
|
||||||
master: key_from_path(path)?,
|
|
||||||
clients: HashMap::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(keyring)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_key_from_path(&mut self, path: &PathBuf, keep: bool) -> Result<(), KeyringError> {
|
|
||||||
let client_key: ClientKey = key_from_path(path)?;
|
|
||||||
self.clients.insert(client_key.id.clone(), client_key);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn key_from_path<T>(path: &PathBuf) -> Result<T, KeyringError>
|
|
||||||
where T: serde::de::DeserializeOwned
|
|
||||||
{
|
|
||||||
|
|
||||||
let mk_file = File::open(path)?;
|
|
||||||
let key = serde_cbor::from_reader(mk_file)?;
|
|
||||||
|
|
||||||
Ok(key)
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
#[allow(unused_imports)]
|
|
||||||
use log::{debug, error, info, trace, warn};
|
|
||||||
use quick_error::quick_error;
|
|
||||||
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Read;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
// do not provide a path to keyring through coffer module. keyring is hence
|
|
||||||
// effectively private outside coffer
|
|
||||||
mod keyring;
|
|
||||||
use keyring::Keyring;
|
|
||||||
|
|
||||||
quick_error! {
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum CofferError {
|
|
||||||
Keyring(err: keyring::KeyringError) {
|
|
||||||
from()}
|
|
||||||
Io(err: std::io::Error) {
|
|
||||||
from()
|
|
||||||
}
|
|
||||||
Cbor(err: serde_cbor::Error) {
|
|
||||||
from()
|
|
||||||
}
|
|
||||||
Coffer(err: &'static str) {
|
|
||||||
from()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, CofferError>;
|
|
||||||
type Secrets = HashMap<String, String>; // move this to a module if it gathers crust
|
|
||||||
|
|
52
coffer-server/src/coffer_map.rs
Normal file
52
coffer-server/src/coffer_map.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
//! A simple, thread-safe coffer implementation backed by a hash map
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
use std::sync::RwLock;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use coffer_common::coffer::*;
|
||||||
|
|
||||||
|
pub struct CofferMap {
|
||||||
|
coffer: RwLock<HashMap<CofferPath, CofferValue>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CofferMap {
|
||||||
|
pub fn new() -> CofferMap {
|
||||||
|
CofferMap {
|
||||||
|
coffer: RwLock::new(HashMap::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Coffer for CofferMap {
|
||||||
|
fn put(&mut self, path: CofferPath, value: CofferValue) -> CofferResult<()> {
|
||||||
|
let mut lock = self.coffer.write().unwrap();
|
||||||
|
|
||||||
|
match (*lock).contains_key(&path) {
|
||||||
|
true => Err(CofferError::Msg("test")),
|
||||||
|
false => {(*lock).insert(path, value); Ok(())}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, path: CofferPath, value: CofferValue) {
|
||||||
|
let mut lock = self.coffer.write().unwrap();
|
||||||
|
|
||||||
|
(*lock).insert(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, path: CofferPath) -> CofferResult<CofferValue> {
|
||||||
|
let lock = self.coffer.read().unwrap();
|
||||||
|
|
||||||
|
(*lock).get(&path)
|
||||||
|
.and_then(|v| Some(v.clone()))
|
||||||
|
.ok_or(CofferError::Msg("Key not found"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CofferMap {
|
||||||
|
fn default() -> Self {
|
||||||
|
CofferMap::new()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,62 +0,0 @@
|
||||||
#[allow(unused_imports)]
|
|
||||||
use log::{debug, error, info, trace, warn};
|
|
||||||
|
|
||||||
use std::net::{TcpListener, SocketAddr, TcpStream};
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::io::{Write};
|
|
||||||
use std::io::Read;
|
|
||||||
use futures::executor::ThreadPool;
|
|
||||||
|
|
||||||
use crate::coffer::Coffer;
|
|
||||||
|
|
||||||
pub struct Channel {
|
|
||||||
pub executor: ThreadPool,
|
|
||||||
pub address: SocketAddr,
|
|
||||||
pub coffer: Arc<Coffer>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Channel {
|
|
||||||
pub fn listen(self) {
|
|
||||||
|
|
||||||
let listener:TcpListener = TcpListener::bind(self.address).unwrap();
|
|
||||||
|
|
||||||
listener.incoming().for_each(|inc| {
|
|
||||||
match inc {
|
|
||||||
Ok(tcp_stream) => self.executor.spawn_ok(handler(tcp_stream, self.coffer.clone())),
|
|
||||||
Err(e) => error!{"Failed binding incoming connection {}", e}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn handler(mut stream: TcpStream, coffer: Arc<Coffer>) {
|
|
||||||
let mut peek_buf = [0x00; 1];
|
|
||||||
|
|
||||||
while stream.peek(&mut peek_buf).unwrap() != 0 {
|
|
||||||
let mut len_buffer = [0x00; std::mem::size_of::<usize>()];
|
|
||||||
stream.read_exact(&mut len_buffer);
|
|
||||||
let len = usize::from_be_bytes(len_buffer) as u64;
|
|
||||||
debug!{"Length {}", len}
|
|
||||||
|
|
||||||
let mut buf: Vec<u8> = Vec::with_capacity(len as usize);
|
|
||||||
let mut handle = (&stream).take(len);
|
|
||||||
handle.read_to_end(&mut buf);
|
|
||||||
debug!{"Read vec {:?}", buf};
|
|
||||||
|
|
||||||
let res: Result<String, serde_cbor::Error> = serde_cbor::from_slice(&buf);
|
|
||||||
|
|
||||||
match res {
|
|
||||||
Ok(request) => {
|
|
||||||
if let Ok(secret) = coffer.get_secret(&request) {
|
|
||||||
writeln!(stream, "{}", secret)
|
|
||||||
.unwrap_or_else(|err| {error!{"Could not write key response to stream {}", err}});
|
|
||||||
debug!{"Wrote {:?}", secret}
|
|
||||||
} else {
|
|
||||||
writeln!(stream, "")
|
|
||||||
.unwrap_or_else(|err| {error!{"Could not write key response to stream {}", err}})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => error!{"Could not parse secret request: {}", e}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,20 +3,18 @@ use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
use env_logger;
|
use env_logger;
|
||||||
|
|
||||||
use std::convert::TryInto;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use std::net::IpAddr;
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use tokio::prelude::*;
|
use coffer_common::certificate::Certificate;
|
||||||
|
use coffer_common::keyring::Keyring;
|
||||||
|
|
||||||
mod coffer;
|
|
||||||
mod server;
|
mod server;
|
||||||
mod comm;
|
mod coffer_map;
|
||||||
|
|
||||||
use comm::Channel;
|
use server::ServerBuilder;
|
||||||
|
use coffer_map::CofferMap;
|
||||||
|
|
||||||
#[derive(StructOpt, Debug)]
|
#[derive(StructOpt, Debug)]
|
||||||
struct Args {
|
struct Args {
|
||||||
|
@ -29,13 +27,9 @@ struct Args {
|
||||||
#[structopt(short, long, parse(from_os_str), env = "COFFER_SERVER_SECRETS", hide_env_values = true)]
|
#[structopt(short, long, parse(from_os_str), env = "COFFER_SERVER_SECRETS", hide_env_values = true)]
|
||||||
secrets: Option<PathBuf>,
|
secrets: Option<PathBuf>,
|
||||||
|
|
||||||
/// Port the coffer server listens on
|
/// Address the coffer server should bind to
|
||||||
#[structopt(short, long, env = "COFFER_SERVER_PORT", default_value = "9187")]
|
|
||||||
port: u16,
|
|
||||||
|
|
||||||
/// Address coffer server should bind to
|
|
||||||
#[structopt(short, long, parse(try_from_str), env = "COFFER_SERVER_ADDRESS", default_value = "127.0.0.1:9187")]
|
#[structopt(short, long, parse(try_from_str), env = "COFFER_SERVER_ADDRESS", default_value = "127.0.0.1:9187")]
|
||||||
ip: SocketAddr,
|
address: SocketAddr,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -45,9 +39,13 @@ async fn main() {
|
||||||
|
|
||||||
_print_banner();
|
_print_banner();
|
||||||
|
|
||||||
info!{"Filling coffer"}
|
let server = ServerBuilder::new()
|
||||||
let coffer = coffer::Coffer::new_from_path_encrypted(&args.master, &args.secrets)
|
.with_keyring(args.certificate.and_then(|cert_path| Some(Keyring::new(Certificate::from(cert_path)))))
|
||||||
.expect("Could not fill coffer");
|
.with_coffer(Some(CofferMap::new()))
|
||||||
|
.build()
|
||||||
|
.expect("Couldn't build server");
|
||||||
|
|
||||||
|
server.run(args.address).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _print_banner() {
|
fn _print_banner() {
|
||||||
|
|
127
coffer-server/src/server.rs
Normal file
127
coffer-server/src/server.rs
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
use quick_error::quick_error;
|
||||||
|
|
||||||
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
|
use tokio::stream::StreamExt;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
|
use std::net::{ToSocketAddrs, SocketAddr};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use coffer_common::keyring::Keyring;
|
||||||
|
use coffer_common::coffer::Coffer;
|
||||||
|
use coffer_common::certificate::{Certificate, CertificateError};
|
||||||
|
|
||||||
|
quick_error! {
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ServerError {
|
||||||
|
Cert(err: CertificateError) {
|
||||||
|
from()
|
||||||
|
}
|
||||||
|
Msg(err: &'static str) {
|
||||||
|
from(err)
|
||||||
|
display("{}", err)
|
||||||
|
}
|
||||||
|
Other(err: Box<dyn std::error::Error>) {
|
||||||
|
cause(&**err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Server<C>
|
||||||
|
where C: Coffer
|
||||||
|
{
|
||||||
|
keyring: Arc<RwLock<Keyring>>,
|
||||||
|
coffer: Arc<RwLock<C>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <C> Server<C>
|
||||||
|
where C: Coffer + Send + Sync + 'static
|
||||||
|
{
|
||||||
|
pub async fn run<T>(self, addr: T)
|
||||||
|
where T: ToSocketAddrs
|
||||||
|
{
|
||||||
|
debug!{"Building socket"}
|
||||||
|
let socket: SocketAddr = addr
|
||||||
|
.to_socket_addrs()
|
||||||
|
.expect("Could not convert to socket")
|
||||||
|
.next()
|
||||||
|
.expect("No socket could be built");
|
||||||
|
|
||||||
|
debug!{"Binding to socket {:?}", socket}
|
||||||
|
let mut listener = TcpListener::bind(socket).await
|
||||||
|
.expect(format!{"Could not bind to socket {}", socket}.as_str());
|
||||||
|
|
||||||
|
let server = async move {
|
||||||
|
let mut incoming = listener.incoming();
|
||||||
|
|
||||||
|
debug!{"Starting connection loop"}
|
||||||
|
while let Some(connection) = incoming.next().await {
|
||||||
|
debug!{"New incoming connection"}
|
||||||
|
match connection {
|
||||||
|
Ok(mut tcp_stream) => {
|
||||||
|
debug!{"Connection ok"}
|
||||||
|
debug!{"Spawning off connection handler"}
|
||||||
|
|
||||||
|
let keyring = self.keyring.clone();
|
||||||
|
let coffer = self.coffer.clone();
|
||||||
|
tokio::spawn(Self::handle_connection(keyring, coffer, tcp_stream));
|
||||||
|
}
|
||||||
|
Err(err) => error!{"Connection could not be established {}", err}
|
||||||
|
}
|
||||||
|
debug!{"Waiting for new connections"}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
server.await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle_connection(keyring: Arc<RwLock<Keyring>>,
|
||||||
|
coffer: Arc<RwLock<C>>,
|
||||||
|
mut tcp_stream: TcpStream)
|
||||||
|
{
|
||||||
|
let (reader, mut writer) = tcp_stream.split();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ServerBuilder<C>
|
||||||
|
where C: Coffer
|
||||||
|
{
|
||||||
|
keyring: Option<Keyring>,
|
||||||
|
coffer: Option<C>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <'a, C> ServerBuilder<C>
|
||||||
|
where C: Coffer + Default
|
||||||
|
{
|
||||||
|
pub fn new() -> ServerBuilder<C> {
|
||||||
|
ServerBuilder {
|
||||||
|
keyring: None,
|
||||||
|
coffer: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_keyring(mut self, keyring: Option<Keyring>) -> ServerBuilder<C> {
|
||||||
|
self.keyring = keyring;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_coffer(mut self, coffer: Option<C>) -> ServerBuilder<C> {
|
||||||
|
self.coffer = coffer;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(self) -> Result<Server<C>, ServerError> {
|
||||||
|
let keyring = match self.keyring {
|
||||||
|
Some(k) => Arc::new(RwLock::new(k)),
|
||||||
|
None => {let cert = Certificate::new()?;
|
||||||
|
Arc::new(RwLock::new(Keyring::new(cert)))}
|
||||||
|
};
|
||||||
|
|
||||||
|
let coffer = Arc::new(RwLock::new(self.coffer.unwrap_or_else(|| { C::default() } )));
|
||||||
|
|
||||||
|
Ok(Server {keyring, coffer})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
//! Public APIs for `coffer-server`
|
|
||||||
|
|
||||||
use std::net::ToSocketAddrs;
|
|
||||||
|
|
||||||
use tokio::prelude::*;
|
|
||||||
use tokio::net::TcpListener;
|
|
||||||
|
|
||||||
async fn run_server<T: ToSocketAddrs>(sock_addrs: T) {
|
|
||||||
let addr = sock_addrs.to_socket_addrs().unwrap().next().unwrap();
|
|
||||||
let listener = TcpListener::bind(addr);
|
|
||||||
}
|
|
Loading…
Reference in a new issue