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
|
_Requirement: We must be able to generate a that does have a
|
||||||
password._
|
password._
|
||||||
|
|
||||||
Unfortunately, the `--with-password` option causes `sq` to read the
|
~~~scenario
|
||||||
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.
|
|
||||||
|
|
||||||
~~~
|
|
||||||
given an installed sq
|
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
|
when I run sq --no-cert-store --no-key-store inspect key.pgp
|
||||||
then stdout contains "Secret key: Encrypted"
|
then stdout contains "Secret key: Encrypted"
|
||||||
~~~
|
~~~
|
||||||
@ -1603,3 +1599,9 @@ This is an empty file.
|
|||||||
|
|
||||||
~~~{#empty .file add-newline=no}
|
~~~{#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,
|
value_enum,
|
||||||
)]
|
)]
|
||||||
pub cipher_suite: CipherSuite,
|
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(
|
#[clap(
|
||||||
long = "without-password",
|
long = "without-password",
|
||||||
help = "Don't protect the secret key material with a password",
|
help = "Don't protect the secret key material with a password",
|
||||||
)]
|
)]
|
||||||
pub without_password: bool,
|
pub without_password: bool,
|
||||||
|
|
||||||
#[clap(
|
#[clap(
|
||||||
long = "expiration",
|
long = "expiration",
|
||||||
value_name = "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(
|
builder = builder.set_password(
|
||||||
password::prompt_for_new_or_none(&sq, "key")?);
|
password::prompt_for_new_or_none(&sq, "key")?);
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,12 @@ impl Sq {
|
|||||||
-> (Cert, PathBuf, PathBuf)
|
-> (Cert, PathBuf, PathBuf)
|
||||||
{
|
{
|
||||||
let mut cmd = self.command();
|
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 {
|
for arg in extra_args {
|
||||||
cmd.arg(arg);
|
cmd.arg(arg);
|
||||||
}
|
}
|
||||||
|
@ -44,3 +44,27 @@ fn sq_key_generate_name_email() -> Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
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