feat(notgraph): heatmap coloring, symbol counts, per-crate module graphs, cycle callouts
This commit is contained in:
@@ -36,7 +36,7 @@ impl Identity for EncryptedIdentity {
|
||||
Err(_) => {
|
||||
return Some(Err(AgeError::ParseError(
|
||||
"decrypted identity file is not valid UTF-8".to_string(),
|
||||
)))
|
||||
)));
|
||||
}
|
||||
};
|
||||
// Parse inner identity — only X25519 supported for now
|
||||
|
||||
@@ -39,9 +39,9 @@ impl FileKey {
|
||||
impl TryFrom<&[u8]> for FileKey {
|
||||
type Error = AgeError;
|
||||
fn try_from(b: &[u8]) -> Result<Self, AgeError> {
|
||||
b.try_into()
|
||||
.map(Self)
|
||||
.map_err(|_| AgeError::ParseError(format!("file key must be 16 bytes, got {}", b.len())))
|
||||
b.try_into().map(Self).map_err(|_| {
|
||||
AgeError::ParseError(format!("file key must be 16 bytes, got {}", b.len()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ pub(crate) fn derive_scrypt_key(
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::identities::FileKey;
|
||||
use crate::recipients::scrypt::ScryptRecipient;
|
||||
use crate::recipients::Recipient;
|
||||
use crate::recipients::scrypt::ScryptRecipient;
|
||||
|
||||
#[test]
|
||||
fn scrypt_wrap_unwrap_roundtrip() {
|
||||
@@ -73,7 +73,9 @@ mod tests {
|
||||
let identity = ScryptIdentity::new(passphrase);
|
||||
|
||||
let file_key = FileKey::new([0x11u8; 16]);
|
||||
let stanza = recipient.wrap_file_key(&file_key).expect("wrap should succeed");
|
||||
let stanza = recipient
|
||||
.wrap_file_key(&file_key)
|
||||
.expect("wrap should succeed");
|
||||
assert_eq!(stanza.tag, "scrypt");
|
||||
assert_eq!(stanza.args.len(), 2);
|
||||
|
||||
|
||||
@@ -46,7 +46,11 @@ impl Identity for SshEd25519Identity {
|
||||
}
|
||||
let fp_bytes = match STANDARD_NO_PAD.decode(&stanza.args[0]) {
|
||||
Ok(b) => b,
|
||||
Err(e) => return Some(Err(AgeError::ParseError(format!("fingerprint base64: {e}")))),
|
||||
Err(e) => {
|
||||
return Some(Err(AgeError::ParseError(format!(
|
||||
"fingerprint base64: {e}"
|
||||
))));
|
||||
}
|
||||
};
|
||||
if fp_bytes.as_slice() != self.fingerprint() {
|
||||
return None;
|
||||
@@ -68,8 +72,11 @@ fn unwrap(stanza: &Stanza, identity: &SshEd25519Identity) -> Result<FileKey, Age
|
||||
let shared = x25519_secret.diffie_hellman(&ephemeral_pub);
|
||||
let x25519_pub = X25519PublicKey::from(&x25519_secret);
|
||||
|
||||
let wrap_key =
|
||||
derive_wrap_key(shared.as_bytes(), ephemeral_pub.as_bytes(), x25519_pub.as_bytes())?;
|
||||
let wrap_key = derive_wrap_key(
|
||||
shared.as_bytes(),
|
||||
ephemeral_pub.as_bytes(),
|
||||
x25519_pub.as_bytes(),
|
||||
)?;
|
||||
|
||||
let cipher = ChaCha20Poly1305::new(Key::from_slice(&wrap_key));
|
||||
let nonce = Nonce::default();
|
||||
@@ -104,8 +111,8 @@ pub(crate) fn derive_wrap_key(
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::identities::FileKey;
|
||||
use crate::recipients::ssh_ed25519::SshEd25519Recipient;
|
||||
use crate::recipients::Recipient;
|
||||
use crate::recipients::ssh_ed25519::SshEd25519Recipient;
|
||||
|
||||
fn test_signing_key() -> SigningKey {
|
||||
use rand::rngs::OsRng;
|
||||
@@ -123,7 +130,9 @@ mod tests {
|
||||
let identity = SshEd25519Identity::from_signing_key(signing_key);
|
||||
|
||||
let file_key = FileKey::new([0x33u8; 16]);
|
||||
let stanza = recipient.wrap_file_key(&file_key).expect("wrap should succeed");
|
||||
let stanza = recipient
|
||||
.wrap_file_key(&file_key)
|
||||
.expect("wrap should succeed");
|
||||
assert_eq!(stanza.tag, "ssh-ed25519");
|
||||
assert_eq!(stanza.args.len(), 2);
|
||||
|
||||
|
||||
@@ -32,7 +32,11 @@ impl Identity for SshRsaIdentity {
|
||||
}
|
||||
let fp = match STANDARD_NO_PAD.decode(&stanza.args[0]) {
|
||||
Ok(b) => b,
|
||||
Err(e) => return Some(Err(AgeError::ParseError(format!("fingerprint base64: {e}")))),
|
||||
Err(e) => {
|
||||
return Some(Err(AgeError::ParseError(format!(
|
||||
"fingerprint base64: {e}"
|
||||
))));
|
||||
}
|
||||
};
|
||||
if fp.as_slice() != self.fingerprint() {
|
||||
return None;
|
||||
@@ -62,8 +66,8 @@ pub(crate) fn rsa_pubkey_fingerprint(public_key: &RsaPublicKey) -> [u8; 4] {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::recipients::ssh_rsa::SshRsaRecipient;
|
||||
use crate::recipients::Recipient;
|
||||
use crate::recipients::ssh_rsa::SshRsaRecipient;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
fn test_rsa_keypair() -> (RsaPrivateKey, RsaPublicKey) {
|
||||
@@ -79,7 +83,9 @@ mod tests {
|
||||
let identity = SshRsaIdentity::from_private_key(private_key);
|
||||
|
||||
let file_key = FileKey::new([0x55u8; 16]);
|
||||
let stanza = recipient.wrap_file_key(&file_key).expect("wrap should succeed");
|
||||
let stanza = recipient
|
||||
.wrap_file_key(&file_key)
|
||||
.expect("wrap should succeed");
|
||||
assert_eq!(stanza.tag, "ssh-rsa");
|
||||
assert_eq!(stanza.args.len(), 1);
|
||||
|
||||
|
||||
@@ -119,7 +119,9 @@ mod tests {
|
||||
let recipient = X25519Recipient::from_public_key(public);
|
||||
let identity = X25519Identity::from_static_secret(StaticSecret::from(secret_bytes));
|
||||
let file_key = FileKey::new([0x42u8; 16]);
|
||||
let stanza = recipient.wrap_file_key(&file_key).expect("wrap should succeed");
|
||||
let stanza = recipient
|
||||
.wrap_file_key(&file_key)
|
||||
.expect("wrap should succeed");
|
||||
assert_eq!(stanza.tag, "X25519");
|
||||
assert_eq!(stanza.args.len(), 1);
|
||||
let unwrapped = identity
|
||||
@@ -148,7 +150,8 @@ mod tests {
|
||||
let public = PublicKey::from(&secret);
|
||||
let recipient_str = X25519Recipient::from_public_key(public).to_bech32();
|
||||
assert!(recipient_str.starts_with("age1"));
|
||||
let identity_str = X25519Identity::from_static_secret(StaticSecret::from(secret_bytes)).to_bech32();
|
||||
let identity_str =
|
||||
X25519Identity::from_static_secret(StaticSecret::from(secret_bytes)).to_bech32();
|
||||
assert!(identity_str.starts_with("AGE-SECRET-KEY-1"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user