Skip to content

Commit

Permalink
Merge pull request #173 from str4d/windows-test-vectors
Browse files Browse the repository at this point in the history
age: Re-enable age test vectors on Windows
  • Loading branch information
str4d authored Jan 11, 2021
2 parents 4cf2ec5 + 3d2c948 commit bf82a7e
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 13 deletions.
4 changes: 4 additions & 0 deletions age/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ to 1.0.0 are beta releases.
(instead of wrapping `std::io::File` directly), which does not open the file
until it is first written to.

### Fixed
- `age::cli_common::read_identities` now allows either kind of line ending in
SSH identity files.

## [0.5.0] - 2020-11-22
### Added
- Italian, Spanish, and Chinese translations!
Expand Down
4 changes: 4 additions & 0 deletions age/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ unstable = ["age-core/unstable"]
[lib]
bench = false

[[test]]
name = "test_vectors"
required-features = ["ssh"]

[[bench]]
name = "throughput"
harness = false
25 changes: 21 additions & 4 deletions age/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,23 @@ pub struct IdentityFile {
impl IdentityFile {
/// Parses one or more identities from a file containing valid UTF-8.
pub fn from_file(filename: String) -> io::Result<Self> {
File::open(filename)
File::open(&filename)
.map(io::BufReader::new)
.and_then(IdentityFile::from_buffer)
.and_then(|data| IdentityFile::parse_identities(Some(filename), data))
}

/// Parses one or more identities from a buffered input containing valid UTF-8.
pub fn from_buffer<R: io::BufRead>(data: R) -> io::Result<Self> {
Self::parse_identities(None, data)
}

fn parse_identities<R: io::BufRead>(filename: Option<String>, data: R) -> io::Result<Self> {
let mut identities = vec![];

#[cfg(feature = "plugin")]
let mut plugin_identities = vec![];

for line in data.lines() {
for (line_number, line) in data.lines().enumerate() {
let line = line?;
if line.is_empty() || line.starts_with('#') {
continue;
Expand All @@ -54,9 +58,22 @@ impl IdentityFile {
#[cfg(not(feature = "plugin"))]
let _: () = identity;
} else {
// Return a line number in place of the line, so we don't leak the file
// contents in error messages.
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"invalid identity file",
if let Some(filename) = filename {
format!(
"identity file {} contains non-identity data on line {}",
filename,
line_number + 1
)
} else {
format!(
"identity file contains non-identity data on line {}",
line_number + 1
)
},
));
}
}
Expand Down
12 changes: 6 additions & 6 deletions age/src/ssh/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use i18n_embed_fl::fl;
use nom::{
branch::alt,
bytes::streaming::{is_not, tag},
character::streaming::newline,
character::streaming::{line_ending, newline},
combinator::{map_opt, opt},
sequence::{pair, preceded, terminated, tuple},
IResult,
Expand Down Expand Up @@ -299,11 +299,11 @@ fn rsa_pem_encryption_header(input: &str) -> IResult<&str, &str> {

fn rsa_privkey(input: &str) -> IResult<&str, Identity> {
preceded(
pair(tag("-----BEGIN RSA PRIVATE KEY-----"), newline),
pair(tag("-----BEGIN RSA PRIVATE KEY-----"), line_ending),
terminated(
map_opt(
pair(
opt(terminated(rsa_pem_encryption_header, newline)),
opt(terminated(rsa_pem_encryption_header, line_ending)),
wrapped_str_while_encoded(base64::STANDARD),
),
|(enc_header, privkey)| {
Expand All @@ -322,19 +322,19 @@ fn rsa_privkey(input: &str) -> IResult<&str, Identity> {
}
},
),
pair(newline, tag("-----END RSA PRIVATE KEY-----")),
pair(line_ending, tag("-----END RSA PRIVATE KEY-----")),
),
)(input)
}

fn openssh_privkey(input: &str) -> IResult<&str, Identity> {
preceded(
pair(tag("-----BEGIN OPENSSH PRIVATE KEY-----"), newline),
pair(tag("-----BEGIN OPENSSH PRIVATE KEY-----"), line_ending),
terminated(
map_opt(wrapped_str_while_encoded(base64::STANDARD), |privkey| {
read_ssh::openssh_privkey(&privkey).ok().map(|(_, key)| key)
}),
pair(newline, tag("-----END OPENSSH PRIVATE KEY-----")),
pair(line_ending, tag("-----END OPENSSH PRIVATE KEY-----")),
),
)(input)
}
Expand Down
4 changes: 2 additions & 2 deletions age/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ pub(crate) mod read {
pub(crate) fn wrapped_str_while_encoded(
config: base64::Config,
) -> impl Fn(&str) -> IResult<&str, Vec<u8>> {
use nom::{bytes::streaming::take_while1, character::streaming::newline};
use nom::{bytes::streaming::take_while1, character::streaming::line_ending};

move |input: &str| {
map_res(
separated_nonempty_list(
newline,
line_ending,
take_while1(|c| {
let c = c as u8;
// Substitute the character in twice after AA, so that padding
Expand Down
1 change: 0 additions & 1 deletion age/tests/test_vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use secrecy::SecretString;
use std::fs;
use std::io::{self, Read};

#[cfg(unix)]
#[test]
fn age_test_vectors() -> Result<(), age::DecryptError> {
for test_vector in fs::read_dir("./tests/testdata")?.filter(|res| {
Expand Down

0 comments on commit bf82a7e

Please sign in to comment.