| 69 | } |
| 70 | |
| 71 | func (r *DecryptReader) Read(p []byte) (int, error) { |
| 72 | if len(r.unread) > 0 { |
| 73 | n := copy(p, r.unread) |
| 74 | r.unread = r.unread[n:] |
| 75 | return n, nil |
| 76 | } |
| 77 | if r.err != nil { |
| 78 | return 0, r.err |
| 79 | } |
| 80 | if len(p) == 0 { |
| 81 | return 0, nil |
| 82 | } |
| 83 | |
| 84 | last, err := r.readChunk() |
| 85 | if err != nil { |
| 86 | r.err = err |
| 87 | return 0, err |
| 88 | } |
| 89 | |
| 90 | n := copy(p, r.unread) |
| 91 | r.unread = r.unread[n:] |
| 92 | |
| 93 | if last { |
| 94 | // Ensure there is an EOF after the last chunk as expected. In other |
| 95 | // words, check for trailing data after a full-length final chunk. |
| 96 | // Hopefully, the underlying reader supports returning EOF even if it |
| 97 | // had previously returned an EOF to ReadFull. |
| 98 | if _, err := r.src.Read(make([]byte, 1)); err == nil { |
| 99 | r.err = errors.New("trailing data after end of encrypted file") |
| 100 | } else if err != io.EOF { |
| 101 | r.err = fmt.Errorf("non-EOF error reading after end of encrypted file: %w", err) |
| 102 | } else { |
| 103 | r.err = io.EOF |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | return n, nil |
| 108 | } |
| 109 | |
| 110 | // readChunk reads the next chunk of ciphertext from r.src and makes it available |
| 111 | // in r.unread. last is true if the chunk was marked as the end of the message. |