Skip to content

Commit

Permalink
Merge pull request #523 from str4d/recipients-by-ref
Browse files Browse the repository at this point in the history
age: Take recipients by reference in `Encryptor::with_recipients`
  • Loading branch information
str4d authored Aug 30, 2024
2 parents 8b0b65e + 9ab26bf commit 9af4790
Show file tree
Hide file tree
Showing 23 changed files with 106 additions and 78 deletions.
14 changes: 14 additions & 0 deletions age/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ to 1.0.0 are beta releases.

### Changed
- Migrated to `i18n-embed 0.15`.
- `age::Encryptor::with_recipients` now takes recipients by reference instead of
by value. This aligns it with `age::Decryptor` (which takes identities by
reference), and also means that errors with recipients are reported earlier.
This causes the following changes to the API:
- `Encryptor::with_recipients` takes `impl Iterator<Item = &'a dyn Recipient>`
instead of `Vec<Box<dyn Recipient + Send>>`.
- Verification of recipients and generation of stanzas now happens in
`Encryptor::with_recipients` instead of `Encryptor::wrap_output` and
`Encryptor::wrap_async_output`.
- `Encryptor::with_recipients` returns `Result<Self, EncryptError>` instead of
`Option<Self>`, and `Encryptor::{wrap_output, wrap_async_output}` return
`io::Result<StreamWriter<W>>` instead of `Result<StreamWriter<W>, EncryptError>`.
- `age::EncryptError` has a new variant `MissingRecipients`, taking the place
of the `None` that `Encryptor::with_recipients` could previously return.
- `age::Decryptor` is now an opaque struct instead of an enum with `Recipients`
and `Passphrase` variants.
- `age::IdentityFile` now has a `C: Callbacks` generic parameter, which defaults
Expand Down
20 changes: 7 additions & 13 deletions age/benches/parser.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use age::{x25519, Decryptor, Encryptor, Recipient};
use age::{x25519, Decryptor, Encryptor};
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};

#[cfg(unix)]
Expand All @@ -8,25 +8,19 @@ use std::io::Write;

fn bench(c: &mut Criterion) {
let recipients: Vec<_> = (0..10)
.map(|_| Box::new(x25519::Identity::generate().to_public()))
.map(|_| x25519::Identity::generate().to_public())
.collect();
let mut group = c.benchmark_group("header");

for count in 1..10 {
group.throughput(Throughput::Elements(count as u64));
group.bench_function(BenchmarkId::new("parse", count), |b| {
let mut encrypted = vec![];
let mut output = Encryptor::with_recipients(
recipients
.iter()
.take(count)
.cloned()
.map(|r| r as Box<dyn Recipient + Send>)
.collect(),
)
.unwrap()
.wrap_output(&mut encrypted)
.unwrap();
let mut output =
Encryptor::with_recipients(recipients.iter().take(count).map(|r| r as _))
.unwrap()
.wrap_output(&mut encrypted)
.unwrap();
output.write_all(&[]).unwrap();
output.finish().unwrap();

Expand Down
4 changes: 2 additions & 2 deletions age/benches/throughput.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn bench(c: &mut Criterion_) {

group.bench_function(BenchmarkId::new("encrypt", size), |b| {
b.iter(|| {
let mut output = Encryptor::with_recipients(vec![Box::new(recipient.clone())])
let mut output = Encryptor::with_recipients(iter::once(&recipient as _))
.unwrap()
.wrap_output(io::sink())
.unwrap();
Expand All @@ -62,7 +62,7 @@ fn bench(c: &mut Criterion_) {
});

group.bench_function(BenchmarkId::new("decrypt", size), |b| {
let mut output = Encryptor::with_recipients(vec![Box::new(recipient.clone())])
let mut output = Encryptor::with_recipients(iter::once(&recipient as _))
.unwrap()
.wrap_output(&mut ct_buf)
.unwrap();
Expand Down
2 changes: 2 additions & 0 deletions age/i18n/en-US/age.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ err-invalid-recipient-labels = The first recipient requires one or more invalid
err-key-decryption = Failed to decrypt an encrypted key
err-missing-recipients = Missing recipients.
err-mixed-recipient-passphrase = {-scrypt-recipient} can't be used with other recipients.
err-no-matching-keys = No matching keys found
Expand Down
2 changes: 2 additions & 0 deletions age/i18n/es-AR/age.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ err-header-mac-invalid = MAC de encabezado inválido.
err-key-decryption = No se pudo desencriptar una clave encriptada.
err-missing-recipients = No se encontraron destinatarios.
err-no-matching-keys = No se encontraron claves coincidentes.
err-unknown-format = Formato {-age} desconocido.
Expand Down
2 changes: 2 additions & 0 deletions age/i18n/fr/age.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ err-header-mac-invalid = Le MAC de l'en-tête est invalide
err-key-decryption = Echec du déchiffrement d'une clef chiffrée
err-missing-recipients = Destinataires manquants.
err-no-matching-keys = Aucune clef correspondante n'a été trouvée
err-unknown-format = Format {-age} inconnu.
Expand Down
2 changes: 2 additions & 0 deletions age/i18n/it/age.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ err-header-mac-invalid = Il MAC dell'header è invalido
err-key-decryption = La decifrazione di una chiave crittografata è fallita
err-missing-recipients = Destinatari mancanti.
err-no-matching-keys = Nessuna chiave corrispondente trovata
err-unknown-format = Formato {-age} sconosciuto.
Expand Down
2 changes: 2 additions & 0 deletions age/i18n/ru/age.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ err-header-mac-invalid = Недействительный MAC заголовка
err-key-decryption = Не удалось расшифровать зашифрованный ключ
err-missing-recipients = Отсутствуют получатели.
err-no-matching-keys = Не найдены подходящие ключи
err-unknown-format = Неизвестный формат {-age}.
Expand Down
2 changes: 2 additions & 0 deletions age/i18n/zh-CN/age.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ err-header-mac-invalid = 标头消息认证码 (MAC) 无效
err-key-decryption = 未能解密加密密钥
err-missing-recipients = 缺少接收方。
err-no-matching-keys = 未搜索到匹配的密钥
err-unknown-format = 未知的 {-age} 格式。
Expand Down
2 changes: 2 additions & 0 deletions age/i18n/zh-TW/age.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ err-header-mac-invalid = 標頭消息認證碼 (MAC) 無效
err-key-decryption = 未能解密加密密鑰
err-missing-recipients = 缺少接收方。
err-no-matching-keys = 未搜索到匹配的密鑰
err-unknown-format = 未知的 {-age} 格式。
Expand Down
4 changes: 4 additions & 0 deletions age/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ pub enum EncryptError {
/// The plugin's binary name.
binary_name: String,
},
/// The encryptor was not given any recipients.
MissingRecipients,
/// [`scrypt::Recipient`] was mixed with other recipient types.
///
/// [`scrypt::Recipient`]: crate::scrypt::Recipient
Expand Down Expand Up @@ -219,6 +221,7 @@ impl Clone for EncryptError {
Self::MissingPlugin { binary_name } => Self::MissingPlugin {
binary_name: binary_name.clone(),
},
Self::MissingRecipients => Self::MissingRecipients,
Self::MixedRecipientAndPassphrase => Self::MixedRecipientAndPassphrase,
#[cfg(feature = "plugin")]
Self::Plugin(e) => Self::Plugin(e.clone()),
Expand Down Expand Up @@ -277,6 +280,7 @@ impl fmt::Display for EncryptError {
wlnfl!(f, "err-missing-plugin", plugin_name = binary_name.as_str())?;
wfl!(f, "rec-missing-plugin")
}
EncryptError::MissingRecipients => wfl!(f, "err-missing-recipients"),
EncryptError::MixedRecipientAndPassphrase => {
wfl!(f, "err-mixed-recipient-passphrase")
}
Expand Down
2 changes: 1 addition & 1 deletion age/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
//! // Encrypt the plaintext to a ciphertext...
//! # fn encrypt(pubkey: age::x25519::Recipient, plaintext: &[u8]) -> Result<Vec<u8>, age::EncryptError> {
//! let encrypted = {
//! let encryptor = age::Encryptor::with_recipients(vec![Box::new(pubkey)])
//! let encryptor = age::Encryptor::with_recipients(iter::once(&pubkey as _))
//! .expect("we provided a recipient");
//!
//! let mut encrypted = vec![];
Expand Down
6 changes: 3 additions & 3 deletions age/src/primitives/armor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ enum ArmorIs<W> {
/// ```
/// # use std::io::Read;
/// use std::io::Write;
/// # use std::iter;
/// use std::iter;
///
/// # fn run_main() -> Result<(), ()> {
/// # let identity = age::x25519::Identity::generate();
Expand All @@ -301,7 +301,7 @@ enum ArmorIs<W> {
///
/// # fn encrypt(recipient: age::x25519::Recipient, plaintext: &[u8]) -> Result<Vec<u8>, age::EncryptError> {
/// let encrypted = {
/// let encryptor = age::Encryptor::with_recipients(vec![Box::new(recipient)])
/// let encryptor = age::Encryptor::with_recipients(iter::once(&recipient as _))
/// .expect("we provided a recipient");
///
/// let mut encrypted = vec![];
Expand Down Expand Up @@ -664,7 +664,7 @@ enum StartPos {
/// # fn run_main() -> Result<(), ()> {
/// # fn encrypt(recipient: age::x25519::Recipient, plaintext: &[u8]) -> Result<Vec<u8>, age::EncryptError> {
/// # let encrypted = {
/// # let encryptor = age::Encryptor::with_recipients(vec![Box::new(recipient)])
/// # let encryptor = age::Encryptor::with_recipients(iter::once(&recipient as _))
/// # .expect("we provided a recipient");
/// # let mut encrypted = vec![];
/// # let mut writer = encryptor.wrap_output(
Expand Down
Loading

0 comments on commit 9af4790

Please sign in to comment.