mirror of
https://github.com/FiloSottile/age.git
synced 2025-12-23 13:35:14 +00:00
age: wrap decryption errors through and add armor.Error
This commit is contained in:
4
age.go
4
age.go
@@ -179,7 +179,7 @@ func Decrypt(src io.Reader, identities ...Identity) (io.Reader, error) {
|
|||||||
|
|
||||||
hdr, payload, err := format.Parse(src)
|
hdr, payload, err := format.Parse(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read header: %v", err)
|
return nil, fmt.Errorf("failed to read header: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stanzas := make([]*Stanza, 0, len(hdr.Recipients))
|
stanzas := make([]*Stanza, 0, len(hdr.Recipients))
|
||||||
@@ -212,7 +212,7 @@ func Decrypt(src io.Reader, identities ...Identity) (io.Reader, error) {
|
|||||||
|
|
||||||
nonce := make([]byte, streamNonceSize)
|
nonce := make([]byte, streamNonceSize)
|
||||||
if _, err := io.ReadFull(payload, nonce); err != nil {
|
if _, err := io.ReadFull(payload, nonce); err != nil {
|
||||||
return nil, fmt.Errorf("failed to read nonce: %v", err)
|
return nil, fmt.Errorf("failed to read nonce: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return stream.NewReader(streamKey(fileKey, nonce), payload)
|
return stream.NewReader(streamKey(fileKey, nonce), payload)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"filippo.io/age/internal/format"
|
"filippo.io/age/internal/format"
|
||||||
@@ -90,7 +91,7 @@ func (r *armoredReader) Read(p []byte) (int, error) {
|
|||||||
line, err := r.r.ReadBytes('\n')
|
line, err := r.r.ReadBytes('\n')
|
||||||
if err != nil && len(line) == 0 {
|
if err != nil && len(line) == 0 {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
err = errors.New("invalid armor: unexpected EOF")
|
err = io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -103,7 +104,7 @@ func (r *armoredReader) Read(p []byte) (int, error) {
|
|||||||
return 0, r.setErr(err)
|
return 0, r.setErr(err)
|
||||||
}
|
}
|
||||||
if string(line) != Header {
|
if string(line) != Header {
|
||||||
return 0, r.setErr(errors.New("invalid armor first line: " + string(line)))
|
return 0, r.setErr(fmt.Errorf("invalid first line: %q", line))
|
||||||
}
|
}
|
||||||
r.started = true
|
r.started = true
|
||||||
}
|
}
|
||||||
@@ -115,12 +116,12 @@ func (r *armoredReader) Read(p []byte) (int, error) {
|
|||||||
return 0, r.setErr(io.EOF)
|
return 0, r.setErr(io.EOF)
|
||||||
}
|
}
|
||||||
if len(line) > format.ColumnsPerLine {
|
if len(line) > format.ColumnsPerLine {
|
||||||
return 0, r.setErr(errors.New("invalid armor: column limit exceeded"))
|
return 0, r.setErr(errors.New("column limit exceeded"))
|
||||||
}
|
}
|
||||||
r.unread = r.buf[:]
|
r.unread = r.buf[:]
|
||||||
n, err := base64.StdEncoding.Strict().Decode(r.unread, line)
|
n, err := base64.StdEncoding.Strict().Decode(r.unread, line)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, r.setErr(errors.New("invalid armor: " + err.Error()))
|
return 0, r.setErr(err)
|
||||||
}
|
}
|
||||||
r.unread = r.unread[:n]
|
r.unread = r.unread[:n]
|
||||||
|
|
||||||
@@ -130,7 +131,7 @@ func (r *armoredReader) Read(p []byte) (int, error) {
|
|||||||
return 0, r.setErr(err)
|
return 0, r.setErr(err)
|
||||||
}
|
}
|
||||||
if string(line) != Footer {
|
if string(line) != Footer {
|
||||||
return 0, r.setErr(errors.New("invalid armor closing line: " + string(line)))
|
return 0, r.setErr(fmt.Errorf("invalid closing line: %q", line))
|
||||||
}
|
}
|
||||||
r.err = io.EOF
|
r.err = io.EOF
|
||||||
}
|
}
|
||||||
@@ -140,7 +141,22 @@ func (r *armoredReader) Read(p []byte) (int, error) {
|
|||||||
return nn, nil
|
return nn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Error) Error() string {
|
||||||
|
return "invalid armor: " + e.err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Error) Unwrap() error {
|
||||||
|
return e.err
|
||||||
|
}
|
||||||
|
|
||||||
func (r *armoredReader) setErr(err error) error {
|
func (r *armoredReader) setErr(err error) error {
|
||||||
|
if err != io.EOF {
|
||||||
|
err = &Error{err}
|
||||||
|
}
|
||||||
r.err = err
|
r.err = err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ func (r *StanzaReader) ReadStanza() (s *Stanza, err error) {
|
|||||||
|
|
||||||
line, err := r.r.ReadBytes('\n')
|
line, err := r.r.ReadBytes('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read line: %v", err)
|
return nil, fmt.Errorf("failed to read line: %w", err)
|
||||||
}
|
}
|
||||||
if !bytes.HasPrefix(line, stanzaPrefix) {
|
if !bytes.HasPrefix(line, stanzaPrefix) {
|
||||||
return nil, fmt.Errorf("malformed stanza opening line: %q", line)
|
return nil, fmt.Errorf("malformed stanza opening line: %q", line)
|
||||||
@@ -195,7 +195,7 @@ func (r *StanzaReader) ReadStanza() (s *Stanza, err error) {
|
|||||||
for {
|
for {
|
||||||
line, err := r.r.ReadBytes('\n')
|
line, err := r.r.ReadBytes('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read line: %v", err)
|
return nil, fmt.Errorf("failed to read line: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := DecodeString(strings.TrimSuffix(string(line), "\n"))
|
b, err := DecodeString(strings.TrimSuffix(string(line), "\n"))
|
||||||
@@ -216,14 +216,20 @@ func (r *StanzaReader) ReadStanza() (s *Stanza, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ParseError string
|
type ParseError struct {
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
func (e ParseError) Error() string {
|
func (e *ParseError) Error() string {
|
||||||
return "parsing age header: " + string(e)
|
return "parsing age header: " + e.err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ParseError) Unwrap() error {
|
||||||
|
return e.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func errorf(format string, a ...interface{}) error {
|
func errorf(format string, a ...interface{}) error {
|
||||||
return ParseError(fmt.Sprintf(format, a...))
|
return &ParseError{fmt.Errorf(format, a...)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse returns the header and a Reader that begins at the start of the
|
// Parse returns the header and a Reader that begins at the start of the
|
||||||
@@ -234,7 +240,7 @@ func Parse(input io.Reader) (*Header, io.Reader, error) {
|
|||||||
|
|
||||||
line, err := rr.ReadString('\n')
|
line, err := rr.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errorf("failed to read intro: %v", err)
|
return nil, nil, errorf("failed to read intro: %w", err)
|
||||||
}
|
}
|
||||||
if line != intro {
|
if line != intro {
|
||||||
return nil, nil, errorf("unexpected intro: %q", line)
|
return nil, nil, errorf("unexpected intro: %q", line)
|
||||||
@@ -244,13 +250,13 @@ func Parse(input io.Reader) (*Header, io.Reader, error) {
|
|||||||
for {
|
for {
|
||||||
peek, err := rr.Peek(len(footerPrefix))
|
peek, err := rr.Peek(len(footerPrefix))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errorf("failed to read header: %v", err)
|
return nil, nil, errorf("failed to read header: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes.Equal(peek, footerPrefix) {
|
if bytes.Equal(peek, footerPrefix) {
|
||||||
line, err := rr.ReadBytes('\n')
|
line, err := rr.ReadBytes('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to read header: %v", err)
|
return nil, nil, fmt.Errorf("failed to read header: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix, args := splitArgs(line)
|
prefix, args := splitArgs(line)
|
||||||
@@ -266,7 +272,7 @@ func Parse(input io.Reader) (*Header, io.Reader, error) {
|
|||||||
|
|
||||||
s, err := sr.ReadStanza()
|
s, err := sr.ReadStanza()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to parse header: %v", err)
|
return nil, nil, fmt.Errorf("failed to parse header: %w", err)
|
||||||
}
|
}
|
||||||
h.Recipients = append(h.Recipients, s)
|
h.Recipients = append(h.Recipients, s)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user