parent
230f849307
commit
0cf495bd90
@ -466,14 +466,10 @@ then stdout contains "Secret key: Unencrypted"
|
||||
_Requirement: We must be able to generate a that does have a
|
||||
password._
|
||||
|
||||
Unfortunately, the `--with-password` option causes `sq` to read the
|
||||
password from the terminal, and that makes it hard to do in an
|
||||
automated test. Thus, this scenario isn't enabled, waiting for a way
|
||||
to feed `sq` a password as if the user typed it from a terminal.
|
||||
|
||||
~~~
|
||||
~~~scenario
|
||||
given an installed sq
|
||||
when I run sq --no-cert-store --no-key-store key generate --no-userids --output key.pgp --with-password
|
||||
given file password.txt
|
||||
when I run sq --no-cert-store --no-key-store key generate --no-userids --output key.pgp --new-password-file password.txt
|
||||
when I run sq --no-cert-store --no-key-store inspect key.pgp
|
||||
then stdout contains "Secret key: Encrypted"
|
||||
~~~
|
||||
@ -1603,3 +1599,9 @@ This is an empty file.
|
||||
|
||||
~~~{#empty .file add-newline=no}
|
||||
~~~
|
||||
|
||||
This is a file containing a password.
|
||||
|
||||
~~~{#password.txt .file}
|
||||
hunter2
|
||||
~~~
|
||||
|
@ -252,11 +252,27 @@ Canonical user IDs are of the form `Name (Comment) \
|
||||
value_enum,
|
||||
)]
|
||||
pub cipher_suite: CipherSuite,
|
||||
|
||||
#[clap(
|
||||
long = "new-password-file",
|
||||
value_name = "PASSWORD_FILE",
|
||||
help = "\
|
||||
File containing password to encrypt the secret key material",
|
||||
long_help = "\
|
||||
File containing password to encrypt the secret key material.
|
||||
|
||||
Note that the entire key file will be used as the password including \
|
||||
any surrounding whitespace like a trailing newline.",
|
||||
conflicts_with = "without_password",
|
||||
)]
|
||||
pub new_password_file: Option<PathBuf>,
|
||||
|
||||
#[clap(
|
||||
long = "without-password",
|
||||
help = "Don't protect the secret key material with a password",
|
||||
)]
|
||||
pub without_password: bool,
|
||||
|
||||
#[clap(
|
||||
long = "expiration",
|
||||
value_name = "EXPIRATION",
|
||||
|
@ -121,7 +121,13 @@ pub fn generate(
|
||||
}
|
||||
}
|
||||
|
||||
if ! command.without_password {
|
||||
if let Some(password_file) = command.new_password_file {
|
||||
let password = std::fs::read(&password_file)
|
||||
.with_context(|| {
|
||||
format!("Reading {}", password_file.display())
|
||||
})?;
|
||||
builder = builder.set_password(Some(password.into()));
|
||||
} else if ! command.without_password {
|
||||
builder = builder.set_password(
|
||||
password::prompt_for_new_or_none(&sq, "key")?);
|
||||
}
|
||||
|
@ -347,7 +347,12 @@ impl Sq {
|
||||
-> (Cert, PathBuf, PathBuf)
|
||||
{
|
||||
let mut cmd = self.command();
|
||||
cmd.args([ "key", "generate", "--without-password" ]);
|
||||
cmd.args([ "key", "generate" ]);
|
||||
|
||||
if ! extra_args.contains(&"--new-password-file") {
|
||||
cmd.arg("--without-password");
|
||||
}
|
||||
|
||||
for arg in extra_args {
|
||||
cmd.arg(arg);
|
||||
}
|
||||
|
@ -44,3 +44,27 @@ fn sq_key_generate_name_email() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sq_key_generate_with_password() -> Result<()> {
|
||||
let sq = common::Sq::new();
|
||||
|
||||
let password = "hunter2";
|
||||
let path = sq.base().join("password");
|
||||
std::fs::write(&path, password)?;
|
||||
|
||||
let (cert, _, _) = sq.key_generate(&[
|
||||
"--new-password-file", &path.display().to_string(),
|
||||
], &[]);
|
||||
|
||||
assert!(cert.is_tsk());
|
||||
|
||||
let password = password.into();
|
||||
for key in cert.keys() {
|
||||
let secret = key.optional_secret().unwrap();
|
||||
assert!(secret.is_encrypted());
|
||||
assert!(secret.clone().decrypt(key.pk_algo(), &password).is_ok());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user