summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko <heiko@schaefer.name>2021-05-07 12:46:53 +0200
committerHeiko <heiko@schaefer.name>2021-05-07 12:47:44 +0200
commitf581d1be5ae7c7d2d9abdfbfa2af4feef1d6e46f (patch)
tree5634268fd699abf622766a6b805bb4a7c0b35c91
parente0d66ddf4a36d391546c70e73b592c530721260a (diff)
downloadopenpgp-ca-f581d1be5ae7c7d2d9abdfbfa2af4feef1d6e46f.tar.gz
Move gnupg wrapper into its own crate "gnupg-test-wrapper".
-rw-r--r--Cargo.lock17
-rw-r--r--Cargo.toml1
-rw-r--r--gnupg-test-wrapper/Cargo.toml19
-rw-r--r--gnupg-test-wrapper/src/lib.rs (renamed from openpgp-ca-lib/tests/gnupg/mod.rs)4
-rw-r--r--openpgp-ca-lib/Cargo.toml3
-rw-r--r--openpgp-ca-lib/tests/test_gpg.rs2
-rw-r--r--openpgp-ca-lib/tests/test_oca.rs2
-rw-r--r--openpgp-ca-restd/Cargo.toml4
-rw-r--r--openpgp-ca-restd/tests/gnupg/mod.rs544
-rw-r--r--openpgp-ca-restd/tests/test_restd.rs3
10 files changed, 39 insertions, 560 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3e29be3..2042c10 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1025,6 +1025,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
+name = "gnupg-test-wrapper"
+version = "0.0.1"
+dependencies = [
+ "anyhow",
+ "csv",
+ "rexpect",
+ "tempfile",
+]
+
+[[package]]
name = "h2"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1749,12 +1759,11 @@ dependencies = [
"anyhow",
"chbs",
"chrono",
- "csv",
"diesel",
"diesel_migrations",
+ "gnupg-test-wrapper",
"openpgp-keylist",
"publicsuffix",
- "rexpect",
"sequoia-net",
"sequoia-openpgp",
"sha2",
@@ -1769,18 +1778,16 @@ dependencies = [
"anyhow",
"chrono",
"clap",
- "csv",
+ "gnupg-test-wrapper",
"once_cell",
"openpgp-ca-lib",
"reqwest 0.10.10",
- "rexpect",
"rocket",
"rocket_contrib",
"sequoia-openpgp",
"serde",
"serde_json",
"structopt",
- "tempfile",
"tokio 0.2.25",
]
diff --git a/Cargo.toml b/Cargo.toml
index c0a0636..d52329b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,4 +6,5 @@ members = [
"openpgp-ca-lib",
"openpgp-ca-bin",
"openpgp-ca-restd",
+ "gnupg-test-wrapper",
]
diff --git a/gnupg-test-wrapper/Cargo.toml b/gnupg-test-wrapper/Cargo.toml
new file mode 100644
index 0000000..3f52c3b
--- /dev/null
+++ b/gnupg-test-wrapper/Cargo.toml
@@ -0,0 +1,19 @@
+# SPDX-FileCopyrightText: 2019-2021 Heiko Schaefer <heiko@schaefer.name>
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[package]
+name = "gnupg-test-wrapper"
+version = "0.0.1"
+description = "A wrapper for using GnuPG in integration tests. Don't use for security critical purposes!"
+authors = ["Heiko Schaefer <heiko@schaefer.name>"]
+license = "GPL-3.0-or-later"
+categories = ["cryptography", "email"]
+keywords = ["OpenPGP", "GnuPG", "PGP"]
+repository = "https://gitlab.com/openpgp-ca/openpgp-ca"
+edition = "2018"
+
+[dependencies]
+anyhow = "1.0"
+tempfile = "3.1"
+rexpect = "0.4"
+csv = "1.1"
diff --git a/openpgp-ca-lib/tests/gnupg/mod.rs b/gnupg-test-wrapper/src/lib.rs
index 6eb9c5b..9beb341 100644
--- a/openpgp-ca-lib/tests/gnupg/mod.rs
+++ b/gnupg-test-wrapper/src/lib.rs
@@ -1,9 +1,9 @@
-// Copyright 2019-2020 Heiko Schaefer <heiko@schaefer.name>
+// Copyright 2019-2021 Heiko Schaefer <heiko@schaefer.name>
//
// This file is part of OpenPGP CA
// https://gitlab.com/openpgp-ca/openpgp-ca
//
-// SPDX-FileCopyrightText: 2019-2020 Heiko Schaefer <heiko@schaefer.name>
+// SPDX-FileCopyrightText: 2019-2021 Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: GPL-3.0-or-later
use std::collections::BTreeMap;
diff --git a/openpgp-ca-lib/Cargo.toml b/openpgp-ca-lib/Cargo.toml
index 8fabe52..5cab6da 100644
--- a/openpgp-ca-lib/Cargo.toml
+++ b/openpgp-ca-lib/Cargo.toml
@@ -39,6 +39,5 @@ sequoia-net = "0.23"
# for tests
[dev-dependencies]
+gnupg-test-wrapper = { path = "../gnupg-test-wrapper" }
tempfile = "3.1"
-csv = "1.1"
-rexpect = "0.4"
diff --git a/openpgp-ca-lib/tests/test_gpg.rs b/openpgp-ca-lib/tests/test_gpg.rs
index cb63488..fb67328 100644
--- a/openpgp-ca-lib/tests/test_gpg.rs
+++ b/openpgp-ca-lib/tests/test_gpg.rs
@@ -15,7 +15,7 @@ use openpgp_ca_lib::pgp::Pgp;
use anyhow::{Context, Result};
use std::path::PathBuf;
-pub mod gnupg;
+use gnupg_test_wrapper as gnupg;
#[test]
/// Create a new CA. Create user certs for Alice and Bob in OpenPGP CA.
diff --git a/openpgp-ca-lib/tests/test_oca.rs b/openpgp-ca-lib/tests/test_oca.rs
index 8132e68..a269490 100644
--- a/openpgp-ca-lib/tests/test_oca.rs
+++ b/openpgp-ca-lib/tests/test_oca.rs
@@ -25,7 +25,7 @@ use openpgp_ca_lib::ca::OpenpgpCa;
use openpgp_ca_lib::pgp::Pgp;
use sequoia_net::Policy;
-pub mod gnupg;
+use gnupg_test_wrapper as gnupg;
#[test]
/// Creates a CA (with a custom name) and a user.
diff --git a/openpgp-ca-restd/Cargo.toml b/openpgp-ca-restd/Cargo.toml
index e0d3dcc..478a59a 100644
--- a/openpgp-ca-restd/Cargo.toml
+++ b/openpgp-ca-restd/Cargo.toml
@@ -46,6 +46,4 @@ features = ["fs", "io-std", "io-util", "rt-threaded", "sync", "signal", "macros"
# for tests
[dev-dependencies]
-tempfile = "3.1"
-csv = "1.1"
-rexpect = "0.4"
+gnupg-test-wrapper = { path = "../gnupg-test-wrapper" } \ No newline at end of file
diff --git a/openpgp-ca-restd/tests/gnupg/mod.rs b/openpgp-ca-restd/tests/gnupg/mod.rs
deleted file mode 100644
index 6eb9c5b..0000000
--- a/openpgp-ca-restd/tests/gnupg/mod.rs
+++ /dev/null
@@ -1,544 +0,0 @@
-// Copyright 2019-2020 Heiko Schaefer <heiko@schaefer.name>
-//
-// This file is part of OpenPGP CA
-// https://gitlab.com/openpgp-ca/openpgp-ca
-//
-// SPDX-FileCopyrightText: 2019-2020 Heiko Schaefer <heiko@schaefer.name>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-use std::collections::BTreeMap;
-use std::collections::HashMap;
-
-use std::fmt;
-use std::io::Read;
-use std::io::Write;
-use std::path::{Path, PathBuf};
-use std::process::Command;
-use std::process::Stdio;
-
-use anyhow::{Context, Result};
-use csv::StringRecord;
-
-// FIXME: `LC_ALL=C` to make calls locale-independent
-
-pub fn make_context() -> Result<Ctx> {
- let ctx = Ctx::ephemeral().context(
- "SKIP: Failed to create GnuPG context. Is GnuPG installed?",
- )?;
-
- ctx.start("gpg-agent").context(
- "SKIP: Failed to to start gpg-agent. Is the GnuPG agent installed?",
- )?;
-
- Ok(ctx)
-}
-
-/// A GnuPG context.
-#[derive(Debug)]
-pub struct Ctx {
- homedir: Option<PathBuf>,
- components: BTreeMap<String, PathBuf>,
- directories: BTreeMap<String, PathBuf>,
- sockets: BTreeMap<String, PathBuf>,
- #[allow(dead_code)] // We keep it around for the cleanup.
- ephemeral: Option<tempfile::TempDir>,
-}
-
-impl Ctx {
- /// Creates a new context for the default GnuPG home directory.
- pub fn new() -> Result<Self> {
- Self::make(None, None)
- }
-
- /// get the homedir Path
- pub fn get_homedir(&self) -> &Path {
- self.homedir.as_ref().unwrap().as_path()
- }
-
- /// Creates a new context for the given GnuPG home directory.
- pub fn with_homedir<P>(homedir: P) -> Result<Self>
- where
- P: AsRef<Path>,
- {
- Self::make(Some(homedir.as_ref()), None)
- }
-
- /// Creates a new ephemeral context.
- ///
- /// The created home directory will be deleted once this object is
- /// dropped.
- pub fn ephemeral() -> Result<Self> {
- Self::make(None, Some(tempfile::tempdir()?))
- }
-
- /// don't delete home directory.
- /// this is intended for manually debugging data that was created in a
- /// test-run.
- pub fn leak_tempdir(&mut self) -> Option<PathBuf> {
- if self.ephemeral.is_some() {
- let _ = self.stop_all();
- let _ = self.remove_socket_dir();
- }
- self.ephemeral.take().map(tempfile::TempDir::into_path)
- }
-
- fn make(
- homedir: Option<&Path>,
- ephemeral: Option<tempfile::TempDir>,
- ) -> Result<Self> {
- let mut components: BTreeMap<String, PathBuf> = Default::default();
- let mut directories: BTreeMap<String, PathBuf> = Default::default();
- let mut sockets: BTreeMap<String, PathBuf> = Default::default();
-
- let homedir: Option<PathBuf> = ephemeral
- .as_ref()
- .map(|tmp| tmp.path())
- .or(homedir)
- .map(|p| p.into());
-
- for fields in
- Self::gpgconf(&homedir, &["--list-components"], 3)?.into_iter()
- {
- components.insert(
- String::from_utf8(fields[0].clone())?,
- String::from_utf8(fields[2].clone())?.into(),
- );
- }
-
- for fields in Self::gpgconf(&homedir, &["--list-dirs"], 2)?.into_iter()
- {
- let (mut key, value) = (fields[0].clone(), fields[1].clone());
- if key.ends_with(b"-socket") {
- let l = key.len();
- key.truncate(l - b"-socket".len());
- sockets.insert(
- String::from_utf8(key)?,
- String::from_utf8(value)?.into(),
- );
- } else {
- directories.insert(
- String::from_utf8(key)?,
- String::from_utf8(value)?.into(),
- );
- }
- }
-
- Ok(Ctx {
- homedir,
- components,
- directories,
- sockets,
- ephemeral,
- })
- }
-
- fn gpgconf(
- homedir: &Option<PathBuf>,
- arguments: &[&str],
- nfields: usize,
- ) -> Result<Vec<Vec<Vec<u8>>>> {
- let nl = |&c: &u8| c as char == '\n';
- let colon = |&c: &u8| c as char == ':';
-
- let mut gpgconf = Command::new("gpgconf");
- if let Some(homedir) = homedir {
- gpgconf.arg("--homedir").arg(homedir);
-
- // https://dev.gnupg.org/T4496
- gpgconf.env("GNUPGHOME", homedir);
- }
-
- for argument in arguments {
- gpgconf.arg(argument);
- }
- let output = gpgconf.output().map_err(|e| -> anyhow::Error {
- GnupgError::GgpConf(e.to_string()).into()
- })?;
-
- if output.status.success() {
- let mut result = Vec::new();
- for line in output.stdout.split(nl) {
- if line.is_empty() {
- // EOF.
- break;
- }
-
- let fields = line
- .splitn(nfields, colon)
- .map(|f| f.to_vec())
- .collect::<Vec<_>>();
-
- if fields.len() != nfields {
- return Err(GnupgError::GgpConf(format!(
- "Malformed response, expected {} fields, \
- on line: {:?}",
- nfields, line
- ))
- .into());
- }
-
- result.push(fields);
- }
- Ok(result)
- } else {
- Err(GnupgError::GgpConf(
- String::from_utf8_lossy(&output.stderr).into_owned(),
- )
- .into())
- }
- }
-
- /// Returns the path to a GnuPG component.
- pub fn component<C>(&self, component: C) -> Result<&Path>
- where
- C: AsRef<str>,
- {
- self.components
- .get(component.as_ref())
- .map(|p| p.as_path())
- .ok_or_else(|| {
- GnupgError::GgpConf(format!(
- "No such component {:?}",
- component.as_ref()
- ))
- .into()
- })
- }
-
- /// Returns the path to a GnuPG directory.
- pub fn directory<C>(&self, directory: C) -> Result<&Path>
- where
- C: AsRef<str>,
- {
- self.directories
- .get(directory.as_ref())
- .map(|p| p.as_path())
- .ok_or_else(|| {
- GnupgError::GgpConf(format!(
- "No such directory {:?}",
- directory.as_ref()
- ))
- .into()
- })
- }
-
- /// Returns the path to a GnuPG socket.
- pub fn socket<C>(&self, socket: C) -> Result<&Path>
- where
- C: AsRef<str>,
- {
- self.sockets
- .get(socket.as_ref())
- .map(|p| p.as_path())
- .ok_or_else(|| {
- GnupgError::GgpConf(format!(
- "No such socket {:?}",
- socket.as_ref()
- ))
- .into()
- })
- }
-
- /// Creates directories for RPC communication.
- pub fn create_socket_dir(&self) -> Result<()> {
- Self::gpgconf(&self.homedir, &["--create-socketdir"], 1)?;
- Ok(())
- }
-
- /// Removes directories for RPC communication.
- ///
- /// Note: This will stop all servers once they note that their
- /// socket is gone.
- pub fn remove_socket_dir(&self) -> Result<()> {
- Self::gpgconf(&self.homedir, &["--remove-socketdir"], 1)?;
- Ok(())
- }
-
- /// Starts a GnuPG component.
- pub fn start(&self, component: &str) -> Result<()> {
- self.create_socket_dir()?;
- Self::gpgconf(&self.homedir, &["--launch", component], 1)?;
- Ok(())
- }
-
- /// Stops a GnuPG component.
- pub fn stop(&self, component: &str) -> Result<()> {
- Self::gpgconf(&self.homedir, &["--kill", component], 1)?;
- Ok(())
- }
-
- /// Stops all GnuPG components.
- pub fn stop_all(&self) -> Result<()> {
- self.stop("all")
- }
-}
-
-impl Drop for Ctx {
- fn drop(&mut self) {
- if self.ephemeral.is_some() {
- let _ = self.stop_all();
- let _ = self.remove_socket_dir();
- }
- }
-}
-
-impl std::error::Error for GnupgError {}
-
-impl fmt::Display for GnupgError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- GnupgError::GgpConf(s) => write!(f, "gpgconf: {}", s),
- GnupgError::OperationFailed(s) => {
- write!(f, "Operation failed: {}", s)
- }
- GnupgError::ProtocolError(s) => {
- write!(f, "Protocol violation: {}", s)
- }
- }
- }
-}
-
-#[derive(Debug)]
-/// Errors used in this module.
-pub enum GnupgError {
- /// Errors related to `gpgconf`.
- GgpConf(String),
-
- /// The remote operation failed.
- OperationFailed(String),
-
- /// The remote party violated the protocol.
- ProtocolError(String),
-}
-
-pub fn import(ctx: &Ctx, what: &[u8]) {
- let mut gpg = Command::new("gpg")
- .stdin(Stdio::piped())
- .arg("--homedir")
- .arg(ctx.directory("homedir").unwrap())
- .arg("--import")
- .spawn()
- .expect("failed to start gpg");
- gpg.stdin.as_mut().unwrap().write_all(what).unwrap();
- let status = gpg.wait().unwrap();
- assert!(status.success());
-}
-
-pub fn export(ctx: &Ctx, search: &str) -> String {
- let mut out = String::new();
-
- let mut gpg = Command::new("gpg")
- .stdout(Stdio::piped())
- .arg("--homedir")
- .arg(ctx.directory("homedir").unwrap())
- .arg("--armor")
- .arg("--export")
- .arg(search)
- .spawn()
- .expect("failed to start gpg");
- let status = gpg.wait().unwrap();
- gpg.stdout
- .as_mut()
- .unwrap()
- .read_to_string(&mut out)
- .unwrap();
- assert!(status.success());
-
- out
-}
-
-pub fn export_secret(ctx: &Ctx, search: &str) -> String {
- let mut out = String::new();
-
- let mut gpg = Command::new("gpg")
- .stdout(Stdio::piped())
- .arg("--homedir")
- .arg(ctx.directory("homedir").unwrap())
- .arg("--armor")
- .arg("--export-secret-keys")
- .arg(search)
- .spawn()
- .expect("failed to start gpg");
- let status = gpg.wait().unwrap();
- gpg.stdout
- .as_mut()
- .unwrap()
- .read_to_string(&mut out)
- .unwrap();
- assert!(status.success());
-
- out
-}
-
-pub fn list_keys(ctx: &Ctx) -> Result<HashMap<String, String>> {
- let res = list_keys_raw(&ctx);
-
- // filter: keep only the "uid" lines
- let uids = res
- .iter()
- .filter(|&line| line.get(0) == Some("uid"))
- .cloned()
- .collect::<Vec<_>>();
-
- // map: uid -> trust
- Ok(uids
- .iter()
- .map(|u| (u.get(9).unwrap().to_owned(), u.get(1).unwrap().to_owned()))
- .collect())
-}
-
-fn list_keys_raw(ctx: &Ctx) -> Vec<StringRecord> {
- let gpg = Command::new("gpg")
- .stdin(Stdio::piped())
- .arg("--homedir")
- .arg(ctx.directory("homedir").unwrap())
- .arg("--list-keys")
- .arg("--with-colons")
- .output()
- .expect("failed to start gpg");
-
- let mut rdr = csv::ReaderBuilder::new()
- .has_headers(false)
- .delimiter(b':')
- .flexible(true)
- .from_reader(gpg.stdout.as_slice());
-
- let status = gpg.status;
- assert!(status.success());
-
- rdr.records().map(|rec| rec.unwrap()).collect()
-}
-
-pub fn edit_trust(ctx: &Ctx, user_id: &str, trust: u8) -> Result<()> {
- let homedir =
- String::from(ctx.directory("homedir").unwrap().to_str().unwrap());
-
- let cmd = format!("gpg --homedir {} --edit-key {}", homedir, user_id);
-
- let mut p = rexpect::spawn(&cmd, Some(10_000)).unwrap();
- p.exp_string("gpg>").unwrap();
- p.send_line("trust").unwrap();
- p.exp_string("Your decision?").unwrap();
- p.send_line(&format!("{}", trust)).unwrap();
- p.exp_string(
- "Do you really want to set this key to ultimate trust? (y/N)",
- )
- .unwrap();
- p.send_line("y").unwrap();
- p.exp_string("gpg>").unwrap();
- p.send_line("quit").unwrap();
- p.exp_eof().unwrap();
-
- Ok(())
-}
-
-pub fn make_revocation(
- ctx: &Ctx,
- user_id: &str,
- filename: &str,
- reason: u8,
-) -> Result<()> {
- let homedir =
- String::from(ctx.directory("homedir").unwrap().to_str().unwrap());
-
- let cmd = format!(
- "gpg --homedir {} --output {} --gen-revoke {}",
- homedir, filename, user_id
- );
-
- let mut p = rexpect::spawn(&cmd, Some(10_000)).unwrap();
- p.exp_string("Create a revocation certificate for this key? (y/N)")
- .unwrap();
- p.send_line("y").unwrap();
- p.exp_string("Your decision?").unwrap();
- p.send_line(&format!("{}", reason)).unwrap();
- p.exp_string(">").unwrap();
- p.send_line("").unwrap();
- p.exp_string("Is this okay? (y/N)").unwrap();
- p.send_line("y").unwrap();
- p.exp_eof().unwrap();
-
- Ok(())
-}
-
-pub fn edit_expire(ctx: &Ctx, user_id: &str, expires: &str) -> Result<()> {
- let homedir =
- String::from(ctx.directory("homedir").unwrap().to_str().unwrap());
-
- let cmd = format!("gpg --homedir {} --edit-key {}", homedir, user_id);
-
- let mut p = rexpect::spawn(&cmd, Some(10_000)).unwrap();
- p.exp_string("gpg>").unwrap();
- p.send_line("expire").unwrap();
- p.exp_string("Key is valid for? (0)").unwrap();
- p.send_line(expires).unwrap();
- p.exp_string("Is this correct? (y/N)").unwrap();
- p.send_line("y").unwrap();
- p.exp_string("gpg>").unwrap();
- p.send_line("quit").unwrap();
- p.exp_string("Save changes? (y/N)").unwrap();
- p.send_line("y").unwrap();
- p.exp_eof().unwrap();
-
- Ok(())
-}
-
-pub fn create_user(ctx: &Ctx, user_id: &str) {
- let mut gpg = Command::new("gpg")
- .stdin(Stdio::piped())
- .arg("--homedir")
- .arg(ctx.directory("homedir").unwrap())
- .arg("--quick-generate-key")
- .arg("--batch")
- .arg("--passphrase")
- .arg("")
- .arg(user_id.to_string())
- .spawn()
- .expect("failed to start gpg");
- let status = gpg.wait().unwrap();
- assert!(status.success());
-}
-
-pub fn sign(ctx: &Ctx, user_id: &str) -> Result<()> {
- let homedir =
- String::from(ctx.directory("homedir").unwrap().to_str().unwrap());
-
- let cmd = format!("gpg --homedir {} --edit-key {}", homedir, user_id);
-
- let mut p = rexpect::spawn(&cmd, Some(10_000)).unwrap();
- p.exp_string("gpg>").unwrap();
- p.send_line("sign").unwrap();
- p.exp_string("Really sign? (y/N)").unwrap();
- p.send_line("y").unwrap();
- p.exp_string("gpg>").unwrap();
- p.send_line("save").unwrap();
- p.exp_eof().unwrap();
-
- Ok(())
-}
-
-pub fn tsign(ctx: &Ctx, user_id: &str, level: u8, trust: u8) -> Result<()> {
- let homedir =
- String::from(ctx.directory("homedir").unwrap().to_str().unwrap());
-
- let cmd = format!("gpg --homedir {} --edit-key {}", homedir, user_id);
-
- let mut p = rexpect::spawn(&cmd, Some(10_000)).unwrap();
- p.exp_string("gpg>").unwrap();
- p.send_line("tsign").unwrap();
- p.exp_string("Your selection?").unwrap();
- p.send_line(&format!("{}", trust)).unwrap();
- p.exp_string("Your selection?").unwrap();
- p.send_line(&format!("{}", level)).unwrap();
- p.exp_string("Your selection?").unwrap();
- p.send_line("").unwrap(); // domain
- p.exp_string("Really sign? (y/N)").unwrap();
- p.send_line("y").unwrap();
- p.exp_string("gpg>").unwrap();
- p.send_line("quit").unwrap();
- p.exp_string("Save changes? (y/N)").unwrap();
- p.send_line("y").unwrap();
- p.exp_eof().unwrap();
-
- Ok(())
-}
diff --git a/openpgp-ca-restd/tests/test_restd.rs b/openpgp-ca-restd/tests/test_restd.rs
index b2d456b..0290ec5 100644
--- a/openpgp-ca-restd/tests/test_restd.rs
+++ b/openpgp-ca-restd/tests/test_restd.rs
@@ -12,12 +12,11 @@ use openpgp_ca_restd::json::{
};
use openpgp_ca_restd::restd;
+use gnupg_test_wrapper as gnupg;
use openpgp_ca_lib::ca::OpenpgpCa;
use rocket::futures::prelude::future::{AbortHandle, Abortable};
-pub mod gnupg;
-
const ALICE_CERT: &str = r#"-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEX419BRYJKwYBBAHaRw8BAQdAnfJuV3EHFAJ31D968YvLlAAu0YqUxySSJ1Lh