kunt

golang IRC bot
git clone git://git.2f30.org/kunt
Log | Files | Refs | LICENSE

commit 10f5cee39b8d9ba271e9ffc4bda209a0318ca7b4
parent b8ccc9bb5529e8976db74ed567884c80cb95f62f
Author: sin <sin@2f30.org>
Date:   Tue, 30 Apr 2013 11:34:07 +0100

add blowfish encryption to mapfs

Diffstat:
Msrc/mapfs/mapfs.go | 89++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Asrc/mapfs/mapfs_test.go | 15+++++++++++++++
2 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/src/mapfs/mapfs.go b/src/mapfs/mapfs.go @@ -3,6 +3,7 @@ package mapfs import ( "bytes" + "code.google.com/p/go.crypto/blowfish" "fmt" "math/rand" "os" @@ -19,6 +20,8 @@ type Mapfs struct { dict map[int]mapfsVal lock sync.Mutex cacheOnly bool + encrypt bool + cipher *blowfish.Cipher } type mapfsVal struct { @@ -37,6 +40,11 @@ func MakeMapIter(m *Mapfs) MapIter { v, ok := m.dict[i] if ok { i++ + if m.encrypt { + pt := make([]byte, len(v.data)) + m.cipher.Decrypt(pt, v.data) + return i - 1, pt, true + } return i - 1, v.data, true } i++ @@ -52,9 +60,25 @@ func NewMapfs(name string, path string, prefix string) *Mapfs { prefix: prefix, dict: make(map[int]mapfsVal), cacheOnly: false, + encrypt: false, + cipher: nil, } } +func NewEncryptedMapfs(name string, path string, prefix string, key string) *Mapfs { + c, _ := blowfish.NewCipher([]byte(key)) + return &Mapfs{ + name: name, + path: path, + prefix: prefix, + dict: make(map[int]mapfsVal), + cacheOnly: false, + encrypt: true, + cipher: c, + } + +} + // Sync dirty entries to disk func (m *Mapfs) Sync() error { m.lock.Lock() @@ -69,8 +93,13 @@ func (m *Mapfs) Sync() error { return err } m.dict[k] = mapfsVal{false, v.data} - fmt.Printf("Synced entry (%d, %v)\n", - k, v.data) + if !m.encrypt { + fmt.Printf("Synced entry (%d, %v)\n", + k, v.data) + } else { + fmt.Printf("Synced entry (%d, %v)\n", + k, "ENCRYPTED") + } } } return nil @@ -151,8 +180,13 @@ func (m *Mapfs) CountMatches(buf []byte) int { m.lock.Lock() defer m.lock.Unlock() i := 0 + raw := buf + if m.encrypt { + ct := m.encryptbuf(buf) + raw = ct + } for _, v := range m.dict { - if bytes.Equal(v.data, buf) { + if bytes.Equal(v.data, raw) { i++ } } @@ -169,6 +203,11 @@ func (m *Mapfs) Put(key int, buf []byte) error { if ok { return fmt.Errorf("Key %d already in use", key) } + if m.encrypt { + ct := m.encryptbuf(buf) + m.dict[key] = mapfsVal{true, ct} + return nil + } m.dict[key] = mapfsVal{true, buf} return nil } @@ -177,6 +216,13 @@ func (m *Mapfs) Put(key int, buf []byte) error { func (m *Mapfs) Append(buf []byte) (int, error) { m.lock.Lock() defer m.lock.Unlock() + if m.encrypt { + ct := m.encryptbuf(buf) + key := len(m.dict) + m.dict[key] = mapfsVal{true, ct} + return key, nil + } + key := len(m.dict) m.dict[key] = mapfsVal{true, buf} return key, nil @@ -193,6 +239,10 @@ func (m *Mapfs) Get(key int) ([]byte, error) { if !ok { return nil, fmt.Errorf("No entry with key: %d", key) } + if m.encrypt { + pt := m.decryptbuf(val.data) + return pt, nil + } return val.data, nil } @@ -204,6 +254,10 @@ func (m *Mapfs) Rand() ([]byte, int) { for k, _ := range m.dict { if i == idx { val := m.dict[k] + if m.encrypt { + pt := m.decryptbuf(val.data) + return pt, k + } return val.data, k } i++ @@ -225,3 +279,32 @@ func (m *Mapfs) Len() int { defer m.lock.Unlock() return len(m.dict) } + +func (m *Mapfs) encryptbuf(a []byte) []byte { + //pad it + padded := a + diff := len(a) % blowfish.BlockSize + if diff != 0 { + diff = blowfish.BlockSize - diff + } + for i := 0; i < diff; i++ { + padded = append(padded, byte(0x0)) + } + ct := make([]byte, len(padded)) + for i := 0; i < len(a); i += blowfish.BlockSize { + if i+blowfish.BlockSize > len(a) { + m.cipher.Encrypt(ct[i:], padded[i:]) + return ct + } + m.cipher.Encrypt(ct[i:i+blowfish.BlockSize], padded[i:i+blowfish.BlockSize]) + } + return ct +} + +func (m *Mapfs) decryptbuf(a []byte) []byte { + pt := make([]byte, len(a)) + for i := 0; i < len(a); i += blowfish.BlockSize { + m.cipher.Decrypt(pt[i:i+blowfish.BlockSize], a[i:i+blowfish.BlockSize]) + } + return pt +} diff --git a/src/mapfs/mapfs_test.go b/src/mapfs/mapfs_test.go @@ -0,0 +1,15 @@ +package mapfs + +import ( + "testing" +) + +func TestEncryptingFs(t *testing.T) { + mfs := NewEncryptedMapfs("kota", "./", "moufa", "ICEBABY!@#") + test := []byte("sweet plaintext!") //this test will only work without padding + mfs.Append(test) + r0, _ := mfs.Get(0) + if string(r0) != string(test) { //byte equality will fail here(padding) + t.Error("encryption failed got:" + string(r0)) + } +}