Denmaseno vor 7 Jahren
Ursprung
Commit
8fa8e2364e
21 geänderte Dateien mit 827 neuen und 705 gelöschten Zeilen
  1. 5 0
      .gitignore
  2. 0 28
      check-once.go
  3. 0 61
      crypt-aes.go
  4. 0 116
      crypt-rsa.go
  5. 0 148
      dump.go
  6. 0 45
      dump_test.go
  7. 0 24
      encrypt-aes_test.go
  8. 0 48
      exec.go
  9. 0 12
      file.go
  10. 0 30
      json.go
  11. 0 62
      part-writer-data.go
  12. 0 56
      signer.go
  13. 102 0
      src/encrypter/aes.go
  14. 31 0
      src/encrypter/rsa-encrypted.go
  15. 295 0
      src/encrypter/rsa.go
  16. 108 0
      src/signer/signature.go
  17. 83 0
      src/slog/formatter.go
  18. 147 0
      src/slog/slog.go
  19. 8 0
      src/util/util.go
  20. 48 0
      src/vendor/manifest
  21. 0 75
      util.go

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+pkg
+src/vendor/github.com
+src/vendor/golang.org
+src/vendor/google.golang.org
+src/vendor/gopkg.in

+ 0 - 28
check-once.go

@@ -1,28 +0,0 @@
-package util
-
-import "sync"
-
-// CheckOnce struct
-type CheckOnce struct {
-	mutex sync.Mutex
-	done  bool
-}
-
-// IsDone func
-func (c *CheckOnce) IsDone() bool {
-	c.mutex.Lock()
-	defer c.mutex.Unlock()
-
-	return c.done
-}
-
-// Done func
-func (c *CheckOnce) Done(f func()) {
-	c.mutex.Lock()
-	defer c.mutex.Unlock()
-
-	if !c.done {
-		f()
-		c.done = true
-	}
-}

+ 0 - 61
crypt-aes.go

@@ -1,61 +0,0 @@
-package util
-
-import (
-	"crypto/aes"
-	"crypto/cipher"
-	"crypto/rand"
-	"fmt"
-	"io"
-)
-
-// KeyAES func
-func KeyAES() []byte {
-	var err error
-	var key = make([]byte, 32)
-	if _, err = rand.Read(key); err != nil {
-		panic(fmt.Errorf("Error generate aes key\n\n%+v", err))
-	}
-	return key
-}
-
-// EncryptAES func
-func EncryptAES(key, data []byte) []byte {
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-
-	ciphertext := make([]byte, aes.BlockSize+len(data))
-	iv := ciphertext[:aes.BlockSize]
-	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
-		panic(err)
-	}
-
-	stream := cipher.NewCFBEncrypter(block, iv)
-	stream.XORKeyStream(ciphertext[aes.BlockSize:], data)
-
-	return ciphertext
-}
-
-// DecryptAES func
-func DecryptAES(key, ori []byte) []byte {
-	ciphertext := make([]byte, len(ori))
-	copy(ciphertext, ori)
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(fmt.Errorf("Error creating new block cipher\n%v\n", err))
-	}
-
-	if len(ciphertext) < aes.BlockSize {
-		panic(fmt.Errorf("ciphertext too short"))
-	}
-	iv := ciphertext[:aes.BlockSize]
-	ciphertext = ciphertext[aes.BlockSize:]
-
-	stream := cipher.NewCFBDecrypter(block, iv)
-
-	// XORKeyStream can work in-place if the two arguments are the same.
-	stream.XORKeyStream(ciphertext, ciphertext)
-
-	return ciphertext
-}

+ 0 - 116
crypt-rsa.go

@@ -1,116 +0,0 @@
-package util
-
-import (
-	"bytes"
-	"crypto/rand"
-	"crypto/rsa"
-	"crypto/x509"
-)
-
-// KeyRSA func
-func KeyRSA() *rsa.PrivateKey {
-	var privateKey *rsa.PrivateKey
-	var err error
-
-	if privateKey, err = rsa.GenerateKey(rand.Reader, 2048); err != nil {
-		panic(err)
-	}
-
-	return privateKey
-}
-
-// MarshalPublicKey func
-func MarshalPublicKey(key *rsa.PublicKey) []byte {
-	if data, err := x509.MarshalPKIXPublicKey(key); err != nil {
-		panic(err)
-	} else {
-		return data
-	}
-}
-
-// UnmarshalPublicKey func
-func UnmarshalPublicKey(key []byte) *rsa.PublicKey {
-	var kk interface{}
-	var err error
-	if kk, err = x509.ParsePKIXPublicKey(key); err != nil {
-		panic(err)
-	}
-	return kk.(*rsa.PublicKey)
-}
-
-// MarshalPrivateKey func
-func MarshalPrivateKey(key *rsa.PrivateKey) []byte {
-	return x509.MarshalPKCS1PrivateKey(key)
-}
-
-// UnmarshalPrivateKey func
-func UnmarshalPrivateKey(key []byte) *rsa.PrivateKey {
-	var kk *rsa.PrivateKey
-	var err error
-	if kk, err = x509.ParsePKCS1PrivateKey(key); err != nil {
-		panic(err)
-	}
-	return kk
-}
-
-// EncryptRSA func
-func EncryptRSA(key *rsa.PublicKey, data []byte) []byte {
-	var err error
-	klen := key.N.BitLen()/8 - 11
-	if len(data) <= klen {
-		var bb []byte
-		if bb, err = rsa.EncryptPKCS1v15(rand.Reader, key, data); err != nil {
-			panic(err)
-		}
-		return bb
-	}
-	var buf bytes.Buffer
-	var bb []byte
-	for i, w, r := 0, 0, len(data); r > 0; i, r = i+w, r-w {
-		if r <= klen {
-			if bb, err = rsa.EncryptPKCS1v15(rand.Reader, key, data[i:]); err != nil {
-				panic(err)
-			}
-			buf.Write(bb)
-			w = r
-		} else {
-			if bb, err = rsa.EncryptPKCS1v15(rand.Reader, key, data[i:i+klen]); err != nil {
-				panic(err)
-			}
-			buf.Write(bb)
-			w = klen
-		}
-	}
-	return buf.Bytes()
-}
-
-// DecryptRSA func
-func DecryptRSA(key *rsa.PrivateKey, data []byte) []byte {
-	var err error
-	klen := key.N.BitLen() / 8
-	if len(data) <= klen {
-		var bb []byte
-		if bb, err = rsa.DecryptPKCS1v15(rand.Reader, key, data); err != nil {
-			panic(err)
-		}
-		return bb
-	}
-	var buf bytes.Buffer
-	var bb []byte
-	for i, w, r := 0, 0, len(data); r > 0; i, r = i+w, r-w {
-		if r <= klen {
-			if bb, err = rsa.DecryptPKCS1v15(rand.Reader, key, data[i:]); err != nil {
-				panic(err)
-			}
-			buf.Write(bb)
-			w = r
-		} else {
-			if bb, err = rsa.DecryptPKCS1v15(rand.Reader, key, data[i:i+klen]); err != nil {
-				panic(err)
-			}
-			buf.Write(bb)
-			w = klen
-		}
-	}
-	return buf.Bytes()
-}

+ 0 - 148
dump.go

@@ -1,148 +0,0 @@
-package util
-
-import (
-	"bytes"
-	"crypto/rsa"
-	"fmt"
-	"io"
-	"reflect"
-	"strings"
-	"time"
-)
-
-const (
-	// MaxFieldLen const
-	MaxFieldLen = 100
-	// MaxSliceLen const
-	MaxSliceLen = 100
-	tabSpace    = "  "
-)
-
-// Dump value
-func Dump(v interface{}) string {
-	var bb bytes.Buffer
-	fdump(&bb, 0, 0, "", reflect.ValueOf(v))
-	return bb.String()
-}
-
-// Fdump value
-func Fdump(w io.Writer, v interface{}) {
-	fdump(w, 0, 0, "", reflect.ValueOf(v))
-}
-
-func fdump(w io.Writer, rx int, rd int, tab string, value reflect.Value) {
-	rx++
-	if rx > 100 {
-		fmt.Fprint(w, "/* too many recursive */")
-	}
-	if rd > 10 {
-		fmt.Fprint(w, "/* too deep */")
-	}
-	if value.Kind() == reflect.Interface && !value.IsNil() {
-		elm := value.Elem()
-		if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
-			value = elm
-		}
-	}
-	if value.Kind() == reflect.Ptr {
-		value = value.Elem()
-	}
-	if value.Kind() == reflect.String {
-		fmt.Fprintf(w, "\"%s\" /* Type:%s */", value, value.Type().String())
-	} else if kindIn(value.Kind(), reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64) {
-		fmt.Fprintf(w, "%+v /* Type:%s */", value, value.Type().String())
-	} else if kindIn(value.Kind(), reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64) {
-		fmt.Fprintf(w, "%+v /* Type:%s */", value, value.Type().String())
-	} else if value.Kind() == reflect.Struct {
-		if value.CanInterface() {
-			if t, ok := value.Interface().(time.Time); ok {
-				fmt.Fprintf(w, "%s /* Type:%s */", t, value.Type())
-				return
-			}
-		}
-		if value.Type() == reflect.TypeOf(rsa.PublicKey{}) {
-			fmt.Fprintf(w, "- /* Type:%s */", value.Type())
-			return
-		}
-		if value.Type() == reflect.TypeOf(rsa.PrivateKey{}) {
-			fmt.Fprintf(w, "- /* Type:%s */", value.Type())
-			return
-		}
-		ntab := tab + tabSpace
-		fmt.Fprintf(w, "{ /* Type:%v:%s-%s */", value.CanInterface(), value.Kind().String(), value.Type().String())
-		il := value.NumField()
-		for i, j := 0, 0; i < il && i < MaxFieldLen; i++ {
-			tf := value.Type().Field(i)
-			tag := strings.Split(value.Type().Field(i).Tag.Get("dump"), ",")
-			if !InStringSlice("ignore", tag...) {
-				if j > 0 {
-					fmt.Fprintf(w, ",\n%s\"%s\": ", ntab, tf.Name)
-				} else {
-					fmt.Fprintf(w, "\n%s\"%s\": ", ntab, tf.Name)
-				}
-				vf := value.Field(i)
-				fdump(w, rx, rd+1, ntab, vf)
-				j++
-			}
-		}
-		fmt.Fprintf(w, "\n%s}", tab)
-	} else if value.Kind() == reflect.Slice {
-		ntab := tab + tabSpace
-		if value.Type().String() == "[]uint8" {
-			il := value.Len()
-			fmt.Fprintf(w, "[ /* Type:%s Length:%v */\n%s      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n%s0000  ", value.Type().String(), il, ntab, ntab)
-			for i, j := 0, 0; i < il; i++ {
-				if j == 16 {
-					fmt.Fprintf(w, "\n%s%04X  ", ntab, i)
-					j = 1
-				} else {
-					j++
-				}
-				fmt.Fprintf(w, "%02X ", value.Index(i).Interface())
-			}
-			fmt.Fprintf(w, "\n%s]%s", tab, "")
-		} else {
-			fmt.Fprintf(w, "[ /* Type:%s Length:%v */\n%s", value.Type().String(), value.Len(), ntab)
-			il := value.Len()
-			for i := 0; i < il && i < MaxSliceLen; i++ {
-				vi := value.Index(i)
-				if i > 0 {
-					fmt.Fprintf(w, ",\n%s/* Index:%v */ ", ntab, i)
-				} else {
-					fmt.Fprint(w, "/* Index:0 */ ")
-				}
-				fdump(w, rx, rd+1, ntab, vi)
-			}
-			if il > MaxSliceLen {
-				fmt.Fprintf(w, "\n%s/* too many items */", ntab)
-			}
-			fmt.Fprintf(w, "\n%s]%s", tab, "")
-		}
-	} else if value.Kind() == reflect.Map {
-		ntab := tab + tabSpace
-		fmt.Fprintf(w, "{ /* Type:%s */\n%s", value.Type().String(), ntab)
-		keys := value.MapKeys()
-		for k, kv := range keys {
-			if k > 0 {
-				fmt.Fprintf(w, ",\n%s\"%v\": ", ntab, kv)
-			} else {
-				fmt.Fprintf(w, "\"%v\": ", kv)
-			}
-			fdump(w, rx, rd+1, ntab, value.MapIndex(kv))
-		}
-		fmt.Fprintf(w, "\n%s}%s", tab, "")
-	} else if !value.IsValid() {
-		fmt.Fprint(w, "/* NOT-VALID */")
-	} else if value.Type() != nil {
-		fmt.Fprintf(w, "undefined /* Type:%s Value:[%v] */", value.Type().String(), value)
-	}
-}
-
-func kindIn(value reflect.Kind, list ...reflect.Kind) bool {
-	for _, v := range list {
-		if value == v {
-			return true
-		}
-	}
-	return false
-}

+ 0 - 45
dump_test.go

@@ -1,45 +0,0 @@
-package util
-
-import (
-	"crypto/rsa"
-	"fmt"
-	"testing"
-	"time"
-)
-
-type Struct1 struct {
-	Name      string
-	secret    string `dump:"ignore"`
-	Codes     []string
-	Config    map[string]*Address
-	Age       uint
-	Timestamp time.Time
-	key       *rsa.PublicKey
-}
-
-type Address struct {
-	Street string
-	City   string
-}
-
-func (address Address) String() string {
-	return Dump(address)
-}
-
-// TestDump test
-func TestDump(t *testing.T) {
-	t.Logf("dump string(TEST) %s\n", Dump("TEST"))
-	t.Logf("dump int(12) %s\n", Dump(12))
-	config := make(map[string]*Address)
-	config["kampung"] = &Address{"Jalan", "Solo"}
-	config["rumah"] = &Address{"Kampret1", "Jakarta"}
-	config["kantor"] = &Address{"Kampret2", "Jakarta"}
-	t.Logf("dump Struct1{}\n%s\n", Dump(Struct1{"seno", "secret",
-		[]string{"sono", "keling"},
-		config,
-		17,
-		time.Now(),
-		&KeyRSA().PublicKey,
-	}))
-	t.Logf("fmt.Sprintf %s", fmt.Sprintf("HERE\n%v", &Address{"seno", "solo"}))
-}

+ 0 - 24
encrypt-aes_test.go

@@ -1,24 +0,0 @@
-package util
-
-import (
-	"bytes"
-	"testing"
-)
-
-// TestAES test
-func TestAES(t *testing.T) {
-	var bb bytes.Buffer
-	for bb.Len() < 1024 {
-		bb.Write([]byte("this is a very long text. "))
-	}
-	b := bb.Bytes()
-	t.Logf("DATA  %v %s", len(b), string(b))
-	key := KeyAES()
-	x := EncryptAES(key, b)
-	t.Logf("ENC LEN %v", len(x))
-	p := DecryptAES(key, x)
-	t.Logf("PLAIN %v %s", len(p), string(p))
-	if !bytes.Equal(b, p) {
-		t.Errorf("ERROR\n%s\n%s", string(b), string(p))
-	}
-}

+ 0 - 48
exec.go

@@ -1,48 +0,0 @@
-package util
-
-import (
-	"fmt"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"strings"
-	"syscall"
-)
-
-var env []string
-
-func init() {
-	cp, err := filepath.Abs(".")
-	if err != nil {
-		panic(err)
-	}
-	for _, v := range os.Environ() {
-		if strings.HasPrefix(v, "GOPATH=") {
-			env = append(env, v+":"+cp)
-		} else {
-			env = append(env, v)
-		}
-	}
-}
-
-// Exec execute go commang with GOPATH=$GOPATH:`pwd`
-func Exec(params ...string) {
-	var err error
-	fmt.Printf("run: %s", strings.Join(params, " "))
-	cmd := exec.Command(params[0], params[1:]...)
-	cmd.Env = env
-	cmd.Stdin = os.Stdin
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	if err = cmd.Start(); err != nil {
-		panic(err)
-	}
-	if err = cmd.Wait(); err != nil {
-		if exiterr, ok := err.(*exec.ExitError); ok {
-			if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
-				os.Exit(status.ExitStatus())
-			}
-		}
-	}
-	fmt.Println()
-}

+ 0 - 12
file.go

@@ -1,12 +0,0 @@
-package util
-
-import "os"
-
-// RemoveAll directory
-func RemoveAll(path ...string) {
-	var err error
-	for _, p := range path {
-		err = os.RemoveAll(p)
-		Check("Remove error: path '%s'\n%v", p, err)
-	}
-}

+ 0 - 30
json.go

@@ -1,30 +0,0 @@
-package util
-
-import "encoding/json"
-
-// JSONPrettyPrint func
-func JSONPrettyPrint(v interface{}) string {
-	if bb, err := json.MarshalIndent(v, "", "   "); err != nil {
-		panic(err)
-	} else {
-		return string(bb)
-	}
-}
-
-//
-// // JSONMarshal func
-// func JSONMarshal(w io.Writer, v interface{}) {
-// 	if d, err := json.Marshal(v); err == nil {
-// 		w.Write(d)
-// 	} else {
-// 		panic(err)
-// 	}
-// }
-//
-// // JSONUnmarshal func
-// func JSONUnmarshal(b []byte, v interface{}) interface{} {
-// 	if err := json.Unmarshal(b, v); err != nil {
-// 		panic(err)
-// 	}
-// 	return v
-// }

+ 0 - 62
part-writer-data.go

@@ -1,62 +0,0 @@
-package util
-
-import (
-	"os"
-	"strconv"
-)
-
-// PartWriter interface
-type PartWriter interface {
-	Next()
-
-	Write(p []byte) (n int, err error)
-
-	Close() error
-
-	Part() uint64
-}
-
-// PartWriterData struct
-type PartWriterData struct {
-	fn   string
-	part uint64
-	file *os.File
-}
-
-// NewPartWriter func
-func NewPartWriter(path string, id uint64) *PartWriterData {
-	var err error
-	var file *os.File
-	fn := path + "/F" + strconv.FormatUint(id, 16) + "."
-	if file, err = os.Create(fn + strconv.FormatUint(uint64(1), 16) + ".tmp"); err != nil {
-		panic(err)
-	}
-	return &PartWriterData{fn, 1, file}
-}
-
-// Next func
-func (w *PartWriterData) Next() {
-	var err error
-	if err = w.file.Close(); err != nil {
-		panic(err)
-	}
-	w.part++
-	if w.file, err = os.Create(w.fn + strconv.FormatUint(uint64(w.part), 16) + ".tmp"); err != nil {
-		panic(err)
-	}
-}
-
-// Write func
-func (w *PartWriterData) Write(p []byte) (n int, err error) {
-	return w.file.Write(p)
-}
-
-// Close func
-func (w *PartWriterData) Close() error {
-	return w.file.Close()
-}
-
-// Part func
-func (w *PartWriterData) Part() uint64 {
-	return w.part
-}

+ 0 - 56
signer.go

@@ -1,56 +0,0 @@
-package util
-
-import (
-	"crypto"
-	"crypto/rand"
-	"crypto/rsa"
-	"fmt"
-	"hash"
-)
-
-// Signer struct
-type Signer struct {
-	opts   rsa.PSSOptions
-	method crypto.Hash
-	h      hash.Hash
-}
-
-// NewSigner func
-func NewSigner() *Signer {
-	hash := crypto.SHA256
-	var opts rsa.PSSOptions
-	opts.SaltLength = rsa.PSSSaltLengthAuto
-	return &Signer{opts, hash, hash.New()}
-}
-
-func (signer *Signer) Write(p []byte) (n int, err error) {
-	signer.h.Write(p)
-	return
-}
-
-// WriteUint64 func
-func (signer *Signer) WriteUint64(v uint64) {
-	signer.h.Write(Uint64ToBytes(v))
-}
-
-// Sign func
-func (signer *Signer) Sign(key *rsa.PrivateKey) []byte {
-	if res, err := rsa.SignPSS(rand.Reader, key, signer.method, signer.h.Sum(nil), &signer.opts); err != nil {
-		panic(err)
-	} else {
-		return res
-	}
-}
-
-// Verify func
-func (signer *Signer) Verify(key *rsa.PublicKey, sum []byte) {
-	if err := rsa.VerifyPSS(key, signer.method, signer.h.Sum(nil), sum, &signer.opts); err != nil {
-		panic(fmt.Errorf("Verify failed"))
-	}
-}
-
-// Check func
-func (signer *Signer) Check(key *rsa.PublicKey, sum []byte) bool {
-	err := rsa.VerifyPSS(key, signer.method, signer.h.Sum(nil), sum, &signer.opts)
-	return err == nil
-}

+ 102 - 0
src/encrypter/aes.go

@@ -0,0 +1,102 @@
+package encrypter
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha256"
+	"encoding/base64"
+)
+
+// AESKey type
+type AESKey []byte
+
+// EncryptedAESKey type
+type EncryptedAESKey []byte
+
+// NewAESKey func
+func NewAESKey() AESKey {
+	bb := make([]byte, 32)
+	rand.Read(bb)
+	return AESKey(bb)
+}
+
+// ParseAESKey func
+func ParseAESKey(b []byte) AESKey {
+	if len(b) != 32 {
+		slog.Panicf("Invalid AESKey (%v)", len(b))
+	}
+	return (AESKey)(b)
+}
+
+// EncryptKey func
+func (s *AESKey) EncryptKey(key *PublicKey) EncryptedAESKey {
+	bb, err := key.Encrypt(([]byte)(*s))
+	if err != nil {
+		panic(err)
+	}
+	return (EncryptedAESKey)(bb)
+}
+
+// Encrypt func
+func (s *AESKey) Encrypt(data []byte) (encrypted []byte, err error) {
+	nonce := make([]byte, 12)
+	rand.Read(nonce)
+	block, err := aes.NewCipher(([]byte)(*s))
+	if err != nil {
+		slog.Warnf("ERROR New cipher %v", err)
+		return
+	}
+	gcm, err := cipher.NewGCM(block)
+	if err != nil {
+		slog.Warnf("ERROR New GCM %v", err)
+		return
+	}
+	encrypted = append(nonce, gcm.Seal(nil, nonce, data, nil)...)
+	return
+}
+
+// Decrypt func
+func (s *AESKey) Decrypt(data []byte) (plain []byte, err error) {
+	block, err := aes.NewCipher(([]byte)(*s))
+	if err != nil {
+		slog.Warnf("ERROR New cipher %v", err)
+		return
+	}
+	gcm, err := cipher.NewGCM(block)
+	if err != nil {
+		slog.Warnf("ERROR New GCM %v", err)
+		return
+	}
+	plain, err = gcm.Open(nil, data[:12], data[12:], nil)
+	return
+}
+
+// MarshalJSON func
+func (s *AESKey) MarshalJSON() ([]byte, error) {
+	return []byte("\"" + base64.RawURLEncoding.EncodeToString(([]byte)(*s)) + "\""), nil
+}
+
+func (s *AESKey) String() string {
+	return base64.RawURLEncoding.EncodeToString(*s)
+}
+
+// Decrypt func
+func (s *EncryptedAESKey) Decrypt(key *PrivateKey) (AESKey, error) {
+	bb, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, (*rsa.PrivateKey)(key), ([]byte)(*s), nil)
+	if err != nil {
+		slog.Warnf("ERROR Decrypt %v", err)
+		return nil, err
+	}
+	return (AESKey)(bb), nil
+}
+
+// MarshalJSON func
+func (s *EncryptedAESKey) MarshalJSON() ([]byte, error) {
+	return []byte("\"" + base64.RawURLEncoding.EncodeToString(([]byte)(*s)) + "\""), nil
+}
+
+func (s *EncryptedAESKey) String() string {
+	return "\"" + base64.RawURLEncoding.EncodeToString(*s) + "\""
+}

+ 31 - 0
src/encrypter/rsa-encrypted.go

@@ -0,0 +1,31 @@
+package encrypter
+
+import (
+	"crypto/x509"
+	"encoding/base64"
+)
+
+// EncryptedPrivateKey type
+type EncryptedPrivateKey []byte
+
+// DecryptKey func
+func (s *EncryptedPrivateKey) DecryptKey(key *PrivateKey) (*PrivateKey, error) {
+	bb, err := key.Decrypt(([]byte)(*s))
+	if err != nil {
+		return nil, err
+	}
+	k, err := x509.ParsePKCS1PrivateKey(bb)
+	if err != nil {
+		return nil, err
+	}
+	return (*PrivateKey)(k), nil
+}
+
+// MarshalJSON func
+func (s *EncryptedPrivateKey) MarshalJSON() ([]byte, error) {
+	return []byte("\"" + base64.RawURLEncoding.EncodeToString(([]byte)(*s)) + "\""), nil
+}
+
+func (s *EncryptedPrivateKey) String() string {
+	return base64.RawURLEncoding.EncodeToString(*s)
+}

+ 295 - 0
src/encrypter/rsa.go

@@ -0,0 +1,295 @@
+package encrypter
+
+import (
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha256"
+	"crypto/x509"
+	"encoding/base64"
+	"fmt"
+	"reflect"
+	"strings"
+
+	msgpack "gopkg.in/vmihailenco/msgpack.v2"
+)
+
+// PrivateKey type
+type PrivateKey rsa.PrivateKey
+
+// PublicKey type
+type PublicKey rsa.PublicKey
+
+const (
+	keySize          = 2048
+	decryptBlockSize = 256
+	encryptBlockSize = 190
+)
+
+// NewPrivateKey func
+func NewPrivateKey() *PrivateKey {
+	pk, err := rsa.GenerateKey(rand.Reader, keySize)
+	if err != nil {
+		panic(fmt.Errorf("Error create rsa.PrivateKey %v", err))
+	}
+	return (*PrivateKey)(pk)
+}
+
+// ParsePrivateKey func
+func ParsePrivateKey(raw []byte) *PrivateKey {
+	k, err := x509.ParsePKCS1PrivateKey(raw)
+	if err != nil {
+		panic(fmt.Errorf("Error parse privateKey %v", err))
+	}
+	return (*PrivateKey)(k)
+}
+
+// ParsePrivateKeyString func
+func ParsePrivateKeyString(str string) (*PrivateKey, error) {
+	raw, err := base64.RawURLEncoding.DecodeString(str)
+	if err != nil {
+		slog.Debugf("Error key decode %v", err)
+		return nil, err
+	}
+	k, err := x509.ParsePKCS1PrivateKey(raw)
+	if err != nil {
+		slog.Debugf("Error parse key %v", err)
+		return nil, err
+	}
+	return (*PrivateKey)(k), nil
+}
+
+// ParsePublicKey func
+func ParsePublicKey(raw []byte) *PublicKey {
+	k, err := x509.ParsePKIXPublicKey(raw)
+	if err != nil {
+		panic(fmt.Errorf("Error parse privateKey %v", err))
+	}
+	if p, ok := k.(*rsa.PublicKey); ok {
+		return (*PublicKey)(p)
+	}
+	panic(fmt.Errorf("Invalid type %s", reflect.TypeOf(k).String()))
+}
+
+// ParsePublicKeyString func
+func ParsePublicKeyString(str string) (*PublicKey, error) {
+	raw, err := base64.RawURLEncoding.DecodeString(str)
+	if err != nil {
+		slog.Debugf("Error key decode %v", err)
+		return nil, err
+	}
+	k, err := x509.ParsePKIXPublicKey(raw)
+	if err != nil {
+		slog.Debugf("Error parse key %v", err)
+		return nil, err
+	}
+	if p, ok := k.(*rsa.PublicKey); ok {
+		return (*PublicKey)(p), nil
+	}
+	err = fmt.Errorf("Invalid type %s", reflect.TypeOf(k).String())
+	slog.Debugf("Error %v", err)
+	return nil, err
+}
+
+var _ msgpack.CustomEncoder = (*PrivateKey)(nil)
+var _ msgpack.CustomDecoder = (*PrivateKey)(nil)
+
+// EncodeMsgpack func
+func (s *PrivateKey) EncodeMsgpack(enc *msgpack.Encoder) error {
+	return enc.Encode(s.Raw())
+}
+
+// DecodeMsgpack func
+func (s *PrivateKey) DecodeMsgpack(dec *msgpack.Decoder) error {
+	var raw []byte
+	err := dec.Decode(&raw)
+	if err != nil {
+		slog.Warnf("PrivateKey.DecodeMsgpack decode str %v", err)
+		return err
+	}
+	sk, err := x509.ParsePKCS1PrivateKey(raw)
+	if err != nil {
+		slog.Warnf("PrivateKey.DecodeMsgpack parse pkcs key %v", err)
+		return err
+	}
+	s.PublicKey = sk.PublicKey
+	s.D = sk.D
+	s.Primes = sk.Primes
+	s.Precomputed = sk.Precomputed
+	return nil
+}
+
+// Decrypt func
+func (s *PrivateKey) Decrypt(crypt []byte) (plain []byte, err error) {
+	for {
+		if len(crypt) <= decryptBlockSize {
+			bb, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, (*rsa.PrivateKey)(s), crypt, nil)
+			if err != nil {
+				return nil, err
+			}
+			return append(plain, bb...), err
+		}
+		bb, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, (*rsa.PrivateKey)(s), crypt[:decryptBlockSize], nil)
+		if err != nil {
+			return nil, err
+		}
+		plain = append(plain, bb...)
+		crypt = crypt[decryptBlockSize:]
+	}
+}
+
+// MarshalJSON func
+func (s *PrivateKey) MarshalJSON() ([]byte, error) {
+	return []byte("\"" + base64.RawURLEncoding.EncodeToString(s.Raw()) + "\""), nil
+}
+
+// UnmarshalJSON func
+func (s *PrivateKey) UnmarshalJSON(b []byte) error {
+	if b[0] != '"' && b[len(b)-1] != '"' {
+		return fmt.Errorf("Invalid key")
+	}
+	skey := strings.Replace(string(b[1:len(b)-1]), "\\n", "", -1)
+	bb, err := base64.RawURLEncoding.DecodeString(skey)
+	if err != nil {
+		return fmt.Errorf("Error parse privateKey %v [%s]", err, skey)
+	}
+	k, err := x509.ParsePKCS1PrivateKey(bb)
+	if err != nil {
+		return fmt.Errorf("Error parse privateKey %v [%s]", err, string(bb))
+	}
+	s.D = k.D
+	s.E = k.E
+	s.N = k.N
+	s.Primes = k.Primes
+	return ((*rsa.PrivateKey)(s)).Validate()
+}
+
+func (s *PrivateKey) String() string {
+	bb := x509.MarshalPKCS1PrivateKey((*rsa.PrivateKey)(s))
+	return base64.RawURLEncoding.EncodeToString(bb)
+}
+
+// Public func
+func (s *PrivateKey) Public() *PublicKey {
+	rp := (*rsa.PrivateKey)(s).PublicKey
+	return (*PublicKey)(&rp)
+}
+
+// EncryptKey func
+func (s *PrivateKey) EncryptKey(key *PublicKey) EncryptedPrivateKey {
+	bb, err := key.Encrypt(s.Raw())
+	if err != nil {
+		panic(err)
+	}
+	return (EncryptedPrivateKey)(bb)
+}
+
+// Raw func
+func (s *PrivateKey) Raw() []byte {
+	return x509.MarshalPKCS1PrivateKey((*rsa.PrivateKey)(s))
+}
+
+// Equal func
+func (s *PrivateKey) Equal(key *PrivateKey) bool {
+	if key == nil {
+		return s == nil
+	}
+	k1 := (*rsa.PrivateKey)(s)
+	k2 := (*rsa.PrivateKey)(key)
+	return k1.E == k2.E && k1.D.Cmp(k2.D) == 0 && k1.N.Cmp(k2.N) == 0
+}
+
+var _ msgpack.CustomEncoder = (*PublicKey)(nil)
+var _ msgpack.CustomDecoder = (*PublicKey)(nil)
+
+// EncodeMsgpack func
+func (s *PublicKey) EncodeMsgpack(enc *msgpack.Encoder) error {
+	return enc.Encode(s.Raw())
+}
+
+// DecodeMsgpack func
+func (s *PublicKey) DecodeMsgpack(dec *msgpack.Decoder) error {
+	var raw []byte
+	err := dec.Decode(&raw)
+	if err != nil {
+		return err
+	}
+	sko, err := x509.ParsePKIXPublicKey(raw)
+	if err != nil {
+		return err
+	}
+	if sk, ok := sko.(*rsa.PublicKey); ok {
+		s.N = sk.N
+		s.E = sk.E
+		return nil
+	}
+	return fmt.Errorf("Unkown type %s", reflect.TypeOf(sko))
+}
+
+// Encrypt func
+func (s *PublicKey) Encrypt(data []byte) (crypt []byte, err error) {
+	for {
+		if len(data) <= encryptBlockSize {
+			bb, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, (*rsa.PublicKey)(s), data, nil)
+			if err != nil {
+				return nil, err
+			}
+			return append(crypt, bb...), err
+		}
+		bb, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, (*rsa.PublicKey)(s), data[:encryptBlockSize], nil)
+		if err != nil {
+			return nil, err
+		}
+		crypt = append(crypt, bb...)
+		data = data[encryptBlockSize:]
+	}
+}
+
+// MarshalJSON func
+func (s *PublicKey) MarshalJSON() ([]byte, error) {
+	return []byte("\"" + base64.RawURLEncoding.EncodeToString(s.Raw()) + "\""), nil
+}
+
+// UnmarshalJSON func
+func (s *PublicKey) UnmarshalJSON(b []byte) error {
+	if b[0] != '"' && b[len(b)-1] != '"' {
+		return fmt.Errorf("Invalid key")
+	}
+	skey := strings.Replace(string(b[1:len(b)-1]), "\\n", "", -1)
+	bb, err := base64.RawURLEncoding.DecodeString(skey)
+	if err != nil {
+		return fmt.Errorf("Error parse privateKey %v [%s]", err, skey)
+	}
+	k, err := x509.ParsePKIXPublicKey(bb)
+	if err != nil {
+		return fmt.Errorf("Error parse privateKey %v [%s]", err, string(bb))
+	}
+	if pk, ok := k.(*rsa.PublicKey); ok {
+		s.E = pk.E
+		s.N = pk.N
+		return nil
+	}
+	return fmt.Errorf("Invalid type %s", reflect.TypeOf(k))
+}
+
+func (s *PublicKey) String() string {
+	return base64.RawURLEncoding.EncodeToString(s.Raw())
+}
+
+// Raw func
+func (s *PublicKey) Raw() []byte {
+	bb, err := x509.MarshalPKIXPublicKey((*rsa.PublicKey)(s))
+	if err != nil {
+		panic(err)
+	}
+	return bb
+}
+
+// Equal func
+func (s *PublicKey) Equal(key *PublicKey) bool {
+	if key == nil {
+		return s == nil
+	}
+	k1 := (*rsa.PublicKey)(s)
+	k2 := (*rsa.PublicKey)(key)
+	return k1.E == k2.E && k1.N.Cmp(k2.N) == 0
+}

+ 108 - 0
src/signer/signature.go

@@ -0,0 +1,108 @@
+package signer
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/rand"
+	"crypto/rsa"
+	"encoding/base64"
+	"encoding/binary"
+	"encrypter"
+	"hash"
+	"time"
+
+	msgpack "gopkg.in/vmihailenco/msgpack.v2"
+)
+
+// PrivateKey type
+type PrivateKey ecdsa.PrivateKey
+
+// PublicKey type
+type PublicKey ecdsa.PublicKey
+
+// Signature type
+type Signature []byte
+
+const sha256 = crypto.SHA256
+
+const ivSize = 8
+
+// Signer struct
+type Signer struct {
+	hasher hash.Hash
+}
+
+// New func
+func New() *Signer {
+	return &Signer{hasher: sha256.New()}
+}
+
+// Write func
+func (s *Signer) Write(data []byte) {
+	s.hasher.Write(data)
+}
+
+// WriteTime func
+func (s *Signer) WriteTime(data *time.Time) {
+	b := make([]byte, 8)
+	binary.BigEndian.PutUint64(b, uint64(data.Unix()))
+	s.hasher.Write(b)
+}
+
+// WritePack func
+func (s *Signer) WritePack(data interface{}) {
+	raw, err := msgpack.Marshal(data)
+	if err != nil {
+		panic(err)
+	}
+	s.hasher.Write(raw)
+}
+
+// Reset func
+func (s *Signer) Reset() {
+	s.hasher.Reset()
+}
+
+// Sign func
+func (s *Signer) Sign(key *encrypter.PrivateKey) Signature {
+	sign, err := rsa.SignPKCS1v15(rand.Reader, (*rsa.PrivateKey)(key), sha256, s.hasher.Sum(nil))
+	if err != nil {
+		panic(err)
+	}
+	s.hasher.Reset()
+	return (Signature)(sign)
+}
+
+// Verify func
+func (s *Signer) Verify(key *encrypter.PublicKey, signature Signature) error {
+	err := rsa.VerifyPKCS1v15((*rsa.PublicKey)(key), sha256, s.hasher.Sum(nil), signature)
+	s.hasher.Reset()
+	return err
+}
+
+// SignWithIV func
+func (s *Signer) SignWithIV(key *encrypter.PrivateKey) (Signature, error) {
+	iv := make([]byte, ivSize)
+	_, err := rand.Read(iv)
+	if err != nil {
+		return nil, err
+	}
+	s.hasher.Write(iv)
+	sign, err := rsa.SignPKCS1v15(rand.Reader, (*rsa.PrivateKey)(key), sha256, s.hasher.Sum(nil))
+	s.hasher.Reset()
+	return (Signature)(append(iv, sign...)), err
+}
+
+// VerifyWithIV func
+func (s *Signer) VerifyWithIV(key *encrypter.PublicKey, signature Signature) error {
+	iv := signature[:ivSize]
+	s.hasher.Write(iv)
+	err := rsa.VerifyPKCS1v15((*rsa.PublicKey)(key), sha256, s.hasher.Sum(nil), signature[ivSize:])
+	s.hasher.Reset()
+	return err
+}
+
+// MarshalJSON func
+func (s *Signature) MarshalJSON() ([]byte, error) {
+	return []byte("\"" + base64.RawURLEncoding.EncodeToString(([]byte)(*s)) + "\""), nil
+}

+ 83 - 0
src/slog/formatter.go

@@ -0,0 +1,83 @@
+package slog
+
+import (
+	"bytes"
+	"fmt"
+
+	"github.com/Sirupsen/logrus"
+)
+
+const (
+	nocolor = 0
+	red     = 31
+	green   = 32
+	yellow  = 33
+	blue    = 34
+	gray    = 39
+)
+
+var (
+	formatParams = map[logrus.Level]formatParam{
+		logrus.DebugLevel: formatParam{
+			color:     blue,
+			levelText: "DEBUG",
+		},
+		logrus.InfoLevel: formatParam{
+			color:     green,
+			levelText: "INFO",
+		},
+		logrus.WarnLevel: formatParam{
+			color:     yellow,
+			levelText: "WARN",
+		},
+		logrus.ErrorLevel: formatParam{
+			color:     red,
+			levelText: "ERROR",
+		},
+	}
+)
+
+type (
+	formatter struct {
+		logrus.TextFormatter
+	}
+
+	formatParam struct {
+		color     int
+		levelText string
+	}
+)
+
+func newFormatter(color bool) *formatter {
+	return &formatter{
+		logrus.TextFormatter{
+			ForceColors:   color,
+			DisableColors: !color,
+		},
+	}
+}
+
+/**************************
+ formatter function
+**************************/
+func (f *formatter) Format(entry *logrus.Entry) ([]byte, error) {
+	formatParams := formatParams[entry.Level]
+	b := &bytes.Buffer{}
+	if f.ForceColors && !f.DisableColors {
+		fmt.Fprintf(b,
+			"\x1b[%dm[%-5s]\x1b[0m %s",
+			formatParams.color,
+			formatParams.levelText,
+			entry.Message,
+		)
+	} else {
+		fmt.Fprintf(b,
+			"[%-5s] %s",
+			formatParams.levelText,
+			entry.Message,
+		)
+	}
+
+	b.WriteByte('\n')
+	return b.Bytes(), nil
+}

+ 147 - 0
src/slog/slog.go

@@ -0,0 +1,147 @@
+package slog
+
+import (
+	"os"
+	"strings"
+
+	logrus_stack "github.com/Gurpartap/logrus-stack"
+	"github.com/Sirupsen/logrus"
+	"github.com/mattn/go-colorable"
+)
+
+type logger struct {
+	*logrus.Logger
+}
+
+var (
+	rootLogger = newRootLogger()
+)
+
+func init() {
+	logrus.AddHook(logrus_stack.NewHook(nil, []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel, logrus.WarnLevel}))
+}
+
+func newRootLogger() *logger {
+	switch strings.ToLower(os.Getenv("LOG_LEVEL")) {
+	case "panic":
+		logrus.SetLevel(logrus.PanicLevel)
+	case "fatal":
+		logrus.SetLevel(logrus.FatalLevel)
+	case "error":
+		logrus.SetLevel(logrus.ErrorLevel)
+	case "warn", "warning":
+		logrus.SetLevel(logrus.WarnLevel)
+	case "info":
+		logrus.SetLevel(logrus.InfoLevel)
+	case "debug":
+		logrus.SetLevel(logrus.DebugLevel)
+	default:
+		logrus.SetLevel(logrus.InfoLevel)
+	}
+	logrus.SetOutput(colorable.NewColorableStdout())
+	logrus.SetFormatter(newFormatter(true))
+	return &logger{logrus.StandardLogger()}
+}
+
+// SetLevelToDebug func
+func SetLevelToDebug() {
+	logrus.SetLevel(logrus.DebugLevel)
+}
+
+// SetLevelToInfo func
+func SetLevelToInfo() {
+	logrus.SetLevel(logrus.InfoLevel)
+}
+
+// SetLevelToWarn func
+func SetLevelToWarn() {
+	logrus.SetLevel(logrus.WarnLevel)
+}
+
+// Debugf func
+func Debugf(format string, fn func() interface{}) {
+	if rootLogger.Level >= logrus.DebugLevel {
+		ff := fn()
+		rootLogger.Debugf(format, ff)
+	}
+}
+
+// Debugff func
+func Debugff(format string, fn func() []interface{}) {
+	if rootLogger.Level >= logrus.DebugLevel {
+		ff := fn()
+		rootLogger.Debugf(format, ff...)
+	}
+}
+
+// Debugfi func
+func Debugfi(format string, ff ...interface{}) {
+	if rootLogger.Level >= logrus.DebugLevel {
+		rootLogger.Debugf(format, ff...)
+	}
+}
+
+// Infof func
+func Infof(format string, fn func() interface{}) {
+	if rootLogger.Level >= logrus.InfoLevel {
+		ff := fn()
+		rootLogger.Infof(format, ff)
+	}
+}
+
+// Infoff func
+func Infoff(format string, fn func() []interface{}) {
+	if rootLogger.Level >= logrus.InfoLevel {
+		ff := fn()
+		rootLogger.Infof(format, ff)
+	}
+}
+
+// Infofi func
+func Infofi(format string, ff ...interface{}) {
+	if rootLogger.Level >= logrus.DebugLevel {
+		rootLogger.Infof(format, ff...)
+	}
+}
+
+// Warnf func
+func Warnf(format string, args ...interface{}) {
+	rootLogger.Warnf(format, args...)
+}
+
+// Errorf func
+func Errorf(format string, args ...interface{}) {
+	rootLogger.Errorf(format, args...)
+}
+
+// Panicf func
+func Panicf(format string, args ...interface{}) {
+	rootLogger.Panicf(format, args...)
+}
+
+// Debug func
+func Debug(args ...interface{}) {
+	if rootLogger.Level >= logrus.DebugLevel {
+		rootLogger.Debug(args...)
+	}
+}
+
+// Info func
+func Info(args ...interface{}) {
+	rootLogger.Info(args...)
+}
+
+// Warn func
+func Warn(args ...interface{}) {
+	rootLogger.Warn(args...)
+}
+
+// Error func
+func Error(args ...interface{}) {
+	rootLogger.Error(args...)
+}
+
+// Panic func
+func Panic(args ...interface{}) {
+	rootLogger.Panic(args...)
+}

+ 8 - 0
src/util/util.go

@@ -0,0 +1,8 @@
+package util
+
+import "fmt"
+
+// Todo func
+func Todo(msg string) error {
+	return fmt.Errorf("TODO %s", msg)
+}

+ 48 - 0
src/vendor/manifest

@@ -0,0 +1,48 @@
+{
+	"version": 0,
+	"dependencies": [
+		{
+			"importpath": "github.com/golang/protobuf/proto",
+			"repository": "https://github.com/golang/protobuf",
+			"vcs": "git",
+			"revision": "ab9f9a6dab164b7d1246e0e688b0ab7b94d8553e",
+			"branch": "master",
+			"path": "/proto",
+			"notests": true
+		},
+		{
+			"importpath": "github.com/golang/protobuf/ptypes/any",
+			"repository": "https://github.com/golang/protobuf",
+			"vcs": "git",
+			"revision": "ab9f9a6dab164b7d1246e0e688b0ab7b94d8553e",
+			"branch": "master",
+			"path": "ptypes/any",
+			"notests": true
+		},
+		{
+			"importpath": "golang.org/x/net/context",
+			"repository": "https://go.googlesource.com/net",
+			"vcs": "git",
+			"revision": "1c05540f6879653db88113bc4a2b70aec4bd491f",
+			"branch": "master",
+			"path": "/context",
+			"notests": true
+		},
+		{
+			"importpath": "google.golang.org/appengine",
+			"repository": "https://github.com/golang/appengine",
+			"vcs": "git",
+			"revision": "d9a072cfa7b9736e44311ef77b3e09d804bfa599",
+			"branch": "master",
+			"notests": true
+		},
+		{
+			"importpath": "gopkg.in/vmihailenco/msgpack.v2",
+			"repository": "https://gopkg.in/vmihailenco/msgpack.v2",
+			"vcs": "git",
+			"revision": "f4f8982de4ef0de18be76456617cc3f5d8d8141e",
+			"branch": "master",
+			"notests": true
+		}
+	]
+}

+ 0 - 75
util.go

@@ -1,75 +0,0 @@
-package util
-
-import (
-	"encoding/binary"
-	"fmt"
-)
-
-// Panic with test
-func Panic(err error) {
-	if err != nil {
-		panic(err)
-	}
-}
-
-// Panicf with test
-func Panicf(format string, err error) {
-	if err != nil {
-		panic(fmt.Errorf(format, err))
-	}
-}
-
-// PanicfArgs with test
-func PanicfArgs(err error, format string, args ...interface{}) {
-	if err != nil {
-		panic(fmt.Errorf(format, args...))
-	}
-}
-
-// Check error function
-func Check(format string, args ...interface{}) {
-	var hasError bool
-	for _, v := range args {
-		if err, ok := v.(error); ok && err != nil {
-			hasError = true
-			break
-		}
-	}
-	if hasError {
-		panic(fmt.Errorf(format, args...))
-	}
-}
-
-// Uint64ToBytes func
-func Uint64ToBytes(v uint64) []byte {
-	bb := make([]byte, 8)
-	binary.LittleEndian.PutUint64(bb, v)
-	return bb
-}
-
-// BytesToUint64 func
-func BytesToUint64(v []byte) uint64 {
-	return binary.LittleEndian.Uint64(v)
-}
-
-// UintToBytes func
-func UintToBytes(v uint) []byte {
-	bb := make([]byte, 4)
-	binary.LittleEndian.PutUint32(bb, uint32(v))
-	return bb
-}
-
-// BytesToUint func
-func BytesToUint(v []byte) uint {
-	return uint(binary.LittleEndian.Uint32(v))
-}
-
-// InStringSlice func
-func InStringSlice(v string, list ...string) bool {
-	for _, vl := range list {
-		if v == vl {
-			return true
-		}
-	}
-	return false
-}