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"
"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
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)
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
if in.KeyType == api.KeyType_KT_EMPTY {
return nil, errors.NewUser("KeyType cannot be empty")
hasData, _, err := client.GetData("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType), key)
log.Printf("grpc call GetData to DataStorage failed: %s", err)
if !hasData {
log.Println("No such key " + in.Uuid)
return nil, errors.NewUser("No such key " + in.Uuid)
func (s *KeyStorageServerImpl) SetKey(ctx context.Context, in *api.SetKeyRequest) (*api.SetKeyResponse, error) {
client := keyutils.CreateDataStorageClient(auth)
return nil, errors.NewUser("Can not set root CA keys")
if in.KeyType == api.KeyType_KT_EMPTY {
return nil, errors.NewUser("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)
return nil, errors.WrapInternalFormat(err, "grpc call GetData to DataStorage failed: %s", err)
_, _, err := client.PutData("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType), in.Key)
if err != nil {
return nil, err
if in.KeyType == api.KeyType_PUBLIC {
keyContent := base64.StdEncoding.EncodeToString(in.Key.Content)
_, _, err = client.PutString(keyToKeyIdTable, keyContent, in.Uuid)
return nil, errors.WrapInternal(err, "can't PutString")
func (s *KeyStorageServerImpl) ReserveKeyUUID(ctx context.Context, in *api.ReserveKeyUUIDRequest) (*api.ReserveKeyUUIDResponse, error) {
auth := s.CreateAuthentication(ctx)
client := keyutils.CreateDataStorageClient(auth)
uuid, err := keyutils.GenerateUnusedUUID(client)
}
emptyKey := &api.Key{
Content: []byte{},
}
_, _, err = client.PutData("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE), emptyKey)
if err != nil {
return nil, errors.WrapInternalFormat(err, "Could not store key %s", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE))
_, _, err = client.PutData("keys", uuid+"/"+api.KeyType.String(api.KeyType_PUBLIC), emptyKey)
if err != nil {
return nil, errors.WrapInternalFormat(err, "Could not store key %s", uuid+"/"+api.KeyType.String(api.KeyType_PUBLIC))
_, _, err = client.PutData("keys", uuid+"/"+api.KeyType.String(api.KeyType_CERTIFICATE), emptyKey)
if err != nil {
return nil, errors.WrapInternalFormat(err, "Could not store key %s", uuid+"/"+api.KeyType.String(api.KeyType_CERTIFICATE))
reserveKeyUUIDResponse := &api.ReserveKeyUUIDResponse{Uuid: uuid}
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}, nil