Skip to content

Commit

Permalink
Merge pull request #82 from cossacklabs/lagovas/update-gohermes
Browse files Browse the repository at this point in the history
add transport to gohermes and use secure session wrapper from hermes-core
  • Loading branch information
Lagovas authored Nov 3, 2017
2 parents b42459f + 12c9bb3 commit 71c1900
Show file tree
Hide file tree
Showing 10 changed files with 505 additions and 210 deletions.
12 changes: 12 additions & 0 deletions docs/examples/go/config.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
id = "user1"
private_key = ""
data_store_url = "127.0.0.1:8890"
key_store_url = "127.0.0.1:8889"
credential_store_url = "127.0.0.1:8888"
credential_store_id = "credential_store"
credential_store_public_key = "VUVDMgAAAC1x1lf9Az0bNDSYU8TG8XcBBwsciK6nOo4H9/VeSb2carumNQla"

key_store_id = "key_store_server"
key_store_public_key = "VUVDMgAAAC3QMLOAAoms9u5nTh1Ir3AnTPt5RkMJY9leIfF6uMIxms/Bkywp"
data_store_id = "data_store_server"
data_store_public_key = "VUVDMgAAAC0VCQ/fAt88d2N8vDFVAKbDJHsXew8HgB55PIrVfhELXrEf1N89"
127 changes: 84 additions & 43 deletions docs/examples/go/hermes_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,22 @@ import (
"flag"
"fmt"
"io/ioutil"
"github.com/BurntSushi/toml"
)

type Transport struct {
type TCPTransport struct {
connection net.Conn
}

func NewTransport(uri string) (Transport, error) {
func NewTransport(uri string) (TCPTransport, error) {
conn, err := net.Dial("tcp", uri)
if err != nil {
return Transport{}, err
return TCPTransport{}, err
}
return Transport{conn}, nil
return TCPTransport{conn}, nil
}

func (t Transport) Send(buf []byte) error {
func (t TCPTransport) Write(buf []byte) error {
var total_send = 0
for total_send < len(buf) {
sended, err := t.connection.Write(buf[total_send:])
Expand All @@ -53,7 +54,7 @@ func (t Transport) Send(buf []byte) error {
return nil
}

func (t Transport) Recv(buf []byte) error {
func (t TCPTransport) Read(buf []byte) error {
var total_received = 0
for total_received < len(buf) {
received, err := t.connection.Read(buf[total_received:])
Expand All @@ -65,73 +66,113 @@ func (t Transport) Recv(buf []byte) error {
return nil
}

func (t Transport) Close() {
func (t TCPTransport) Close() {
t.connection.Close()
}

func usage() string {
return `Usage of ./hermes_client:
type Config struct {
Id string
PrivateKey string `toml:"private_key"`

CredentialStoreUrl string `toml:"credential_store_url"`
CredentialStoreId string `toml:"credential_store_id"`
CredentialStorePublicKey string `toml:"credential_store_public_key"`

DataStoreUrl string `toml:"data_store_url"`
DataStoreId string `toml:"data_store_id"`
DataStorePublicKey string `toml:"data_store_public_key"`

KeyStoreUrl string `toml:"key_store_url"`
KeyStoreId string `toml:"key_store_id"`
KeyStorePublicKey string `toml:"key_store_public_key"`
}

func usage() {
fmt.Println(`hermes_client:
-command string
command
-credential_store_uri string
Credential Store URI (default "127.0.0.1:8888")
-data_store_uri string
Data Store URI (default "127.0.0.1:8889")
command [add_block | read_block | update_block | delete_block | rotate_block | grant_read_access | grant_update_access | revoke_read_access | revoke_update_access ]
-doc string
doc
doc
-for_user string
for user id
-id string
user id
-key_store_uri string
Key Store URI (default "127.0.0.1:8890")
for user id
-meta string
meta
-private_key string
user private key`
meta`)
}

func main() {
var credential_store_uri = flag.String("credential_store_uri", "127.0.0.1:8888", "Credential Store URI")
var key_store_uri = flag.String("key_store_uri", "127.0.0.1:8890", "Key Store URI")
var data_store_uri = flag.String("data_store_uri", "127.0.0.1:8889", "Data Store URI")
var id = flag.String("id", "", "user id")
var private_key = flag.String("private_key", "", "user private key")
var config = flag.String("config", "client.conf", "Config with settings")
var doc_file_name = flag.String("doc", "", "doc")
var meta = flag.String("meta", "", "meta")
var for_user = flag.String("for_user", "", "for user id")
var command = flag.String("command", "", "command [add_block | read_block | update_block | delete_block | rotate_block | grant_read_access | grant_update_access | revoke_read_access | revoke_update_access ]")
flag.Parse()
var conf Config
if _, err := toml.DecodeFile(*config, &conf); err != nil {
panic(err)
}
flag.Usage = usage

if *id == "" || *private_key == "" || *doc_file_name == "" || *command == "" {
fmt.Println(usage())
if conf.Id == "" || conf.PrivateKey == "" ||
conf.CredentialStoreId == "" || conf.CredentialStorePublicKey == "" || conf.CredentialStoreUrl == "" ||
conf.KeyStoreUrl == "" || conf.KeyStoreId == "" || conf.KeyStorePublicKey == "" ||
conf.DataStoreUrl == "" || conf.DataStoreId == "" || conf.DataStorePublicKey == "" {
fmt.Println("all parameters from config file are required")
flag.Usage()
return
}
sk, err := base64.StdEncoding.DecodeString(*private_key)
if *doc_file_name == "" || *command == "" {
fmt.Println("<command> and <doc> parameters are required")
}
privateKey, err := base64.StdEncoding.DecodeString(conf.PrivateKey)
if nil != err {
panic(err)
return
}
CredentialStoreTransport, err := NewTransport(*credential_store_uri)
CredentialStoreTransport, err := NewTransport(conf.CredentialStoreUrl)
if nil != err {
panic(err)
return
}
credentialPublic, err := base64.StdEncoding.DecodeString(conf.CredentialStorePublicKey)
if err != nil {
panic(err)
}
defer CredentialStoreTransport.Close()
DataStoreTransport, err := NewTransport(*data_store_uri)
secureCredentialTransport, err := gohermes.NewSecureTransport([]byte(conf.Id), privateKey, []byte(conf.CredentialStoreId), credentialPublic, CredentialStoreTransport, false)
if err != nil {
panic(err)
}

dataStorePublic, err := base64.StdEncoding.DecodeString(conf.DataStorePublicKey)
if err != nil {
panic(err)
}
DataStoreTransport, err := NewTransport(conf.DataStoreUrl)
if nil != err {
panic(err)
return
}
defer DataStoreTransport.Close()
KeyStoreTransport, err := NewTransport(*key_store_uri)
secureDataStoreTransport, err := gohermes.NewSecureTransport([]byte(conf.Id), privateKey, []byte(conf.DataStoreId), dataStorePublic, DataStoreTransport, false)
if err != nil {
panic(err)
}

keyPublic, err := base64.StdEncoding.DecodeString(conf.KeyStorePublicKey)
if err != nil {
panic(err)
}
KeyStoreTransport, err := NewTransport(conf.KeyStoreUrl)
if nil != err {
panic(err)
return
}
defer KeyStoreTransport.Close()
secureKeyStoreTransport, err := gohermes.NewSecureTransport([]byte(conf.Id), privateKey, []byte(conf.KeyStoreId), keyPublic, KeyStoreTransport, false)
if err != nil {
panic(err)
}

mid_hermes, err := gohermes.NewMidHermes([]byte(*id), sk, KeyStoreTransport, DataStoreTransport, CredentialStoreTransport)
mid_hermes, err := gohermes.NewMidHermes([]byte(conf.Id), privateKey, secureCredentialTransport, secureDataStoreTransport, secureKeyStoreTransport)
if nil != err {
panic(err)
return
Expand All @@ -141,7 +182,7 @@ func main() {
switch *command {
case "add_block":
if *meta == "" {
fmt.Println(usage())
flag.Usage()
}
data, err := ioutil.ReadFile(*doc_file_name)
if nil != err {
Expand All @@ -160,7 +201,7 @@ func main() {
fmt.Println(string(meta))
case "update_block":
if *meta == "" {
fmt.Println(usage())
flag.Usage()
}
data, err := ioutil.ReadFile(*doc_file_name)
if nil != err {
Expand All @@ -182,7 +223,7 @@ func main() {
}
case "grant_read_access":
if *for_user == "" {
fmt.Println(usage())
flag.Usage()
return
}
err := mid_hermes.GrantReadAccess([]byte(*doc_file_name), []byte(*for_user))
Expand All @@ -191,7 +232,7 @@ func main() {
}
case "grant_update_access":
if *for_user == "" {
fmt.Println(usage())
flag.Usage()
return
}
err := mid_hermes.GrantUpdateAccess([]byte(*doc_file_name), []byte(*for_user))
Expand All @@ -200,7 +241,7 @@ func main() {
}
case "revoke_read_access":
if *for_user == "" {
fmt.Println(usage())
flag.Usage()
return
}
err := mid_hermes.RevokeReadAccess([]byte(*doc_file_name), []byte(*for_user))
Expand All @@ -209,15 +250,15 @@ func main() {
}
case "revoke_update_access":
if *for_user == "" {
fmt.Println(usage())
flag.Usage()
return
}
err := mid_hermes.RevokeUpdateAccess([]byte(*doc_file_name), []byte(*for_user))
if nil != err {
panic(err)
}
default:
fmt.Println(usage(), *for_user)
flag.Usage()
}
fmt.Println("success")
}
99 changes: 20 additions & 79 deletions gohermes/mid_hermes.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,102 +23,43 @@ package gohermes
/*
#cgo LDFLAGS: -lhermes_mid_hermes -lhermes_mid_hermes_ll -lhermes_credential_store -lhermes_data_store -lhermes_key_store -lhermes_rpc -lhermes_common -lthemis -lsoter
#include <hermes/mid_hermes/mid_hermes.h>
#include "transport.h"
#include <string.h>
*/
import "C"

import (
"crypto/rand"
"encoding/binary"
"errors"
"runtime"
"unsafe"
)

func pseudo_uuid() (uint64, error) {

b := make([]byte, 8)
_, err := rand.Read(b)
if err != nil {
return 0, err
}
return binary.BigEndian.Uint64(b), nil
}

type HermesTransport interface {
Send(buf []byte) error
Recv(buf []byte) error
}

var transport_map = make(map[uint64]HermesTransport)

//export go_transport_send
func go_transport_send(transport C.uint64_t, buf unsafe.Pointer, buf_length C.size_t) C.int {
p := transport_map[uint64(transport)]
b := (*[1 << 30]byte)(buf)[0:buf_length] //convert {buf, buf_length} to []byte
err := p.Send(b)
if nil != err {
return 1
}
return 0
}

//export go_transport_recv
func go_transport_recv(transport C.uint64_t, buf unsafe.Pointer, buf_length C.size_t) C.int {
p := transport_map[uint64(transport)]
b := (*[1 << 30]byte)(buf)[0:buf_length]
err := p.Recv(b)
if nil != err {
return 1
}
return 0
}

type MidHermes struct {
credential_store_transport_ref, data_store_transport_ref, key_store_transport_ref uint64
credential_store_transport, data_store_transport, key_store_transport *C.hm_rpc_transport_t
mid_hermes *C.mid_hermes_t
mid_hermes *C.mid_hermes_t
credential_store_transport *HermesTransport
key_store_transport *HermesTransport
data_store_transport *HermesTransport
}

func MidHermes_finalize(mid_hermes *MidHermes) {
mid_hermes.Close()
}

func NewMidHermes(
id []byte,
private_key []byte,
credential_store_transport HermesTransport,
data_store_transport HermesTransport,
key_store_transport HermesTransport) (*MidHermes, error) {
credential_store_transport_ref, err := pseudo_uuid()
if nil != err {
return nil, err
}
data_store_transport_ref, err := pseudo_uuid()
if nil != err {
return nil, err
}
key_store_transport_ref, err := pseudo_uuid()
if nil != err {
return nil, err
}
transport_map[credential_store_transport_ref] = credential_store_transport
transport_map[data_store_transport_ref] = data_store_transport
transport_map[key_store_transport_ref] = key_store_transport
id []byte, private_key []byte,
credential_store_transport *HermesTransport,
data_store_transport *HermesTransport,
key_store_transport *HermesTransport) (*MidHermes, error) {

mh := &MidHermes{
credential_store_transport_ref: credential_store_transport_ref,
data_store_transport_ref: data_store_transport_ref,
key_store_transport_ref: key_store_transport_ref,
credential_store_transport: C.transport_create(C.uint64_t(credential_store_transport_ref)),
data_store_transport: C.transport_create(C.uint64_t(data_store_transport_ref)),
key_store_transport: C.transport_create(C.uint64_t(key_store_transport_ref))}
credential_store_transport: credential_store_transport,
data_store_transport: data_store_transport,
key_store_transport: key_store_transport}
mh.mid_hermes = C.mid_hermes_create(
(*C.uint8_t)(unsafe.Pointer(&id[0])), C.size_t(len(id)),
(*C.uint8_t)(unsafe.Pointer(&private_key[0])), C.size_t(len(private_key)),
mh.credential_store_transport,
mh.data_store_transport,
mh.key_store_transport)
mh.key_store_transport.GetHermesTransport(),
mh.data_store_transport.GetHermesTransport(),
mh.credential_store_transport.GetHermesTransport())
if nil == mh.mid_hermes {
return nil, errors.New("MidHermes object creation error")
}
Expand All @@ -128,16 +69,16 @@ func NewMidHermes(

func (mh *MidHermes) Close() error {
C.mid_hermes_destroy(&(mh.mid_hermes))
C.transport_destroy(&(mh.credential_store_transport))
C.transport_destroy(&(mh.data_store_transport))
C.transport_destroy(&(mh.key_store_transport))
return nil
}

func (mh *MidHermes) AddBlock(id []byte, data []byte, meta []byte) error {
id_ptr := (*C.uint8_t)(C.malloc(C.size_t(len(id))))
var id_ptr *C.uint8_t = nil
id_length := C.size_t(len(id))
C.memcpy(unsafe.Pointer(id_ptr), unsafe.Pointer(&id[0]), id_length)
if len(id) > 0 {
id_ptr = (*C.uint8_t)(C.malloc(C.size_t(len(id))))
C.memcpy(unsafe.Pointer(id_ptr), unsafe.Pointer(&id[0]), id_length)
}
if 0 != C.mid_hermes_create_block(
mh.mid_hermes,
&id_ptr, &id_length,
Expand Down
Loading

0 comments on commit 71c1900

Please sign in to comment.