feat: v1.4.0 add cmd_pgpcardserve.rs

This commit is contained in:
2022-07-01 00:14:27 +08:00
parent 5aadb3f082
commit 00dee7b000
5 changed files with 547 additions and 5 deletions

406
Cargo.lock generated
View File

@@ -277,6 +277,16 @@ dependencies = [
"arrayvec",
]
[[package]]
name = "buf_redux"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
dependencies = [
"memchr",
"safemem",
]
[[package]]
name = "buffered-reader"
version = "1.1.2"
@@ -366,7 +376,7 @@ dependencies = [
[[package]]
name = "card-cli"
version = "1.3.3"
version = "1.4.0"
dependencies = [
"authenticator",
"base64 0.13.0",
@@ -384,12 +394,15 @@ dependencies = [
"rust_util",
"sequoia-openpgp",
"serde",
"serde_derive",
"serde_json",
"sha1",
"sha2 0.10.2",
"simpledateformat",
"ssh-agent",
"tokio 1.18.0",
"u2f",
"warp",
"x509",
"x509-parser 0.13.2",
"yubico_manager",
@@ -898,6 +911,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
dependencies = [
"matches",
"percent-encoding",
]
[[package]]
name = "fs2"
version = "0.4.3"
@@ -1078,12 +1101,56 @@ dependencies = [
"subtle",
]
[[package]]
name = "h2"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57"
dependencies = [
"bytes 1.1.0",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http",
"indexmap",
"slab",
"tokio 1.18.0",
"tokio-util 0.7.2",
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "headers"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d"
dependencies = [
"base64 0.13.0",
"bitflags",
"bytes 1.1.0",
"headers-core",
"http",
"httpdate",
"mime",
"sha-1 0.10.0",
]
[[package]]
name = "headers-core"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
dependencies = [
"http",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
@@ -1115,12 +1182,70 @@ dependencies = [
"digest 0.9.0",
]
[[package]]
name = "http"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
dependencies = [
"bytes 1.1.0",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes 1.1.0",
"http",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
[[package]]
name = "httpdate"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyper"
version = "0.14.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f"
dependencies = [
"bytes 1.1.0",
"futures-channel",
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"httparse",
"httpdate",
"itoa",
"pin-project-lite",
"socket2 0.4.4",
"tokio 1.18.0",
"tower-service",
"tracing",
"want",
]
[[package]]
name = "idna"
version = "0.2.3"
@@ -1377,6 +1502,22 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ac78937f19a0c7807e45a931eac41f766f210173ec664ec046d58e6d388a5cb"
[[package]]
name = "mime"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "mime_guess"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
dependencies = [
"mime",
"unicase",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@@ -1457,6 +1598,24 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "multipart"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182"
dependencies = [
"buf_redux",
"httparse",
"log",
"mime",
"mime_guess",
"quick-error",
"rand 0.8.5",
"safemem",
"tempfile",
"twoway",
]
[[package]]
name = "net2"
version = "0.2.37"
@@ -1868,6 +2027,12 @@ dependencies = [
"base64ct",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "petgraph"
version = "0.5.1"
@@ -1893,6 +2058,26 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
[[package]]
name = "pin-project"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
dependencies = [
"proc-macro2",
"quote 1.0.18",
"syn",
]
[[package]]
name = "pin-project-lite"
version = "0.2.9"
@@ -2221,6 +2406,18 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
[[package]]
name = "safemem"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
[[package]]
name = "scoped-tls"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "scopeguard"
version = "1.1.0"
@@ -2275,7 +2472,7 @@ dependencies = [
"tempfile",
"thiserror",
"tokio 1.18.0",
"tokio-util",
"tokio-util 0.6.9",
"winapi 0.3.9",
]
@@ -2340,6 +2537,18 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha-1"
version = "0.9.8"
@@ -2353,6 +2562,17 @@ dependencies = [
"opaque-debug",
]
[[package]]
name = "sha-1"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
"digest 0.10.3",
]
[[package]]
name = "sha1"
version = "0.6.1"
@@ -2845,6 +3065,17 @@ dependencies = [
"tokio-sync",
]
[[package]]
name = "tokio-stream"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio 1.18.0",
]
[[package]]
name = "tokio-sync"
version = "0.1.8"
@@ -2898,6 +3129,19 @@ dependencies = [
"tokio-executor",
]
[[package]]
name = "tokio-tungstenite"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8"
dependencies = [
"futures-util",
"log",
"pin-project",
"tokio 1.18.0",
"tungstenite",
]
[[package]]
name = "tokio-udp"
version = "0.1.6"
@@ -2946,6 +3190,93 @@ dependencies = [
"tokio 1.18.0",
]
[[package]]
name = "tokio-util"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c"
dependencies = [
"bytes 1.1.0",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio 1.18.0",
"tracing",
]
[[package]]
name = "tower-service"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
dependencies = [
"cfg-if 1.0.0",
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
dependencies = [
"proc-macro2",
"quote 1.0.18",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f"
dependencies = [
"lazy_static",
]
[[package]]
name = "try-lock"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
[[package]]
name = "tungstenite"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5"
dependencies = [
"base64 0.13.0",
"byteorder",
"bytes 1.1.0",
"http",
"httparse",
"log",
"rand 0.8.5",
"sha-1 0.9.8",
"thiserror",
"url",
"utf-8",
]
[[package]]
name = "twoway"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
dependencies = [
"memchr",
]
[[package]]
name = "typenum"
version = "1.15.0"
@@ -2969,6 +3300,15 @@ dependencies = [
"time 0.1.43",
]
[[package]]
name = "unicase"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.8"
@@ -3008,6 +3348,24 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
dependencies = [
"form_urlencoded",
"idna",
"matches",
"percent-encoding",
]
[[package]]
name = "utf-8"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "uuid"
version = "0.8.2"
@@ -3035,6 +3393,46 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "want"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
dependencies = [
"log",
"try-lock",
]
[[package]]
name = "warp"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cef4e1e9114a4b7f1ac799f16ce71c14de5778500c5450ec6b7b920c55b587e"
dependencies = [
"bytes 1.1.0",
"futures-channel",
"futures-util",
"headers",
"http",
"hyper",
"log",
"mime",
"mime_guess",
"multipart",
"percent-encoding",
"pin-project",
"scoped-tls",
"serde",
"serde_json",
"serde_urlencoded",
"tokio 1.18.0",
"tokio-stream",
"tokio-tungstenite",
"tokio-util 0.6.9",
"tower-service",
"tracing",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
@@ -3276,7 +3674,7 @@ dependencies = [
"hmac",
"rand 0.8.5",
"rusb",
"sha-1",
"sha-1 0.9.8",
"structure",
]
@@ -3304,7 +3702,7 @@ dependencies = [
"rand_core 0.6.3",
"rsa",
"secrecy",
"sha-1",
"sha-1 0.9.8",
"sha2 0.9.9",
"subtle",
"subtle-encoding",

View File

@@ -1,6 +1,6 @@
[package]
name = "card-cli"
version = "1.3.3"
version = "1.4.0"
authors = ["Hatter Jiang <jht5945@gmail.com>"]
edition = "2018"
@@ -31,6 +31,9 @@ yubico_manager = "0.9"
x509 = "0.2"
x509-parser = "0.13"
ssh-agent = { version = "0.2.3", features = ["agent"] }
tokio = { version = "1", features = ["full"] }
serde_derive = "1.0"
warp = "0.3"
#lazy_static = "1.4.0"
#ssh-key = "0.4.0"
#ctap-hid-fido2 = "2.1.3"

127
src/cmd_pgpcardserve.rs Normal file
View File

@@ -0,0 +1,127 @@
use std::collections::HashMap;
use clap::{App, Arg, ArgMatches, SubCommand};
use openpgp_card::OpenPgp;
use rust_util::util_clap::{Command, CommandError};
use serde_derive::{Deserialize, Serialize};
use warp::Filter;
use warp::reply::{Json, json};
pub struct CommandImpl;
impl Command for CommandImpl {
fn name(&self) -> &str { "pgp-card-serve" }
fn subcommand<'a>(&self) -> App<'a, 'a> {
SubCommand::with_name(self.name()).about("OpenPGP Card Decrypt subcommand")
.arg(Arg::with_name("pin").short("p").long("pin").takes_value(true).default_value("123456").help("OpenPGP card user pin"))
.arg(Arg::with_name("pass").long("pass").takes_value(true).help("[deprecated] now OpenPGP card user pin"))
.arg(Arg::with_name("listen").short("l").long("listen").takes_value(true).default_value("127.0.0.1:3627").help("Listen address"))
// .arg(Arg::with_name("ssh-attach-host").long("ssh-attach-host").takes_value(true).help("SSH attache (e.g. root@example.com)"))
}
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
let pin_opt = sub_arg_matches.value_of("pass").or_else(|| sub_arg_matches.value_of("pin"));
let pin = opt_value_result!(pin_opt, "User pin must be assigned");
if pin.len() < 6 { return simple_error!("User pin length:{}, must >= 6!", pin.len()); }
let mut card = crate::pgpcardutil::get_card()?;
let mut pgp = OpenPgp::new(&mut card);
let mut trans = opt_result!(pgp.transaction(), "Open card failed: {}");
opt_result!(trans.verify_pw1_user(pin.as_ref()), "User pin verify failed: {}");
success!("User pin verify success!");
// let cipher = sub_arg_matches.value_of("cipher");
// let cipher_base64 = sub_arg_matches.value_of("cipher-base64");
//
// let cipher_bytes = if let Some(cipher) = cipher {
// opt_result!(hex::decode(cipher), "Decode cipher failed: {}")
// } else if let Some(cipher_base64) = cipher_base64 {
// opt_result!(base64::decode(cipher_base64), "Decode cipher-base64 failed: {}")
// } else {
// return simple_error!("cipher or cipher-base64 must assign one");
// };
//
// let text = trans.decipher(Cryptogram::RSA(&cipher_bytes))?;
// success!("Clear text HEX: {}", hex::encode(&text));
// success!("Clear text base64: {}", base64::encode(&text));
// success!("Clear text UTF-8: {}", String::from_utf8_lossy(&text));
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let version = warp::get().and(warp::path("version")).map(|| {
let mut version = HashMap::new();
version.insert("version", env!("CARGO_PKG_VERSION"));
warp::reply::json(&version)
});
let create_key = warp::post()
.and(warp::path("create_key"))
.and(warp::body::json())
.map(|create_key_request: CreateKeyRequest| {
let len = create_key_request.len.unwrap_or(32);
if (len < 16) || (len > 1024) {
return ErrResponse::new(400, format!("Invalid length:{}", len));
}
let key = crate::randutil::make_rand(len);
json(&CreateKeyResponse {
request_pub_key_encrypted_key_hex: None,
raw_key_hex: Some(hex::encode(&key)),
encrypted_key_hex: "".to_string(),
})
});
information!("Serve at :3030");
let routes = version.or(create_key);
warp::serve(routes)
.run(([127, 0, 0, 1], 3030))
.await;
});
Ok(None)
}
}
trait ErrorResponseMessage {
fn to_option_string(self) -> Option<String>;
}
impl ErrorResponseMessage for &str {
fn to_option_string(self) -> Option<String> {
Some(self.to_string())
}
}
impl ErrorResponseMessage for String {
fn to_option_string(self) -> Option<String> {
Some(self)
}
}
#[derive(Deserialize, Serialize)]
struct ErrResponse {
code: i32,
message: Option<String>,
}
impl ErrResponse {
fn new(code: i32, message: impl ErrorResponseMessage) -> Json {
json(&ErrResponse {
code,
message: message.to_option_string(),
})
}
}
#[derive(Deserialize, Serialize)]
struct CreateKeyRequest {
len: Option<usize>,
request_pub_key_hex: Option<String>,
}
#[derive(Deserialize, Serialize)]
struct CreateKeyResponse {
request_pub_key_encrypted_key_hex: Option<String>,
raw_key_hex: Option<String>,
encrypted_key_hex: String,
}

View File

@@ -9,6 +9,7 @@ mod fido;
mod digest;
mod rsautil;
mod pkiutil;
mod randutil;
mod pgpcardutil;
mod cmd_u2fregister;
mod cmd_u2fsign;
@@ -20,6 +21,7 @@ mod cmd_pgpcardadmin;
mod cmd_pgpcardlist;
mod cmd_pgpcardsign;
mod cmd_pgpcarddecrypt;
mod cmd_pgpcardserve;
mod cmd_pgpcardmake;
mod cmd_piv;
mod cmd_pivsign;
@@ -59,6 +61,7 @@ fn inner_main() -> CommandError {
Box::new(cmd_pgpcardlist::CommandImpl),
Box::new(cmd_pgpcardsign::CommandImpl),
Box::new(cmd_pgpcarddecrypt::CommandImpl),
Box::new(cmd_pgpcardserve::CommandImpl),
Box::new(cmd_pgpcardmake::CommandImpl),
Box::new(cmd_piv::CommandImpl),
Box::new(cmd_pivsign::CommandImpl),

11
src/randutil.rs Normal file
View File

@@ -0,0 +1,11 @@
use rand::Rng;
pub fn make_rand(len: usize) -> Vec<u8> {
let mut rng = rand::thread_rng();
let mut r = Vec::new();
for _ in 0..len {
let b: u8 = rng.gen();
r.push(b);
}
r
}