Przeglądaj źródła

Add rwc for block cipher mode

tags/0.9
9seconds 8 lat temu
rodzic
commit
336730b919
2 zmienionych plików z 73 dodań i 3 usunięć
  1. 73
    0
      wrappers/blockcipherrwc.go
  2. 0
    3
      wrappers/streamcipherrwc.go

+ 73
- 0
wrappers/blockcipherrwc.go Wyświetl plik

@@ -0,0 +1,73 @@
1
+package wrappers
2
+
3
+import (
4
+	"bytes"
5
+	"crypto/cipher"
6
+	"io"
7
+
8
+	"github.com/juju/errors"
9
+)
10
+
11
+type BlockCipherReadWriteCloser struct {
12
+	encryptor cipher.BlockMode
13
+	decryptor cipher.BlockMode
14
+	conn      io.ReadWriteCloser
15
+	buf       *bytes.Buffer
16
+}
17
+
18
+func (c *BlockCipherReadWriteCloser) Read(p []byte) (n int, err error) {
19
+	blockSize := c.decryptor.BlockSize()
20
+	if len(p) < blockSize {
21
+		return 0, errors.New("Cannot read less than blocksize")
22
+	}
23
+
24
+	n, err = c.conn.Read(p)
25
+	c.buf.Write(p[:n])
26
+
27
+	wantToRead := c.getFullBlocks(len(p), blockSize)
28
+	haveBlocks := c.getFullBlocks(c.buf.Len(), blockSize)
29
+	if haveBlocks < wantToRead {
30
+		wantToRead = haveBlocks
31
+	}
32
+	wantToRead *= blockSize
33
+
34
+	data := c.buf.Bytes()
35
+	c.decryptor.CryptBlocks(p, data[:wantToRead])
36
+	c.buf = bytes.NewBuffer(data[wantToRead:])
37
+
38
+	return wantToRead, err
39
+}
40
+
41
+func (c *BlockCipherReadWriteCloser) Write(p []byte) (n int, err error) {
42
+	blockSize := c.encryptor.BlockSize()
43
+	if len(p)%blockSize != 0 {
44
+		return 0, errors.New("Write size should be compatible with block size")
45
+	}
46
+
47
+	buf := make([]byte, len(p))
48
+	c.encryptor.CryptBlocks(buf, p)
49
+
50
+	return c.conn.Write(buf)
51
+}
52
+
53
+func (c *BlockCipherReadWriteCloser) Close() error {
54
+	return c.conn.Close()
55
+}
56
+
57
+func (c *BlockCipherReadWriteCloser) getFullBlocks(number, blockSize int) int {
58
+	blocks := number / blockSize
59
+
60
+	if blocks > 0 && number%blockSize != 0 {
61
+		blocks--
62
+	}
63
+
64
+	return blocks
65
+}
66
+
67
+func NewBlockCipherRWC(conn io.ReadWriteCloser, encryptor, decryptor cipher.BlockMode) io.ReadWriteCloser {
68
+	return &BlockCipherReadWriteCloser{
69
+		conn:      conn,
70
+		encryptor: encryptor,
71
+		decryptor: decryptor,
72
+	}
73
+}

+ 0
- 3
wrappers/streamcipherrwc.go Wyświetl plik

@@ -1,7 +1,6 @@
1 1
 package wrappers
2 2
 
3 3
 import (
4
-	"bytes"
5 4
 	"crypto/cipher"
6 5
 	"io"
7 6
 )
@@ -10,7 +9,6 @@ type StreamCipherReadWriteCloser struct {
10 9
 	encryptor cipher.Stream
11 10
 	decryptor cipher.Stream
12 11
 	conn      io.ReadWriteCloser
13
-	rest      *bytes.Buffer
14 12
 }
15 13
 
16 14
 // Read reads from connection
@@ -48,6 +46,5 @@ func NewStreamCipherRWC(conn io.ReadWriteCloser, encryptor, decryptor cipher.Str
48 46
 		conn:      conn,
49 47
 		encryptor: encryptor,
50 48
 		decryptor: decryptor,
51
-		rest:      &bytes.Buffer{},
52 49
 	}
53 50
 }

Ładowanie…
Anuluj
Zapisz