Change how the password is set on the FileHeader.

A new field on the FileHeader struct called Password
of type PasswordFn will be set when either reading
or writing a password protected zip. The previous
method was unsuitable due to the ambiguity of
an empty password "" and no password. This new
way can now differentiate the two.
This commit is contained in:
alexmullins 2015-11-26 18:43:22 -06:00
parent e384fc2faf
commit 5a264afc2d
3 changed files with 14 additions and 11 deletions

View File

@ -278,7 +278,7 @@ func newDecryptionReader(r *io.SectionReader, f *File) (io.Reader, error) {
salt := saltpwvv[:saltLen] salt := saltpwvv[:saltLen]
pwvv := saltpwvv[saltLen : saltLen+2] pwvv := saltpwvv[saltLen : saltLen+2]
// generate keys // generate keys
decKey, authKey, pwv := generateKeys(f.password, salt, keyLen) decKey, authKey, pwv := generateKeys(f.Password(), salt, keyLen)
// check password verifier (pwv) // check password verifier (pwv)
// Change to use crypto/subtle for constant time comparison // Change to use crypto/subtle for constant time comparison
if !checkPasswordVerification(pwv, pwvv) { if !checkPasswordVerification(pwv, pwvv) {

View File

@ -7,6 +7,10 @@ import (
"testing" "testing"
) )
var pwFn = func() []byte {
return []byte("golang")
}
// Test simple password reading. // Test simple password reading.
func TestPasswordSimple(t *testing.T) { func TestPasswordSimple(t *testing.T) {
file := "hello-aes.zip" file := "hello-aes.zip"
@ -26,7 +30,7 @@ func TestPasswordSimple(t *testing.T) {
if f.Method != 0 { if f.Method != 0 {
t.Errorf("Expected %s to have its Method set to 0.", file) t.Errorf("Expected %s to have its Method set to 0.", file)
} }
f.SetPassword([]byte("golang")) f.Password = pwFn
rc, err := f.Open() rc, err := f.Open()
if err != nil { if err != nil {
t.Errorf("Expected to open the readcloser: %v.", err) t.Errorf("Expected to open the readcloser: %v.", err)
@ -57,7 +61,7 @@ func TestPasswordHelloWorldAes(t *testing.T) {
if !f.IsEncrypted() { if !f.IsEncrypted() {
t.Errorf("Expected %s to be encrypted.", f.FileInfo().Name) t.Errorf("Expected %s to be encrypted.", f.FileInfo().Name)
} }
f.SetPassword([]byte("golang")) f.Password = pwFn
rc, err := f.Open() rc, err := f.Open()
if err != nil { if err != nil {
t.Errorf("Expected to open readcloser: %v", err) t.Errorf("Expected to open readcloser: %v", err)
@ -87,7 +91,7 @@ func TestPasswordMacbethAct1(t *testing.T) {
if !f.IsEncrypted() { if !f.IsEncrypted() {
t.Errorf("Expected %s to be encrypted.", f.Name) t.Errorf("Expected %s to be encrypted.", f.Name)
} }
f.SetPassword([]byte("golang")) f.Password = pwFn
rc, err := f.Open() rc, err := f.Open()
if err != nil { if err != nil {
t.Errorf("Expected to open readcloser: %v", err) t.Errorf("Expected to open readcloser: %v", err)
@ -127,7 +131,7 @@ func TestPasswordAE1BadCRC(t *testing.T) {
if !f.IsEncrypted() { if !f.IsEncrypted() {
t.Errorf("Expected zip to be encrypted") t.Errorf("Expected zip to be encrypted")
} }
f.SetPassword([]byte("golang")) f.Password = pwFn
rc, err := f.Open() rc, err := f.Open()
if err != nil { if err != nil {
t.Errorf("Expected the readcloser to open.") t.Errorf("Expected the readcloser to open.")
@ -158,7 +162,7 @@ func TestPasswordTamperedData(t *testing.T) {
if !f.IsEncrypted() { if !f.IsEncrypted() {
t.Errorf("Expected zip to be encrypted") t.Errorf("Expected zip to be encrypted")
} }
f.SetPassword([]byte("golang")) f.Password = pwFn
rc, err := f.Open() rc, err := f.Open()
if err != nil { if err != nil {
t.Errorf("Expected the readcloser to open.") t.Errorf("Expected the readcloser to open.")

View File

@ -94,15 +94,14 @@ type FileHeader struct {
Comment string Comment string
// encryption fields // encryption fields
password []byte Password PasswordFn // The password to use when reading/writing
ae uint16 ae uint16
aesStrength byte aesStrength byte
} }
// SetPassword must be called before calling Open on the file. // PasswordFn is a function that returns the password
func (f *FileHeader) SetPassword(password []byte) { // as a byte slice
f.password = password type PasswordFn func() []byte
}
// IsEncrypted indicates whether this file's data is encrypted. // IsEncrypted indicates whether this file's data is encrypted.
func (f *FileHeader) IsEncrypted() bool { func (f *FileHeader) IsEncrypted() bool {