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 (
keyutils "code.vereign.com/code/key-storage-agent/utils"
"code.vereign.com/code/viam-apis/authentication"
"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"
)
const (
keyToKeyIdTable = "authenticationKeyToKeyId"
)
// Server represents the gRPC server
type KeyStorageServerImpl struct {
DataStorageUrl string
CertPEM []byte
KeyPEM []byte
CaCertPEM []byte
VereignCertPEM []byte
VereignPrivateKeyPEM []byte
MaxMessageSize int
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) {
client := keyutils.CreateDataStorageClient(auth)
getKeyResponse := &api.GetKeyResponse{}
if in.KeyType == api.KeyType_CERTIFICATE && in.Uuid == "root" {
key := &api.Key{}
/*data, err := ioutil.ReadFile(s.VereignCertFilePath)
getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList,
"400", api.StatusType_ERROR, "Can not get root certificate")
return getKeyResponse, nil
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")
return getKeyResponse, errors.New("KeyType cannot be empty")
key := &api.Key{}
hasData, errorsString, err := client.GetData("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType), key)
log.Printf("grpc call GetData to DataStorage failed: %s", err)
getKeyResponse.Key = nil
getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList,
"500", api.StatusType_ERROR, err.Error())
getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList,
if !hasData {
log.Println("No such key " + in.Uuid)
getKeyResponse.Key = nil
getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList,
"500", api.StatusType_ERROR, "No such key " + in.Uuid)
return getKeyResponse, errors.New("No such key " + in.Uuid)
func (s *KeyStorageServerImpl) SetKey(ctx context.Context, in *api.SetKeyRequest) (*api.SetKeyResponse, error) {
client := keyutils.CreateDataStorageClient(auth)
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, errors.New("Can not set root CA keys")
if in.KeyType == api.KeyType_KT_EMPTY {
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"400", api.StatusType_ERROR, "KeyType cannot be empty")
return setKeyResponse, errors.New("KeyType cannot be empty")
_, _, err := client.GetData("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType), key)
if err != nil {
log.Printf("grpc call GetData to DataStorage failed: %s", err)
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"500", api.StatusType_ERROR, err.Error())
if len(key.Content) > 0 {
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"400", api.StatusType_ERROR, "Key is already set")
return setKeyResponse, errors.New("Key is already set")
result, errors, err := client.PutData("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType), in.Key)
setKeyResponse.StatusList = keyutils.HandlePutDataErrors(setKeyResponse.StatusList, errors, err)
if setKeyResponse.StatusList == nil || len(setKeyResponse.StatusList) == 0 {
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"200", api.StatusType_INFO, result)
if in.KeyType == api.KeyType_PUBLIC {
keyContent := base64.StdEncoding.EncodeToString(in.Key.Content)
_, _, err = client.PutString(keyToKeyIdTable, keyContent, in.Uuid)
func (s *KeyStorageServerImpl) ReserveKeyUUID(ctx context.Context, in *api.ReserveKeyUUIDRequest) (*api.ReserveKeyUUIDResponse, error) {
auth := s.CreateAuthentication(ctx)
client := keyutils.CreateDataStorageClient(auth)
reserveKeyUUIDResponse := &api.ReserveKeyUUIDResponse{}
uuid, err := keyutils.GenerateUnusedUUID(client)
reserveKeyUUIDResponse.StatusList = utils.AddStatus(reserveKeyUUIDResponse.StatusList,
"500", api.StatusType_INFO, err.Error())
}
emptyKey := &api.Key{
Content: []byte{},
}
result, errors, err := client.PutData("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE), emptyKey)
reserveKeyUUIDResponse.StatusList = keyutils.HandlePutDataErrors(reserveKeyUUIDResponse.StatusList, errors, err)
if reserveKeyUUIDResponse.StatusList == nil || len(reserveKeyUUIDResponse.StatusList) == 0 {
result, errors, err = client.PutData("keys", uuid+"/"+api.KeyType.String(api.KeyType_PUBLIC), emptyKey)
reserveKeyUUIDResponse.StatusList = keyutils.HandlePutDataErrors(reserveKeyUUIDResponse.StatusList, errors, err)
}
if reserveKeyUUIDResponse.StatusList == nil || len(reserveKeyUUIDResponse.StatusList) == 0 {
result, errors, err = client.PutData("keys", uuid+"/"+api.KeyType.String(api.KeyType_CERTIFICATE), emptyKey)
reserveKeyUUIDResponse.StatusList = keyutils.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
}
func (s *KeyStorageServerImpl) GetKeyId(ctx context.Context, in *api.GetKeyIdByKeyRequest) (*api.GetKeyIdByKeyResponse, error) {
auth := s.CreateAuthentication(ctx)
//in.PublicKey
entitiesMagamentClient := keyutils.CreateEntitiesManagementClient(auth)
defer dataStorageClient.CloseClient()
keyIdResponse := &api.GetKeyIdByKeyResponse{}
keyId, errorsString, err := dataStorageClient.GetString(keyToKeyIdTable, in.PublicKey)
if err == nil && errorsString == "" && keyId != "" {
keyIdResponse.KeyId = keyId
} else {
if err != nil {
return nil, err
} else {
return nil, errors.New("Can not get public key")
}
entity, err := clientutils.GetLastEntity(entitiesMagamentClient, in.EntityUUID)
if err != nil {
return nil, err
}
for _, checkID := range entity.AuthenticationKeys {
key := &api.Key{}
hasData, errorsString, err := dataStorageClient.GetData("keys", checkID+"/"+api.KeyType_PUBLIC.String(), key)
log.Printf("grpc call GetData to DataStorage failed: %s", err)
if errorsString != "" {
log.Printf("Error: %s", errorsString)
return nil, errors.New(errorsString)
}
if !hasData {
log.Println("No such checkID " + checkID)
return nil, errors.New("No such checkID " + checkID)
}
keyFromStorage := base64.StdEncoding.EncodeToString(key.Content)
if in.PublicKey != keyFromStorage {
continue
}
_, _, err = dataStorageClient.PutString(keyToKeyIdTable, in.PublicKey, checkID)
return nil, err
}
keyIdResponse.KeyId = checkID
return keyIdResponse, nil
}
//getKeyFromContent
return keyIdResponse, nil
}
func (s *KeyStorageServerImpl) GetVersionKSA(ctx context.Context, in *api.GetVersionKSAMessage) (*api.GetVersionKSAResponseMessage, error) {
return &api.GetVersionKSAResponseMessage{Version: version, Errors: ""}, nil