205 lines
4.2 KiB
Go
205 lines
4.2 KiB
Go
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")
|
|
}
|
|
}
|