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 (
"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"
)
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")
data, err := client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType))
if err != nil {
log.Printf("grpc call DoGetDataCall to DataStorage failed: %s", err)
getKeyResponse.Key = nil
getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList,
"500", api.StatusType_ERROR, err.Error())
return getKeyResponse, nil
}
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) {
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, nil
}
if in.KeyType == api.KeyType_KT_EMPTY {
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"400", api.StatusType_ERROR, "KeyType cannot be empty")
data, err := client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(in.KeyType))
if err != nil {
log.Printf("grpc call DoGetDataCall to DataStorage failed: %s", err)
setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
"500", api.StatusType_ERROR, err.Error())
return setKeyResponse, nil
}
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 = 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.DoPutDataCallWithString(keyToKeyIdTable, keyContent,
in.Uuid, versions.EntitiesManagementAgentApiVersion)
if err != nil {
log.Printf("can't DoPutDataCallWithString: %s", err)
return nil, err
}
}
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.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) GetKeyId(ctx context.Context, in *api.GetKeyIdByKeyRequest) (*api.GetKeyIdByKeyResponse, error) {
auth := s.CreateAuthentication(ctx)
//in.PublicKey
entitiesMagamentClient := keyutils.CreateEntitiesManagementClient(auth)
defer entitiesMagamentClient.CloseClient()
dataStorageClient := keyutils.CreateDataStorageClient(auth)
defer dataStorageClient.CloseClient()
keyIdResponse := &api.GetKeyIdByKeyResponse{}
response, err := dataStorageClient.DoGetDataCall(keyToKeyIdTable, in.PublicKey)
if err == nil && response.Data != nil && response.Data.Data != nil {
keyID := string(response.Data.Data)
keyIdResponse.KeyId = keyID
return keyIdResponse, nil
}
entity, err := clientutils.GetLastEntity(entitiesMagamentClient, in.EntityUUID)
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
if err != nil {
return nil, err
}
for _, checkID := range entity.AuthenticationKeys {
key := &api.Key{}
data, err := dataStorageClient.DoGetDataCall("keys", checkID+"/"+api.KeyType_PUBLIC.String())
if err != nil {
log.Printf("grpc call GetKeyId to DataStorage failed: %s", err)
return nil, err
}
if data.Errors != "" {
return nil, errors.New(data.Errors)
} else {
proto.Unmarshal(data.Data.Data, key)
}
keyFromStorage := base64.StdEncoding.EncodeToString(key.Content)
if in.PublicKey != keyFromStorage {
continue
}
_, _, err = dataStorageClient.DoPutDataCallWithString(keyToKeyIdTable, in.PublicKey,
checkID, versions.EntitiesManagementAgentApiVersion)
if err != nil {
log.Printf("can't DoPutDataCallWithString: %s", err)
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