From 112b06257147ef7e771e49643046554890602f8a Mon Sep 17 00:00:00 2001 From: "didier.amyot" Date: Sat, 13 Sep 2014 13:41:44 -0700 Subject: [PATCH] so many things --- doc/fileformat.md | 64 ++++++++++- encrypter/encrypter.go | 72 +------------ encrypter/encrypter_test.go | 204 ------------------------------------ keys/keys_test.go | 17 ++- 4 files changed, 70 insertions(+), 287 deletions(-) delete mode 100644 encrypter/encrypter_test.go diff --git a/doc/fileformat.md b/doc/fileformat.md index fa782c4..5aaf899 100644 --- a/doc/fileformat.md +++ b/doc/fileformat.md @@ -2,15 +2,11 @@ ### public key Note that any private key are a public key. -~~~ - -~~~ ### private key - ### cypher format We use the `.cyp` file extension for the encrypted file. A .cyp is nothing @@ -22,4 +18,62 @@ else than a zip file containing the following shit. * mode * encrypted symetric key * hash of the encrypted data (always use full for validation) -3. a 'signature' file with the signature of the `meta_data.yml` file \ No newline at end of file +3. a 'signature' file with the signature of the `meta_data.yml` filefunc (this *RsaSha512) encrypt() ([]byte, error) { + +} + + +~~~ + + _____________________________________________________________________ + | + | Envelop: zip file, no compression, no encryption + | _________________________________________________________________ + | | + | | Paiload key: cyphered by target pulic key + | |______________________________________________________________ + | + | _____________________________________________________________________ + | | + | | Envelop meta data: encryption type, mode, Paiload signature (yaml) + | |________________________________________________________________________ + | + | ________________________________________________________________________ + | | + | | Paiload: Zip file, no compression, symetrcally encrypted + | | _________________________________________________________________ + | | | + | | | paiload intern metadata: Data signature, sender, message,... + | | |_________________________________________________________________ + | | + | | _________________________________________________________________ + | | | + | | | Data: Zip file, high compression + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | | + | | |____________________________________________________________________ + | | + | |_________________________________________________________________________ + | + |______________________________________________________________________________ + +~~~ \ No newline at end of file diff --git a/encrypter/encrypter.go b/encrypter/encrypter.go index b44f2b7..0afc5ad 100644 --- a/encrypter/encrypter.go +++ b/encrypter/encrypter.go @@ -1,77 +1,13 @@ package encrypter import ( - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "github.com/didiercrunch/ecrypto/keys" "io" ) -type FileEncrypter struct { - PublicKey keys.PublicKey - PrivateKey keys.PrivateKey - InputPath string - OutputPath string - randomReader io.Reader - - iv []byte - key []byte +type StreamEncrypter interface { + EncrypeReaderToWriter(clearInput io.Reader, encryptedOutput io.Writer) } -func NewEncrypter() *FileEncrypter { - ret := new(FileEncrypter) - ret.randomReader = rand.Reader - return ret -} - -func (this *FileEncrypter) createSymetricKey(size int) ([]byte, error) { - key := make([]byte, size) - _, err := io.ReadFull(this.randomReader, key) - return key, err -} - -func (this *FileEncrypter) getCypherBlock() (cipher.Block, error) { - var err error - this.key, err = this.createSymetricKey(32) - if err != nil { - return nil, err - } - return aes.NewCipher(this.key) -} - -func (this *FileEncrypter) createIV(block cipher.Block) (iv []byte, err error) { - return this.createSymetricKey(block.BlockSize()) -} - -func (this *FileEncrypter) createStreamMode(block cipher.Block) (stream cipher.Stream, err error) { - this.iv, err = this.createIV(block) - if err != nil { - return nil, err - } - return cipher.NewOFB(block, this.iv), err -} - -func (this *FileEncrypter) createFileHandlerAndCypherBlock() (stream cipher.Stream, err error) { - cypherBlock, err := this.getCypherBlock() - if err != nil { - return nil, err - } - return this.createStreamMode(cypherBlock) -} - -func (this *FileEncrypter) encrypeReaderToWriter(clearInput io.Reader, encryptedOutput io.Writer) error { - stream, err := this.createFileHandlerAndCypherBlock() - if err != nil { - return err - } - writer := &cipher.StreamWriter{S: stream, W: encryptedOutput} - if _, err := io.Copy(writer, clearInput); err != nil { - return err - } - return nil -} - -func (this *FileEncrypter) Encrypt() error { - return nil +type StreamSigner interface { + SignStream(input io.Reader) ([]byte, error) } diff --git a/encrypter/encrypter_test.go b/encrypter/encrypter_test.go deleted file mode 100644 index a251f4b..0000000 --- a/encrypter/encrypter_test.go +++ /dev/null @@ -1,204 +0,0 @@ -package encrypter - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "fmt" - "reflect" - "strings" - "testing" -) - -var _ = fmt.Print - -type mockIoWriter struct { - state []byte -} - -func (this *mockIoWriter) Write(p []byte) (n int, err error) { - this.state = append(this.state, p...) - return len(p), nil -} - -func (this *mockIoWriter) String() string { - return string(this.state) -} - -func newMockIoWriter() *mockIoWriter { - return &mockIoWriter{make([]byte, 0, 1024)} -} - -func (this *mockIoWriter) Length() int { - return len(this.state) -} - -func (this *mockIoWriter) Bytes() []byte { - return this.state -} - -func range_(length int) []byte { - ret := make([]byte, length) - for i, _ := range ret { - ret[i] = byte(i) - } - return ret -} -func fromRange(from, to int) []byte { - ret := make([]byte, to-from) - for i, _ := range ret { - ret[i] = byte(i + from) - } - return ret -} - -func createMockRandomData(length int) []byte { - ret := make([]byte, length) - for i, _ := range ret { - ret[i] = byte(i) - } - return ret -} - -func NewMockEncrypter() *FileEncrypter { - ret := new(FileEncrypter) - mockRandomData := createMockRandomData(1024) - ret.randomReader = bytes.NewReader(mockRandomData) - return ret -} - -func TestCreateSymetricKey(t *testing.T) { - c := NewMockEncrypter() - key, e := c.createSymetricKey(512) - if e != nil { - t.Error(e) - } else if len(key) != 512 { - t.Error("bad key lenght") - } else if !reflect.DeepEqual(key, createMockRandomData(512)) { - t.Fail() - } -} - -func TestGetCypherBlock(t *testing.T) { - c := NewMockEncrypter() - if c.key != nil { - t.Error("expected nil key at this point") - } - block, err := c.getCypherBlock() - if err != nil { - t.Error(err) - } - if block.BlockSize() != 16 { - t.Fail() - } - src := createMockRandomData(16) - dst := make([]byte, 16) - expected := []byte{90, 110, 4, 87, 8, 251, 113, 150, 240, 46, 85, 61, 2, 195, 166, 146} - - block.Encrypt(dst, src) - if !reflect.DeepEqual(dst, expected) { - t.Error("bad aes encryption") - } - if !reflect.DeepEqual(c.key, range_(32)) { - t.Error("bad key", c.key) - } -} - -func TestNewEncrypter(t *testing.T) { - c := NewEncrypter() - if c.randomReader != rand.Reader { - t.Fail() - } -} - -func TestCreateIV(t *testing.T) { - m := NewMockEncrypter() - b, err := aes.NewCipher([]byte("example key 1234")) - if err != nil { - t.Error(err) - return - } - iv, err := m.createIV(b) - if err != nil { - t.Error(err) - return - } - expt := range_(16) - if !reflect.DeepEqual(iv, expt) { - t.Error("bad iv", iv) - } -} - -func TestCreateStreamMode(t *testing.T) { - m := NewMockEncrypter() - if m.iv != nil { - t.Error("expected nil iv at first") - } - b, err := aes.NewCipher([]byte("example key 1234")) - if err != nil { - t.Error(err) - return - } - _, err = m.createStreamMode(b) - if err != nil { - t.Error(err) - return - } - exptIv := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} - if !reflect.DeepEqual(m.iv, exptIv) { - t.Error("bad iv", m.iv) - } -} - -func TestCreateFileHandlerAndCypherBlock(t *testing.T) { - m := NewMockEncrypter() - if m.iv != nil { - t.Error("expected nil iv at first") - } - - _, err := m.createFileHandlerAndCypherBlock() - if err != nil { - t.Error(err) - } - if !reflect.DeepEqual(m.key, range_(32)) { - t.Error("bad key", m.key) - } - if !reflect.DeepEqual(m.iv, fromRange(32, 32+16)) { - t.Error("bad iv", m.iv) - } -} - -func TestSimpleEncrypeReaderToWriter(t *testing.T) { - reader := strings.NewReader("some plain text") - writer := newMockIoWriter() - m := NewMockEncrypter() - if err := m.encrypeReaderToWriter(reader, writer); err != nil { - t.Error(err) - } -} - -func decryptEncryptedTextWithAESAlgorithmAndOFBMode(key, iv, encryptedText []byte) (string, error) { - block, err := aes.NewCipher(key) - if err != nil { - return "", err - } - stream := cipher.NewOFB(block, iv) - ret := make([]byte, len(encryptedText)) - stream.XORKeyStream(ret, encryptedText) - return string(ret), nil -} - -func TestEncryptDecrypt(t *testing.T) { - reader := strings.NewReader("some plain text") - writer := newMockIoWriter() - m := NewMockEncrypter() - if err := m.encrypeReaderToWriter(reader, writer); err != nil { - t.Error(err) - } - if plaintext2, err := decryptEncryptedTextWithAESAlgorithmAndOFBMode(m.key, m.iv, writer.Bytes()); err != nil { - t.Error(err) - } else if string(plaintext2) != "some plain text" { - t.Error("bad encryption/decryption process") - } -} diff --git a/keys/keys_test.go b/keys/keys_test.go index 87c9790..ab0205e 100644 --- a/keys/keys_test.go +++ b/keys/keys_test.go @@ -3,17 +3,14 @@ package keys import ( "crypto/rsa" "encoding/json" + . "github.com/didiercrunch/ecrypto/helper" "math/big" "reflect" "testing" ) -func b(x int64) *big.Int { - return big.NewInt(x) -} - func TestGetDefaultRSAPublicKey(t *testing.T) { - key := &rsa.PublicKey{b(31 * 11), 3} + key := &rsa.PublicKey{B(31 * 11), 3} pk := GetDefaultRSAPublicKey(key) if big.NewInt(31*11).Cmp(pk.Key.N) != 0 { @@ -26,9 +23,9 @@ func TestGetDefaultRSAPublicKey(t *testing.T) { func TestGetDefaultRSAPrivateKey(t *testing.T) { privKey := &rsa.PrivateKey{ - rsa.PublicKey{b(3 * 11), 7}, - b(3), - []*big.Int{b(3), b(11)}, + rsa.PublicKey{B(3 * 11), 7}, + B(3), + []*big.Int{B(3), B(11)}, rsa.PrecomputedValues{}, } pk, err := GetDefaultRSAPrivateKey(privKey) @@ -50,7 +47,7 @@ func TestGetDefaultRSAPrivateKey(t *testing.T) { } func TestRSAPrivateKeyJsonification(t *testing.T) { - key := &RSAPrivateKey{b(1023), b(2112), b(328723), b(2332), 89} + key := &RSAPrivateKey{B(1023), B(2112), B(328723), B(2332), 89} data, err := json.Marshal(key) if err != nil { t.Error(err) @@ -67,7 +64,7 @@ func TestRSAPrivateKeyJsonification(t *testing.T) { } func TestRSAPublicKeyJsonification(t *testing.T) { - key := &RSAPublicKey{b(1023), 89} + key := &RSAPublicKey{B(1023), 89} data, err := json.Marshal(key) if err != nil { t.Error(err)