The extra dependency makes it harder to package age. Temporarily drop it
to facilitate getting v1.0.0 into distributions.
This reverts commit 53ccaf8b71.
It's not clear the convenience for SSH keys is worth having any
implicitly configured identity at all. Will revisit after v1.0.0.
This reverts commit 225044b061.
This is a breaking change, but like the other changes to these
interfaces it should not matter to consumers of the API that don't
implement custom Recipients or Identities, which is all of them so far,
as far as I can tell.
It became clear working on plugins that we might want Recipient to
return multiple recipient stanzas, for example if the plugin recipient
is an alias or a group. The Identity side is less important, but it
might help avoid round-trips and it makes sense to keep things
symmetric.
It was completely useless: the same checks in Match could be implemented
in Unwrap, returning an early ErrIncorrectIdentity.
Not sure why I added it. It felt clever at the time.
The Type() method was a mistake, as proven by the fact that I can remove
it without losing any functionality. It gives special meaning to the
"0th argument" of recipient stanzas, when actually it should be left up
to Recipient implementations to make their own stanzas recognizable to
their Identity counterparts.
More importantly, there are totally reasonable Identity (and probably
Recipient) implementations that don't know their own stanza type in
advance. For example, a proxy plugin.
Concretely, it was only used to special-case "scrypt" recipients, and to
skip invoking Unwrap. The former can be done based on the returned
recipient stanza, and the latter is best avoided entirely: the Identity
should start by looking at the stanza and returning ErrIncorrectIdentity
if it's of the wrong type.
This is a breaking API change. However, we are still in beta, and none
of the public downstreams look like they would be affected, as they only
use Recipient and Identity implementations from this package, they only
use them with the interfaces defined in this package, and they don't
directly use the Type() method.
We are going to reuse the stanza format for IPC in the plugin protocol,
but in that context we need stanzas to be self-closing. Currently they
almost are, but if the body is 0 modulo 48, there is no way to know if
the stanza is over after the last line.
Now, all stanzas have to end with a short line, even if empty.
No ciphertexts generated by age in the past are affected, but 3% of the
ciphertexts generated by rage will now stop working. They are still
supported by rage going forward. If it turns out to be a common issue,
we can add an exception.
Buffering only when the armorFlag is set disregards use cases where data
from a tty stdin is decrypted or where binary data goes to a tty stdout.
Buffering is only necessary if stdin is a tty and stdout is a tty.
Co-authored-by: Filippo Valsorda <hi@filippo.io>
This avoids leaving behind an empty file when an error occurs before we
write the header (for example, because the passphrase is invalid). Do a
best-effort check before taking user input for whether the file exists
so we don't waste user effort. An error might still happen after user
input if other kind of open errors happen (for example, a permission
issue, or disk full).
Fixes#159Fixes#57Closes#169
Most writes in the cmd/age Writer stack are chunk-sized, so
approximately 64KiB. However, the newlineWriter, which splits lines at
64 columns, was doing a Write on the underlying Writer for each line,
making chunks effectively 48 bytes (before base64). There is no
buffering underneath it, so it was resulting in a lot of write syscalls.
Add a reusable bytes.Buffer to buffer the output of each
(*newlineWriter).Write call, and Write it all at once on the
destination.
This makes --armor just 50% slower than plain, instead of 10x.
Fixes#167