summaryrefslogtreecommitdiff
path: root/pkg/server/module/aes.go
diff options
context:
space:
mode:
authorMikhail Osipov <mike.osipov@gmail.com>2020-02-25 01:12:00 +0300
committerMikhail Osipov <mike.osipov@gmail.com>2020-02-25 01:19:34 +0300
commitd7b723c6b132a504a837aa528ca0a66b618e3c6c (patch)
tree1a5e64c9ac7b45cd3e4992a39517fb47603c9046 /pkg/server/module/aes.go
parente93460de418a6973421bac5988b11364ee80e4ea (diff)
add aes module
Diffstat (limited to 'pkg/server/module/aes.go')
-rw-r--r--pkg/server/module/aes.go86
1 files changed, 86 insertions, 0 deletions
diff --git a/pkg/server/module/aes.go b/pkg/server/module/aes.go
new file mode 100644
index 0000000..68dcc7c
--- /dev/null
+++ b/pkg/server/module/aes.go
@@ -0,0 +1,86 @@
+package module
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/md5"
+ "crypto/rand"
+ "io"
+ "tunnel/pkg/server/env"
+ "tunnel/pkg/server/opts"
+ "tunnel/pkg/server/queue"
+)
+
+type aesInfo struct {
+ key []byte
+}
+
+type aesModule struct{}
+
+func (a *aesInfo) Send(rq, wq queue.Q) error {
+ block, err := aes.NewCipher(a.key)
+ if err != nil {
+ return err
+ }
+
+ iv := make([]byte, aes.BlockSize)
+
+ if _, err := rand.Read(iv); err != nil {
+ return err
+ }
+
+ writer := &cipher.StreamWriter{
+ S: cipher.NewOFB(block, iv),
+ W: wq.Writer(),
+ }
+
+ wq <- iv
+
+ return queue.IoCopy(rq.Reader(), writer)
+}
+
+func (a *aesInfo) Recv(rq, wq queue.Q) error {
+ block, err := aes.NewCipher(a.key)
+ if err != nil {
+ return err
+ }
+
+ r := rq.Reader()
+
+ iv := make([]byte, aes.BlockSize)
+
+ if _, err := io.ReadFull(r, iv); err != nil {
+ if err == io.EOF {
+ return nil
+ }
+ return err
+ }
+
+ reader := &cipher.StreamReader{
+ S: cipher.NewOFB(block, iv),
+ R: r,
+ }
+
+ return queue.IoCopy(reader, wq.Writer())
+}
+
+func newAes(env env.Env) *aesInfo {
+ s := getAuthSecret(env)
+ h := md5.Sum([]byte(s))
+
+ a := &aesInfo{key: make([]byte, 16)}
+ copy(a.key, h[:])
+
+ return a
+}
+
+func (m aesModule) Open(env env.Env) (Pipe, Pipe) {
+ a := newAes(env)
+ return a.Send, a.Recv
+}
+
+func init() {
+ register("aes", func(opts.Opts, env.Env) (module, error) {
+ return aesModule{}, nil
+ })
+}