/* 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 ( "log" "strings" "code.vereign.com/code/viam-apis/versions" "github.com/golang/protobuf/proto" 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" ) // Server represents the gRPC server type KeyStorageServerImpl struct { DataStorageUrl string CertPEM []byte KeyPEM []byte CaCertPEM []byte VereignCertPEM []byte VereignPrivateKeyPEM []byte MaxMessageSize int } var version = "undefined" 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 := keyutils.CreateDataStorageClient(auth) defer client.CloseClient() getKeyResponse := &api.GetKeyResponse{} if in.KeyType == api.KeyType_CERTIFICATE && in.Uuid == "root" { key := &api.Key{} /*data, err := ioutil.ReadFile(s.VereignCertFilePath) if err != nil { log.Printf("Error: %v", err) getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList, "400", api.StatusType_ERROR, "Can not get root certificate") return getKeyResponse, nil }*/ key.Content = s.VereignCertPEM 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, nil } data, err := client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType)) if err != nil { getKeyResponse.Key = nil getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList, "500", api.StatusType_ERROR, err.Error()) return getKeyResponse, nil } if data.Errors != "" { getKeyResponse.Key = nil getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList, "500", api.StatusType_ERROR, data.Errors) } else { key := &api.Key{} proto.Unmarshal(data.Data.Data, key) getKeyResponse.Key = key } return getKeyResponse, nil } func (s *KeyStorageServerImpl) SetKey(ctx context.Context, in *api.SetKeyRequest) (*api.SetKeyResponse, error) { auth := s.CreateAuthentication(ctx) client := keyutils.CreateDataStorageClient(auth) defer client.CloseClient() 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") return setKeyResponse, nil } data, err := client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType)) if err != nil { setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList, "500", api.StatusType_ERROR, err.Error()) return setKeyResponse, nil } if data.Errors != "" { 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") return setKeyResponse, nil } result, errors, err := client.DoPutDataCall("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType), in.Key, versions.EntitiesManagementAgentApiVersion) 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) } return setKeyResponse, nil } func (s *KeyStorageServerImpl) ReserveKeyUUID(ctx context.Context, in *api.ReserveKeyUUIDRequest) (*api.ReserveKeyUUIDResponse, error) { auth := s.CreateAuthentication(ctx) client := keyutils.CreateDataStorageClient(auth) defer client.CloseClient() reserveKeyUUIDResponse := &api.ReserveKeyUUIDResponse{} uuid, err := keyutils.GenerateUnusedUUID(client) if err != nil { log.Printf("Error: %v", err) 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 = keyutils.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 = keyutils.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 = 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) GetVersionKSA(ctx context.Context, in *api.GetVersionKSAMessage) (*api.GetVersionKSAResponseMessage, error) { log.Println("Version: " + version) return &api.GetVersionKSAResponseMessage{Version: version, Errors: ""}, nil }