Skip to content

Commit

Permalink
Merge pull request #80 from bodgit/issue75
Browse files Browse the repository at this point in the history
Fix failures with encrypted archives
  • Loading branch information
bodgit authored Apr 13, 2023
2 parents 15d9bce + 6580c23 commit 894e8c3
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 13 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ require (
github.com/andybalholm/brotli v1.0.5
github.com/bodgit/plumbing v1.3.0
github.com/bodgit/windows v1.0.1
github.com/connesc/cipherio v0.2.1
github.com/hashicorp/go-multierror v1.1.1
github.com/klauspost/compress v1.16.4
github.com/pierrec/lz4/v4 v4.1.17
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/connesc/cipherio v0.2.1 h1:FGtpTPMbKNNWByNrr9aEBtaJtXjqOzkIXNYJp6OEycw=
github.com/connesc/cipherio v0.2.1/go.mod h1:ukY0MWJDFnJEbXMQtOcn2VmTpRfzcTz4OoVrWGGJZcA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -45,8 +43,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand Down
32 changes: 24 additions & 8 deletions internal/aes7z/reader.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
package aes7z

import (
"bytes"
"crypto/aes"
"crypto/cipher"
"errors"
"io"

"github.com/connesc/cipherio"
)

var errProperties = errors.New("aes7z: not enough properties")

type readCloser struct {
rc io.ReadCloser
br io.Reader
salt, iv []byte
cycles int
cbc cipher.BlockMode
buf bytes.Buffer
}

func (rc *readCloser) Close() error {
var err error
if rc.rc != nil {
err = rc.rc.Close()
rc.rc, rc.br = nil, nil
rc.rc = nil
}

return err
Expand All @@ -34,7 +34,7 @@ func (rc *readCloser) Password(p string) error {
return err
}

rc.br = cipherio.NewBlockReader(rc.rc, cipher.NewCBCDecrypter(block, rc.iv))
rc.cbc = cipher.NewCBCDecrypter(block, rc.iv)

return nil
}
Expand All @@ -44,11 +44,27 @@ func (rc *readCloser) Read(p []byte) (int, error) {
return 0, errors.New("aes7z: Read after Close")
}

if rc.br == nil {
if rc.cbc == nil {
return 0, errors.New("aes7z: no password set")
}

return rc.br.Read(p)
var block [aes.BlockSize]byte

for rc.buf.Len() < len(p) {
if n, err := io.ReadFull(rc.rc, block[:]); err != nil {
if err == io.EOF {
break
}

return n, err
}

rc.cbc.CryptBlocks(block[:], block[:])

_, _ = rc.buf.Write(block[:])
}

return rc.buf.Read(p)
}

// NewReader returns a new AES-256-CBC & SHA-256 io.ReadCloser. The Password
Expand Down Expand Up @@ -78,7 +94,7 @@ func NewReader(p []byte, _ uint64, readers []io.ReadCloser) (io.ReadCloser, erro
}

rc.salt = p[2 : 2+salt]
rc.iv = make([]byte, 16)
rc.iv = make([]byte, aes.BlockSize)
copy(rc.iv, p[2+salt:])

rc.cycles = int(p[0] & 0x3f)
Expand Down
5 changes: 5 additions & 0 deletions reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ func TestOpenReaderWithPassword(t *testing.T) {
file: "t3.7z",
password: "password",
},
{
name: "issue 75",
file: "7zcracker.7z",
password: "876",
},
}

for _, table := range tables {
Expand Down
Binary file added testdata/7zcracker.7z
Binary file not shown.

0 comments on commit 894e8c3

Please sign in to comment.