diff --git a/envelop/envelop.go b/envelop/envelop.go index 84e4693..f054001 100644 --- a/envelop/envelop.go +++ b/envelop/envelop.go @@ -13,10 +13,10 @@ type Payload interface { GetAlgorithm() string GetMode() string GetHashMethod() string - GetPayloadData() io.Reader + GetPayloadData() (io.Reader, error) } -type Encryptor interface { +type PublicKeyEncryptor interface { Encrypt(data []byte) ([]byte, error) } @@ -24,17 +24,25 @@ type Signer interface { Sign(data []byte) ([]byte, error) } +func NewEnveloper(publicKeyEncryptor PublicKeyEncryptor, payload Payload, signer Signer) *Enveloper { + return &Enveloper{ + publicKeyEncryptor: publicKeyEncryptor, + payload: payload, + signer: signer, + } +} + type Enveloper struct { - encryptor Encryptor - payload Payload - signer Signer - EncryptedKey []byte - Signature []byte - Metadata *Metadata + publicKeyEncryptor PublicKeyEncryptor + payload Payload + signer Signer + EncryptedKey []byte + Signature []byte + Metadata *Metadata } func (this *Enveloper) EncryptKey() ([]byte, error) { - return this.encryptor.Encrypt(this.payload.GetKey()) + return this.publicKeyEncryptor.Encrypt(this.payload.GetKey()) } func (this *Enveloper) SignPayload() ([]byte, error) { @@ -66,8 +74,12 @@ func (this *Enveloper) WritePayload(z *zip.Writer) error { if err != nil { return err } - _, err = io.Copy(dataWriter, this.payload.GetPayloadData()) - return err + if r, err := this.payload.GetPayloadData(); err != nil { + return err + } else if _, err = io.Copy(dataWriter, r); err != nil { + return err + } + return nil } func (this *Enveloper) WriteMetadata(z *zip.Writer) error { diff --git a/envelop/envelop_test.go b/envelop/envelop_test.go index 607434a..9d2fea4 100644 --- a/envelop/envelop_test.go +++ b/envelop/envelop_test.go @@ -4,15 +4,12 @@ import ( "archive/zip" "bytes" "errors" - "fmt" "github.com/didiercrunch/filou/helper" "io" "reflect" "testing" ) -var _ = fmt.Print - type mockPayload struct { MethodsCall []string } @@ -77,13 +74,13 @@ func (this *mockPayload) GetHashMethod() string { return theHashMethodUsedInThePayLoad } -func (this *mockPayload) GetPayloadData() io.Reader { +func (this *mockPayload) GetPayloadData() (io.Reader, error) { this.addMethodCall("GetPayloadData") someData := `some data must be here. In reality, the data would be the encrypted payload. This will be the big chunk of the data. ` - return bytes.NewReader([]byte(someData)) + return bytes.NewReader([]byte(someData)), nil } type mockEncryptor struct{} @@ -110,8 +107,8 @@ func (this *mockSigner) Sign(data []byte) ([]byte, error) { func TestEncryptKey(t *testing.T) { env := &Enveloper{ - encryptor: &mockEncryptor{}, - payload: newMockPayload(), + publicKeyEncryptor: &mockEncryptor{}, + payload: newMockPayload(), } if enc, err := env.EncryptKey(); err != nil { t.Error(err) @@ -121,11 +118,7 @@ func TestEncryptKey(t *testing.T) { } func TestCreateEnvelopCompletelyEncryptKey(t *testing.T) { - env := &Enveloper{ - encryptor: &mockEncryptor{}, - payload: newMockPayload(), - signer: &mockSigner{}, - } + env := NewEnveloper(&mockEncryptor{}, newMockPayload(), &mockSigner{}) if err := env.CreateEnvelopCompletely(); err != nil { t.Error(err) } @@ -147,11 +140,7 @@ func TestSignPayload(t *testing.T) { } func TestCreateEnvelopCompletelySignHash(t *testing.T) { - env := &Enveloper{ - payload: newMockPayload(), - encryptor: &mockEncryptor{}, - signer: &mockSigner{}, - } + env := NewEnveloper(&mockEncryptor{}, newMockPayload(), &mockSigner{}) if err := env.CreateEnvelopCompletely(); err != nil { t.Error(err) } @@ -176,9 +165,9 @@ func TestCreateMetadata(t *testing.T) { func TestCreateEnvelopCompletelyMetadata(t *testing.T) { env := &Enveloper{ - encryptor: &mockEncryptor{}, - payload: newMockPayload(), - signer: &mockSigner{}, + publicKeyEncryptor: &mockEncryptor{}, + payload: newMockPayload(), + signer: &mockSigner{}, } if err := env.CreateEnvelopCompletely(); err != nil { t.Error(err) @@ -190,9 +179,9 @@ func TestCreateEnvelopCompletelyMetadata(t *testing.T) { func TestWriteToWriter(t *testing.T) { env := &Enveloper{ - payload: newMockPayload(), - signer: &mockSigner{}, - encryptor: &mockEncryptor{}, + payload: newMockPayload(), + signer: &mockSigner{}, + publicKeyEncryptor: &mockEncryptor{}, } w := helper.NewMockIoWriter() if err := env.WriteToWriter(w); err != nil { @@ -211,9 +200,9 @@ func TestWriteToWriter(t *testing.T) { func TestMethodOrder(t *testing.T) { mockPayload := newMockPayload() env := &Enveloper{ - payload: mockPayload, - signer: &mockSigner{}, - encryptor: &mockEncryptor{}, + payload: mockPayload, + signer: &mockSigner{}, + publicKeyEncryptor: &mockEncryptor{}, } w := helper.NewMockIoWriter() if err := env.WriteToWriter(w); err != nil { diff --git a/integration/enveloppayload_test.go b/integration/enveloppayload_test.go new file mode 100644 index 0000000..240dd4b --- /dev/null +++ b/integration/enveloppayload_test.go @@ -0,0 +1,39 @@ +package integration + +import ( + "bytes" + "testing" + + "github.com/didiercrunch/filou/envelop" + "github.com/didiercrunch/filou/payload" +) + +type mockEncryptor struct{} + +func (this *mockEncryptor) Encrypt(data []byte) ([]byte, error) { + // cesar encryption! + ret := make([]byte, len(data)) + for i, d := range data { + ret[i] = d + 3 // modulo is implicit + } + return ret, nil +} + +type mockSigner struct{} + +func (this *mockSigner) Sign(data []byte) ([]byte, error) { + // a slice with the sum of the data plus a "secret" value + var sum byte = 36 + for _, d := range data { + sum += d + } + return []byte{sum}, nil +} + +func TestPayloadCanBeUseInEnvelop(t *testing.T) { + payload_ := payload.GetDefaultPayload(bytes.NewBufferString("some data to encrypt")) + envelop := envelop.NewEnveloper(&mockEncryptor{}, payload_, &mockSigner{}) + if envelop == nil { + t.Fail() + } +} diff --git a/payload/payload.go b/payload/payload.go index 350044e..f54e4ce 100644 --- a/payload/payload.go +++ b/payload/payload.go @@ -3,6 +3,7 @@ package payload import ( "archive/zip" "crypto/cipher" + "crypto/rand" "encoding/json" "io" ) @@ -21,6 +22,16 @@ type Payload struct { Hash []byte } +func GetDefaultPayload(dataSource io.Reader) *Payload { + return &Payload{ + DataSource: dataSource, + Random: rand.Reader, + HashMethod: SHA512, + Block: AES256, + BlockMode: OFB, + } +} + type payloadWriter struct { Reader io.Reader Pipewriter io.WriteCloser diff --git a/payload/payload_test.go b/payload/payload_test.go index 7207c60..335c5c3 100644 --- a/payload/payload_test.go +++ b/payload/payload_test.go @@ -141,5 +141,27 @@ func TestGetPayloadData(t *testing.T) { fmt.Println(p.GetHash()) errorC <- errors.New("hash has not been computed") } +} +func TestGetDefaultPayload(t *testing.T) { + p := GetDefaultPayload(bytes.NewBufferString("some data to encrypt")) + r, err := p.GetPayloadData() + if err != nil { + t.Error(err) + return + } + errorC := make(chan error) + go func(errorC chan error) { + if _, err := ioutil.ReadAll(r); err != nil { + errorC <- err + } + errorC <- nil + }(errorC) + + if err := <-errorC; err != nil { + t.Error(err) + } else if len(p.GetHash()) != 512/8 { + fmt.Println(p.GetHash()) + errorC <- errors.New("hash has not been computed") + } }