Newer
Older
/*
Copyright (c) 2018 Vereign AG [https://www.vereign.com]
This is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package handler
import (
"strings"
"code.vereign.com/code/viam-apis/versions"
"github.com/golang/protobuf/proto"
"code.vereign.com/code/viam-apis/authentication"
"code.vereign.com/code/viam-apis/data-storage-agent/client"
"code.vereign.com/code/viam-apis/key-storage-agent/api"
"code.vereign.com/code/viam-apis/utils"
"golang.org/x/net/context"
"google.golang.org/grpc/metadata"
)
// Server represents the gRPC server
type KeyStorageServerImpl struct {
DataStorageUrl string
CertFilePath string
VereignCertFilePath string
VereignPrivateKeyFilePath string
}
func (s *KeyStorageServerImpl) CreateAuthentication(ctx context.Context) *authentication.Authentication {
if md, ok := metadata.FromIncomingContext(ctx); ok {
uuid := strings.Join(md["uuid"], "")
session := strings.Join(md["session"], "")
auth := &authentication.Authentication{
Uuid: uuid,
Session: session,
}
return auth
}
return nil
}
func (s *KeyStorageServerImpl) GetKey(ctx context.Context, in *api.GetKeyRequest) (*api.GetKeyResponse, error) {
auth := s.CreateAuthentication(ctx)
client := &client.DataStorageClientImpl{}
client.SetUpClient(auth, s.DataStorageUrl, s.CertFilePath)
getKeyResponse := &api.GetKeyResponse{}
if in.KeyType == api.KeyType_CERTIFICATE && in.Uuid == "root" {
key := &api.Key{}
data, err := ioutil.ReadFile(s.VereignCertFilePath)
if err != nil {
getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList,
"400", api.StatusType_ERROR, "Can not get root certificate")
return getKeyResponse, nil
}
key.Content = data
key.Revoked = false
getKeyResponse.Key = key
return getKeyResponse, nil
}
if in.KeyType == api.KeyType_KT_EMPTY {
getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList,
"400", api.StatusType_ERROR, "KeyType cannot be empty")
}
data, _ := client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType))
getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList,
"500", api.StatusType_ERROR, data.Errors)
func (s *KeyStorageServerImpl) SetKey(ctx context.Context, in *api.SetKeyRequest) (*api.SetKeyResponse, error) {
auth := s.CreateAuthentication(ctx)
client := &client.DataStorageClientImpl{}
client.SetUpClient(auth, s.DataStorageUrl, s.CertFilePath)
setKeyResponse := &api.SetKeyResponse{}
if in.Uuid == "root" {
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"400", api.StatusType_ERROR, "Can not set root CA keys")
return setKeyResponse, nil
}
if in.KeyType == api.KeyType_KT_EMPTY {
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"400", api.StatusType_ERROR, "KeyType cannot be empty")
data, _ := client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType))
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"400", api.StatusType_ERROR, data.Errors)
return setKeyResponse, nil
}
key := &api.Key{}
proto.Unmarshal(data.Data.Data, key)
if key != nil && key.Content != nil && len(key.Content) > 0 {
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"400", api.StatusType_ERROR, "Key is already set")
result, errors, err := client.DoPutDataCall("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType), in.Key, versions.EntitiesManagementAgentApiVersion)
setKeyResponse.StatusList = handlePutDataErrors(setKeyResponse.StatusList, errors, err)
if setKeyResponse.StatusList == nil || len(setKeyResponse.StatusList) == 0 {
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"200", api.StatusType_INFO, result)
}
return setKeyResponse, nil
func (s *KeyStorageServerImpl) ReserveKeyUUID(ctx context.Context, in *api.ReserveKeyUUIDRequest) (*api.ReserveKeyUUIDResponse, error) {
auth := s.CreateAuthentication(ctx)
client := &client.DataStorageClientImpl{}
client.SetUpClient(auth, s.DataStorageUrl, s.CertFilePath)
reserveKeyUUIDResponse := &api.ReserveKeyUUIDResponse{}
uuid, err := generateUnusedUUID(client)
reserveKeyUUIDResponse.StatusList = utils.AddStatus(reserveKeyUUIDResponse.StatusList,
"500", api.StatusType_INFO, err.Error())
}
emptyKey := &api.Key{
Content: []byte{},
}
result, errors, err := client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE), emptyKey, versions.EntitiesManagementAgentApiVersion)
reserveKeyUUIDResponse.StatusList = handlePutDataErrors(reserveKeyUUIDResponse.StatusList, errors, err)
if reserveKeyUUIDResponse.StatusList == nil || len(reserveKeyUUIDResponse.StatusList) == 0 {
result, errors, err = client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PUBLIC), emptyKey, versions.EntitiesManagementAgentApiVersion)
reserveKeyUUIDResponse.StatusList = handlePutDataErrors(reserveKeyUUIDResponse.StatusList, errors, err)
}
if reserveKeyUUIDResponse.StatusList == nil || len(reserveKeyUUIDResponse.StatusList) == 0 {
result, errors, err = client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_CERTIFICATE), emptyKey, versions.EntitiesManagementAgentApiVersion)
reserveKeyUUIDResponse.StatusList = handlePutDataErrors(reserveKeyUUIDResponse.StatusList, errors, err)
}
if reserveKeyUUIDResponse.StatusList == nil || len(reserveKeyUUIDResponse.StatusList) == 0 {
reserveKeyUUIDResponse.Uuid = uuid
reserveKeyUUIDResponse.StatusList = utils.AddStatus(reserveKeyUUIDResponse.StatusList,
"200", api.StatusType_INFO, result)
return reserveKeyUUIDResponse, nil
}