commit cae49d644399e149a3fe0ab66d80390e830ef7dd Author: lrodham Date: Fri Apr 7 23:19:03 2017 +0100 inital commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bbec59a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +vendor +.realize +app diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9e1f6b3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +FROM busybox:latest +ADD app /app +CMD ["/app"] diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json new file mode 100644 index 0000000..90e3f7e --- /dev/null +++ b/Godeps/Godeps.json @@ -0,0 +1,52 @@ +{ + "ImportPath": "vault", + "GoVersion": "go1.7", + "GodepVersion": "v79", + "Deps": [ + { + "ImportPath": "github.com/gin-gonic/gin/binding", + "Comment": "v1.1.4", + "Rev": "e2212d40c62a98b388a5eb48ecbdcf88534688ba" + }, + { + "ImportPath": "github.com/gin-gonic/gin/render", + "Comment": "v1.1.4", + "Rev": "e2212d40c62a98b388a5eb48ecbdcf88534688ba" + }, + { + "ImportPath": "github.com/golang/protobuf/proto", + "Rev": "c9c7427a2a70d2eb3bafa0ab2dc163e45f143317" + }, + { + "ImportPath": "github.com/manucorporat/sse", + "Rev": "ee05b128a739a0fb76c7ebd3ae4810c1de808d6d" + }, + { + "ImportPath": "github.com/mattn/go-isatty", + "Comment": "v0.0.1-32-gfc9e8d8", + "Rev": "fc9e8d8ef48496124e79ae0df75490096eccf6fe" + }, + { + "ImportPath": "golang.org/x/net/context", + "Rev": "6c23252515492caf9b228a9d5cabcdbde29f7f82" + }, + { + "ImportPath": "golang.org/x/sys/unix", + "Rev": "afadfcc7779c1f4db0f6f6438afcb108d9c9c7cd" + }, + { + "ImportPath": "gopkg.in/gin-gonic/gin.v1", + "Comment": "v1.1.4", + "Rev": "e2212d40c62a98b388a5eb48ecbdcf88534688ba" + }, + { + "ImportPath": "gopkg.in/go-playground/validator.v8", + "Comment": "v8.18.1", + "Rev": "5f57d2222ad794d0dffb07e664ea05e2ee07d60c" + }, + { + "ImportPath": "gopkg.in/yaml.v2", + "Rev": "a3f3340b5840cee44f372bddb5880fcbc419b46a" + } + ] +} diff --git a/Godeps/Readme b/Godeps/Readme new file mode 100644 index 0000000..4cdaa53 --- /dev/null +++ b/Godeps/Readme @@ -0,0 +1,5 @@ +This directory tree is generated automatically by godep. + +Please do not edit. + +See https://github.com/tools/godep for more information. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6a742ce --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +BINARY=vault +VERSION=test +CONTAINER_PORT=-p 7007:7014 + +build: + docker run --rm -v ${PWD}:/go/src/app -w /go/src/app -e GOOS=linux -e GOARCH=386 sipsynergy/go-builder /bin/sh -c "godep get && godep go build" + docker build -t ${BINARY}:${VERSION} . +start: + docker run -d ${CONTAINER_PORT} --name ${BINARY} ${BINARY}:${VERSION} +stop: + docker stop ${BINARY} && docker rm ${BINARY} diff --git a/main.go b/main.go new file mode 100644 index 0000000..321cc3c --- /dev/null +++ b/main.go @@ -0,0 +1,133 @@ +package main + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "log" + "strings" + "time" + + "gopkg.in/gin-gonic/gin.v1" +) + +type Item struct { + Data string `json:"data"` + Expiry time.Time `json:"expiryData"` + TTL int32 `json:"ttl"` +} + +type Vault struct { + Vault string `json:"vault"` + Key string `json:"key"` +} + +func main() { + router := gin.Default() + + router.POST("/", createAction) + router.POST("/decrypt", decryptAction) + router.Run(":7014") +} + +func show(c *gin.Context) { + log.Println("asdasdsa") +} + +func createAction(c *gin.Context) { + var item Item + c.BindJSON(&item) + + key := generateUniqueID(16) + json, _ := json.Marshal(&item) + data := encrypt([]byte(key), string(json)) + + var vault Vault + vault.Key = key + vault.Vault = data + + c.JSON(200, vault) +} + +func decryptAction(c *gin.Context) { + var vault Vault + err := c.BindJSON(&vault) + if err != nil { + panic(err) + } + + data := decrypt([]byte(vault.Key), vault.Vault) + + var item Item + err = json.Unmarshal([]byte(data), &item) + if err != nil { + panic(err) + } + + c.JSON(200, item) +} + +func generateUniqueID(length int) string { + n := length + b := make([]byte, n) + if _, err := rand.Read(b); err != nil { + panic(err) + } + s := fmt.Sprintf("%X", b) + + return strings.ToLower(s) +} + +func encrypt(key []byte, message string) string { + plainText := []byte(message) + + block, err := aes.NewCipher(key) + if err != nil { + return "" + } + + //IV needs to be unique, but doesn't have to be secure. + //It's common to put it at the beginning of the ciphertext. + cipherText := make([]byte, aes.BlockSize+len(plainText)) + iv := cipherText[:aes.BlockSize] + if _, err = io.ReadFull(rand.Reader, iv); err != nil { + return "" + } + + stream := cipher.NewCFBEncrypter(block, iv) + stream.XORKeyStream(cipherText[aes.BlockSize:], plainText) + + //returns to base64 encoded string + encmess := base64.URLEncoding.EncodeToString(cipherText) + return encmess +} + +func decrypt(key []byte, securemess string) string { + cipherText, err := base64.URLEncoding.DecodeString(securemess) + if err != nil { + return "" + } + + block, err := aes.NewCipher(key) + if err != nil { + return "" + } + + if len(cipherText) < aes.BlockSize { + return "" + } + + 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) + + decodedmess := string(cipherText) + return decodedmess +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..39dab8b --- /dev/null +++ b/readme.md @@ -0,0 +1,23 @@ +# Vault +To build the vault you'll need to use the makefile. From the root of this project run ```make build```. +To run the app ```make start``` +To stop the app ```make stop``` + + +### Routes + +POST "/" +``` +{ + "data": "Test Data", + "ttl": 30 +} +``` + +POST "/decrypt" +``` +{ + "vault": "3HXCBDkcT7R2ub39FXluykb_SZmC2udY09R-F1UuEnnTaekT60T6LbhUf_llovadxRg3w1ZL_krFsyoHodpvqeNpuXGsdMoHAVxJMhZpBOzH", + "key": "efc927b61eab7f9cc3bd274b40330956" +} +```