package crypto import ( "bytes" "errors" "io" ) type decryptReader struct { buf []byte rd *bytes.Reader } func (d *decryptReader) Read(dst []byte) (n int, err error) { if d.buf == nil { return 0, io.EOF } n, err = d.rd.Read(dst) if err == io.EOF { d.free() } return } func (d *decryptReader) free() { freeBuffer(d.buf) d.buf = nil } func (d *decryptReader) Close() error { if d == nil || d.buf == nil { return nil } d.free() return nil } func (d *decryptReader) ReadByte() (c byte, err error) { if d.buf == nil { return 0, io.EOF } c, err = d.rd.ReadByte() if err == io.EOF { d.free() } return } func (d *decryptReader) WriteTo(w io.Writer) (n int64, err error) { if d.buf == nil { return 0, errors.New("WriteTo() called on drained reader") } n, err = d.rd.WriteTo(w) d.free() return } // DecryptFrom verifies and decrypts the ciphertext read from rd with ks and // makes it available on the returned Reader. Ciphertext must be in the form IV // || Ciphertext || MAC. In order to correctly verify the ciphertext, rd is // drained, locally buffered and made available on the returned Reader // afterwards. If a MAC verification failure is observed, it is returned // immediately. func DecryptFrom(ks *Key, rd io.Reader) (io.ReadCloser, error) { buf := bytes.NewBuffer(getBuffer()[:0]) _, err := buf.ReadFrom(rd) if err != nil { return (*decryptReader)(nil), err } ciphertext := buf.Bytes() ciphertext, err = Decrypt(ks, ciphertext, ciphertext) if err != nil { freeBuffer(ciphertext) return (*decryptReader)(nil), err } return &decryptReader{buf: ciphertext, rd: bytes.NewReader(ciphertext)}, nil }