diff --git a/cert/vereign_ca.cer b/cert/vereign_ca.cer
new file mode 100644
index 0000000000000000000000000000000000000000..6aacfac5ee9a0c352d35ebc86d9e3a4ee848841d
--- /dev/null
+++ b/cert/vereign_ca.cer
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEnjCCA4agAwIBAgIEW2lRSjANBgkqhkiG9w0BAQsFADCBoTETMBEGCgmSJomT
+8ixkARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB3ZlcmVpZ24xCzAJBgNVBAYTAkJH
+MRAwDgYDVQQIDAdQbG92ZGl2MRAwDgYDVQQHDAdQbG92ZGl2MRMwEQYDVQQKDApW
+ZXJlaWduIEFHMRUwEwYDVQQLDAxWZXJlaWduIExhYnMxFDASBgNVBAMMC3ZlcmVp
+Z24uY29tMB4XDTE4MDgwNzA3NTkwNloXDTI4MDgwNzA3NTkwNlowgaExEzARBgoJ
+kiaJk/IsZAEZFgNjb20xFzAVBgoJkiaJk/IsZAEZFgd2ZXJlaWduMQswCQYDVQQG
+EwJCRzEQMA4GA1UECAwHUGxvdmRpdjEQMA4GA1UEBwwHUGxvdmRpdjETMBEGA1UE
+CgwKVmVyZWlnbiBBRzEVMBMGA1UECwwMVmVyZWlnbiBMYWJzMRQwEgYDVQQDDAt2
+ZXJlaWduLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALYs0VOg
+HyXuNbJhYjZBLKoR2EH95VYQ5BStX+KD7ppxlT+H4sxbuj11xVVcDj95aJvlc9Nc
+yBdWktjkIi+MrqoiMM1ljuCzwSsvfnVidWGhZmqSNvEjXgAkX57NoG0U+C9AK16i
+otLApBQ79sXSONfxq2fbdXlaGm98ahCLreomFqKXizkTsOmnirbouJvTX0eFXeaA
++qXPhGpsQxu7vOlWoWqgCAqPAn2krpIBKPvX8n9rL29tFs8JXft0Z5MKykCweP8D
+Sn3e4nmMUDRl8F/0+r+1HIK5FWw2vKUrinMAN/YkpsfEE/flIlZCKg3D8GEYnMFQ
+w9Gaz7NVH87qI8sCAwEAAaOB2zCB2DAeBgNVHREEFzAVgRNjb250YWN0QHZlcmVp
+Z24uY29tMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgH+MIGaBgNVHSUEgZIwgY8G
+CCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCisGAQQBgjcKAwwGCSqGSIb3
+LwEBBQYIKwYBBQUHAwQGCisGAQQBgjcKAwQGCCsGAQUFBwMFBggrBgEFBQcDBgYI
+KwYBBQUHAwcGCCsGAQUFBwMIBggrBgEFBQcDCQYKKwYBBAGCNxQCAgYEVR0lADAN
+BgkqhkiG9w0BAQsFAAOCAQEAMotIWeKzq8T2CZR6hzUMVjBzLfJRnKKXLwoaa3R0
+mXwOcyloQmIQkYqQ7M4ELDEmAtN/f7cE/uBhUdD8UEWn0I4Im6Al8Q7eUFPOAvW3
+uvoqEx5+0sMjsBDUxVW1xkcwYIP9Vpp7occ4Uu0dbj6WR6jsTWQFor+Fc+J4wkRq
+5a4i7pnI78r41rJAHpIUqToLmcoxBOqVrjDys/scCQcxlDGgZcy7T4OFGgJGUdY0
+Zs2W/7GdZUKctb4d+2kWwvA+34w8V9lOBTwM2ddSYS/EkUYMkP93Cb0/LH9Go43u
+U2lEx/41yecR4bipRcwHamTOlvpsFoC9+NjZ0m+l9EM0vA==
+-----END CERTIFICATE-----
diff --git a/cert/vereign_ca.key b/cert/vereign_ca.key
new file mode 100644
index 0000000000000000000000000000000000000000..2bdd81dff19a2917475fa8845923b4021ce475f3
--- /dev/null
+++ b/cert/vereign_ca.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2LNFToB8l7jWy
+YWI2QSyqEdhB/eVWEOQUrV/ig+6acZU/h+LMW7o9dcVVXA4/eWib5XPTXMgXVpLY
+5CIvjK6qIjDNZY7gs8ErL351YnVhoWZqkjbxI14AJF+ezaBtFPgvQCteoqLSwKQU
+O/bF0jjX8atn23V5WhpvfGoQi63qJhail4s5E7Dpp4q26Lib019HhV3mgPqlz4Rq
+bEMbu7zpVqFqoAgKjwJ9pK6SASj71/J/ay9vbRbPCV37dGeTCspAsHj/A0p93uJ5
+jFA0ZfBf9Pq/tRyCuRVsNrylK4pzADf2JKbHxBP35SJWQioNw/BhGJzBUMPRms+z
+VR/O6iPLAgMBAAECggEAG9HMRZD2MLynxo3IibB6OZ5v/+Pd2b7Klb3EHrs2/K7L
+s9/0anC3iBsr/1UHd/n6V5Q6k9RfWfEGi8iKz+gT5DdEbJlNsFLC9O1Tymk2s6oK
+EcwyR7C28h6b24xbK01AeTa7aMA9TSHN7KkbjioENDXbjwicb+OqlcvSBqTN8iuM
+aZrpLHG1ddd7qceUsJuZWkrtC8/RIv/OOPbjdCx2US24T1AgpSANgReHWqk2C8aK
+Bo/Np2NhKKr0lmWN7mhXKBV/OVtM8QPFd8JfsI4vQByd3aV0R5GJpBgX/sP2rQi5
+CnZSV45f6OrYNbzK3DgNdVLFqFUdvAdyroyClTDQgQKBgQDzm6WnmjKg20wUi3tb
+Wy7syU8Ss4WBFeCjt5aVkqeILgdeMwy+FBnXZNfU5enNBTjPMRcAfPuVm0jet79H
+NLgHrTU80sb5fQ0fENlS031OOdEG0PjeoCCGfGsf/YFsmS2WYSHlkYlbibItCmzn
+WTVmu0KIQ3H82YDqz7vu/NQ0WQKBgQC/cSsdwPrMVT1XcSANB77/81v2t3ZVrckx
+gp1KNWKEmaVgWfFsNQ780d4HQAdhKAa9eKRLAL3R7hIDOGXSTPkxEZ95LwkzbNlf
+qSnlxTwhRY41+OHYdjHMzCTu8qoumwPLCrFkKBdU/s5z84HA8KU1nAIAJzz1mNAN
+qbT+Bv/kwwKBgCTSV/23bwOlYiCQ3Lp4U+VyoEMhY4KZffUBIP/GxQ/udSql6L0q
+aKWIFp+ViPt2WJnov6NRQO3iJOeVOpJWw6JVagChk3XOkxcpAtBkK0KRtqijGZr8
+9S2ezMpvFQsHND7Qu8DpeKufapEoTEHD2DCJCYtzNl2TusrDT5LWIHUxAoGADCwe
+6LJnf+x/jPrFZe6zJ0UK+OHrZUE6hKpgY+KHFBVM3ZZ6cj3haRPTATUCAxxvaUat
+c5Nlfl6byJaiar+4LHWJZUQnWpy2KY3w+woSa68nfqkHeyLwwavNQWAuj+4NTLCu
+XMbrzNyytc6q1mC2sHTt76KPDrKbr/K1bl11kc8CgYEAodKJD6bP4w1vWDR08/HU
+T4I0XaKq5X150BbwQZO0axEsuiVwqsosioXYSVAW85NOWSTNDSgpVPCjyWRyHyRL
+cVVrWMQda3Hc/s6EzsiqC0BGw9D0r3TZN8n7Wm+BoNkek//xPhoiLfNTKtwRZIcr
+CikzGE28ynzRwrDK70wV7Q4=
+-----END PRIVATE KEY-----
diff --git a/handler/generate_certificate.go b/handler/generate_certificate.go
new file mode 100644
index 0000000000000000000000000000000000000000..e4d6dba8143d4d16fcef6f6f3cf45f2aead8c02d
--- /dev/null
+++ b/handler/generate_certificate.go
@@ -0,0 +1,244 @@
+/*
+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 (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha256"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/pem"
+	"io/ioutil"
+	"math/big"
+	"time"
+
+	"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"
+	"code.vereign.com/code/viam-apis/versions"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+func (s *KeyStorageServerImpl) GenerateCertificate(ctx context.Context, in *api.GenerateCertificateRequest) (*api.GenerateCertificateResponse, error) {
+	auth := s.CreateAuthentication(ctx)
+
+	client := &client.DataStorageClientImpl{}
+	client.SetUpClient(auth, s.DataStorageUrl, s.CertFilePath)
+	defer client.CloseClient()
+
+	generateCertificateResponse := &api.GenerateCertificateResponse{}
+
+	// Get and decrypt aes key
+	encryptedAesKeyMessage := &api.Key{}
+	data, _ := client.DoGetDataCall("keys", in.Uuid+"/aeskey")
+	if data.Errors != "" {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"400", api.StatusType_ERROR, data.Errors)
+		return generateCertificateResponse, nil
+	}
+
+	proto.Unmarshal(data.Data.Data, encryptedAesKeyMessage)
+
+	aesKeyBytes, err := rsaDecryptWithServerKey(s.VereignPrivateKeyFilePath, encryptedAesKeyMessage.Content, []byte("aeskeys"))
+	if err != nil {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"400", api.StatusType_ERROR, err.Error())
+		return generateCertificateResponse, nil
+	}
+
+	// Get and decrypt rsa private key
+	encryptedPrivateKeyMessage := &api.Key{}
+	data, _ = client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE))
+	if data.Errors != "" {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"400", api.StatusType_ERROR, data.Errors)
+		return generateCertificateResponse, nil
+	}
+	proto.Unmarshal(data.Data.Data, encryptedPrivateKeyMessage)
+
+	nonce := &api.Key{}
+	data, _ = client.DoGetDataCall("keys", in.Uuid+"/privatekey_nonce")
+	if data.Errors != "" {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"400", api.StatusType_ERROR, data.Errors)
+		return generateCertificateResponse, nil
+	}
+	proto.Unmarshal(data.Data.Data, nonce)
+
+	privateKeyBytes, err := aesDecrypt(aesKeyBytes, nonce.Content, encryptedPrivateKeyMessage.Content)
+	if err != nil {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"400", api.StatusType_ERROR, err.Error())
+		return generateCertificateResponse, nil
+	}
+
+	// Get and decrypt rsa public key
+	encryptedPublicKeyMessage := &api.Key{}
+	data, _ = client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(api.KeyType_PUBLIC))
+	if data.Errors != "" {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"400", api.StatusType_ERROR, data.Errors)
+		return generateCertificateResponse, nil
+	}
+	proto.Unmarshal(data.Data.Data, encryptedPublicKeyMessage)
+
+	nonce = &api.Key{}
+	data, _ = client.DoGetDataCall("keys", in.Uuid+"/publickey_nonce")
+	if data.Errors != "" {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"400", api.StatusType_ERROR, data.Errors)
+		return generateCertificateResponse, nil
+	}
+	proto.Unmarshal(data.Data.Data, nonce)
+
+	publicKeyBytes, err := aesDecrypt(aesKeyBytes, nonce.Content, encryptedPublicKeyMessage.Content)
+	if err != nil {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"400", api.StatusType_ERROR, err.Error())
+		return generateCertificateResponse, nil
+	}
+
+	certificateBytes, err := generateCertificate(privateKeyBytes, publicKeyBytes, s.VereignCertFilePath, in.CertificateData)
+	if err != nil {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"400", api.StatusType_ERROR, err.Error())
+		return generateCertificateResponse, nil
+	}
+
+	certificateMessage := &api.Key{
+		Content: certificateBytes,
+	}
+
+	result, errors, err := client.DoPutDataCall("keys", in.Uuid+"/"+api.KeyType.String(api.KeyType_CERTIFICATE), certificateMessage, versions.EntitiesManagementAgentApiVersion)
+	generateCertificateResponse.StatusList = handlePutDataErrors(generateCertificateResponse.StatusList, errors, err)
+
+	if generateCertificateResponse.StatusList == nil || len(generateCertificateResponse.StatusList) == 0 {
+		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList,
+			"200", api.StatusType_INFO, result)
+	}
+
+	return generateCertificateResponse, nil
+}
+
+func generateCertificate(privateKeyBytes []byte, publicKeyBytes []byte, caCertFilePath string,
+	certificateData *api.GenerateCertificateRequest_CertificateData) ([]byte, error) {
+
+	privateKey, err := x509.ParsePKCS8PrivateKey(privateKeyBytes)
+	if err != nil {
+		return nil, err
+	}
+	publicKey, err := x509.ParsePKIXPublicKey(publicKeyBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	notBeforeTime := time.Unix(certificateData.NotBefore.Seconds, int64(certificateData.NotBefore.Nanos)).UTC()
+	notAfterTime := time.Unix(certificateData.NotAfter.Seconds, int64(certificateData.NotAfter.Nanos)).UTC()
+
+	template := x509.Certificate{
+		SerialNumber: big.NewInt(1),
+		Subject: pkix.Name{
+			Country:            []string{certificateData.Country},
+			Organization:       []string{certificateData.Organization},
+			OrganizationalUnit: []string{certificateData.OrganizationalUnit},
+			CommonName:         certificateData.CommonName,
+		},
+		NotBefore:             notBeforeTime,
+		NotAfter:              notAfterTime,
+		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
+		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
+		BasicConstraintsValid: true,
+		IsCA:     false,
+		DNSNames: []string{certificateData.Host},
+	}
+
+	caCertificate, err := readCertificateFromFile(caCertFilePath)
+	if err != nil {
+		return nil, err
+	}
+
+	certificateBytes, err := x509.CreateCertificate(rand.Reader, &template, caCertificate, publicKey, privateKey)
+	if err != nil {
+		return nil, err
+	}
+
+	return certificateBytes, nil
+}
+
+func readPrivateKeyFromFile(fileName string) (*rsa.PrivateKey, error) {
+	privateKeyPemBlock, err := readPemBlockFromFile(fileName)
+	if err != nil {
+		return nil, err
+	}
+
+	parseResult, err := x509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
+	if err != nil {
+		return nil, err
+	}
+	privateKey := parseResult.(*rsa.PrivateKey)
+
+	return privateKey, nil
+}
+
+func readPemBlockFromFile(fileName string) (*pem.Block, error) {
+	fileBytes, err := ioutil.ReadFile(fileName)
+	if err != nil {
+		return nil, err
+	}
+
+	certificatePemBlock, _ := pem.Decode(fileBytes)
+
+	return certificatePemBlock, nil
+}
+
+func rsaDecryptWithServerKey(privateKeyFilePath string, encryptedMessage []byte, label []byte) ([]byte, error) {
+	serverPrivateKey, err := readPrivateKeyFromFile(privateKeyFilePath)
+	if err != nil {
+		return nil, err
+	}
+
+	message, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, serverPrivateKey, encryptedMessage, label)
+	if err != nil {
+		return nil, err
+	}
+
+	return message, nil
+}
+
+func aesDecrypt(aesKey []byte, nonce []byte, encryptedMessage []byte) ([]byte, error) {
+	block, err := aes.NewCipher(aesKey)
+	if err != nil {
+		return nil, err
+	}
+
+	aesgcm, err := cipher.NewGCM(block)
+	if err != nil {
+		return nil, err
+	}
+
+	message, err := aesgcm.Open(nil, nonce, encryptedMessage, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return message, nil
+}
diff --git a/handler/generate_keypair.go b/handler/generate_keypair.go
new file mode 100644
index 0000000000000000000000000000000000000000..8e2ef25340faad611d2d58c4eb5a5d20b081aacd
--- /dev/null
+++ b/handler/generate_keypair.go
@@ -0,0 +1,186 @@
+/*
+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 (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha256"
+	"crypto/x509"
+
+	"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"
+	"code.vereign.com/code/viam-apis/versions"
+	"golang.org/x/net/context"
+)
+
+func (s *KeyStorageServerImpl) GenerateKeyPair(ctx context.Context, in *api.GenerateKeyPairRequest) (*api.GenerateKeyPairResponse, error) {
+	auth := s.CreateAuthentication(ctx)
+
+	client := &client.DataStorageClientImpl{}
+	client.SetUpClient(auth, s.DataStorageUrl, s.CertFilePath)
+	defer client.CloseClient()
+
+	generateKeyPairResponse := &api.GenerateKeyPairResponse{}
+
+	uuid, err := generateUnusedUUID(client)
+	if err != nil {
+		generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList,
+			"500", api.StatusType_ERROR, err.Error())
+	}
+
+	privateKeyBytes, publicKeyBytes, err := generateKeyPair(int(in.KeySize))
+	if err != nil {
+		generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList,
+			"500", api.StatusType_ERROR, err.Error())
+	}
+
+	aesKeyBytes, err := generateRandomSequence(256)
+	if err != nil {
+		generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList,
+			"500", api.StatusType_ERROR, err.Error())
+	}
+	encryptedAesKeyBytes, err := rsaEncryptWithServerKey(s.VereignCertFilePath, aesKeyBytes, []byte("aeskeys"))
+	if err != nil {
+		generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList,
+			"500", api.StatusType_ERROR, err.Error())
+		return generateKeyPairResponse, nil
+	}
+
+	encryptedAesKey := &api.Key{Content: encryptedAesKeyBytes}
+
+	result, errors, err := client.DoPutDataCall("keys", uuid+"/aeskey", encryptedAesKey, versions.EntitiesManagementAgentApiVersion)
+	generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err)
+
+	if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 {
+		encryptedPrivateKeyBytes, nonce, err := aesEncrypt(aesKeyBytes, privateKeyBytes)
+		if err != nil {
+			generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList,
+				"500", api.StatusType_ERROR, err.Error())
+			return generateKeyPairResponse, nil
+		}
+		encryptedPrivateKey := &api.Key{Content: encryptedPrivateKeyBytes}
+		result, errors, err = client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE), encryptedPrivateKey, versions.EntitiesManagementAgentApiVersion)
+		generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err)
+		if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 {
+			nonceMessage := &api.Key{Content: nonce}
+			result, errors, err = client.DoPutDataCall("keys", uuid+"/privatekey_nonce", nonceMessage, versions.EntitiesManagementAgentApiVersion)
+			generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err)
+		}
+	}
+
+	if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 {
+		encryptedPublicKeyBytes, nonce, err := aesEncrypt(aesKeyBytes, publicKeyBytes)
+		if err != nil {
+			generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList,
+				"500", api.StatusType_ERROR, err.Error())
+			return generateKeyPairResponse, nil
+		}
+		encryptedPublicKey := &api.Key{Content: encryptedPublicKeyBytes}
+		result, errors, err = client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PUBLIC), encryptedPublicKey, versions.EntitiesManagementAgentApiVersion)
+		generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err)
+		if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 {
+			nonceMessage := &api.Key{Content: nonce}
+			result, errors, err = client.DoPutDataCall("keys", uuid+"/publickey_nonce", nonceMessage, versions.EntitiesManagementAgentApiVersion)
+			generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err)
+		}
+	}
+
+	if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 {
+		generateKeyPairResponse.Uuid = uuid
+		generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList,
+			"200", api.StatusType_INFO, result)
+	}
+
+	return generateKeyPairResponse, nil
+}
+
+func generateKeyPair(keySize int) ([]byte, []byte, error) {
+	privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	err = privateKey.Validate()
+	if err != nil {
+		return nil, nil, err
+	}
+
+	publicKey := &privateKey.PublicKey
+
+	privateKeyBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
+	if err != nil {
+		return nil, nil, err
+	}
+	publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return privateKeyBytes, publicKeyBytes, nil
+}
+
+func rsaEncryptWithServerKey(certFilePath string, message []byte, label []byte) ([]byte, error) {
+	serverCertificate, err := readCertificateFromFile(certFilePath)
+	if err != nil {
+		return nil, err
+	}
+	serverPublicKey := serverCertificate.PublicKey.(*rsa.PublicKey)
+
+	encryptedMessageBytes, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, serverPublicKey, message, label)
+	if err != nil {
+		return nil, err
+	}
+
+	return encryptedMessageBytes, nil
+}
+
+func aesEncrypt(aesKey []byte, message []byte) ([]byte, []byte, error) {
+	block, err := aes.NewCipher(aesKey)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	aesgcm, err := cipher.NewGCM(block)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	nonce, err := generateRandomSequence(aesgcm.NonceSize() * 8)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	encryptedMessage := aesgcm.Seal(nil, nonce, message, nil)
+
+	return encryptedMessage, nonce, nil
+}
+
+func generateRandomSequence(keySize int) ([]byte, error) {
+	key := make([]byte, keySize/8)
+
+	_, err := rand.Read(key)
+	if err != nil {
+		return nil, err
+	}
+
+	return key, nil
+}
diff --git a/handler/handler.go b/handler/handler.go
index 99000df4702e059355e5444d5c76d8022edccf13..293a3408d8ed1346e9a112df4d0d895f0cce61aa 100644
--- a/handler/handler.go
+++ b/handler/handler.go
@@ -18,16 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
 package handler
 
 import (
-	"crypto/rand"
-	"crypto/rsa"
-	"crypto/x509"
-	"crypto/x509/pkix"
-	"fmt"
-	"io"
-	"log"
-	"math/big"
 	"strings"
-	"time"
 
 	"code.vereign.com/code/viam-apis/versions"
 	"github.com/golang/protobuf/proto"
@@ -42,8 +33,10 @@ import (
 
 // Server represents the gRPC server
 type KeyStorageServerImpl struct {
-	DataStorageUrl string
-	CertPath       string
+	DataStorageUrl            string
+	CertFilePath              string
+	VereignCertFilePath       string
+	VereignPrivateKeyFilePath string
 }
 
 func (s *KeyStorageServerImpl) CreateAuthentication(ctx context.Context) *authentication.Authentication {
@@ -66,20 +59,22 @@ func (s *KeyStorageServerImpl) GetKey(ctx context.Context, in *api.GetKeyRequest
 	auth := s.CreateAuthentication(ctx)
 
 	client := &client.DataStorageClientImpl{}
-	client.SetUpClient(auth, s.DataStorageUrl, s.CertPath)
+	client.SetUpClient(auth, s.DataStorageUrl, s.CertFilePath)
 	defer client.CloseClient()
 
 	getKeyResponse := &api.GetKeyResponse{}
 
 	if in.KeyType == api.KeyType_KT_EMPTY {
-		getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList, "400", api.StatusType_ERROR, "KeyType cannot be 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))
 
 	if data.Errors != "" {
 		getKeyResponse.Key = nil
-		getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList, "500", api.StatusType_ERROR, data.Errors)
+		getKeyResponse.StatusList = utils.AddStatus(getKeyResponse.StatusList,
+			"500", api.StatusType_ERROR, data.Errors)
 	} else {
 		key := &api.Key{}
 		proto.Unmarshal(data.Data.Data, key)
@@ -93,19 +88,29 @@ func (s *KeyStorageServerImpl) SetKey(ctx context.Context, in *api.SetKeyRequest
 	auth := s.CreateAuthentication(ctx)
 
 	client := &client.DataStorageClientImpl{}
-	client.SetUpClient(auth, s.DataStorageUrl, s.CertPath)
+	client.SetUpClient(auth, s.DataStorageUrl, s.CertFilePath)
 	defer client.CloseClient()
 
 	setKeyResponse := &api.SetKeyResponse{}
 
 	if in.KeyType == api.KeyType_KT_EMPTY {
-		setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList, "400", api.StatusType_ERROR, "KeyType cannot be 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))
 
 	if data.Errors != "" {
-		setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList, "400", api.StatusType_ERROR, 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
 	}
 
@@ -113,105 +118,32 @@ func (s *KeyStorageServerImpl) SetKey(ctx context.Context, in *api.SetKeyRequest
 	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)
+		setKeyResponse.StatusList = utils.AddStatus(setKeyResponse.StatusList,
+			"200", api.StatusType_INFO, result)
 	}
 
 	return setKeyResponse, nil
 }
 
-func (s *KeyStorageServerImpl) GenerateKeyPair(ctx context.Context, in *api.GenerateKeyPairRequest) (*api.GenerateKeyPairResponse, error) {
-	auth := s.CreateAuthentication(ctx)
-
-	client := &client.DataStorageClientImpl{}
-	client.SetUpClient(auth, s.DataStorageUrl, s.CertPath)
-	defer client.CloseClient()
-
-	uuid, err := newUUID()
-	privateKeyBytes, publicKeyBytes, _ := generateKeyPair(int(in.KeySize * 8))
-
-	privateKey := &api.Key{Content: privateKeyBytes}
-	publicKey := &api.Key{Content: publicKeyBytes}
-
-	generateKeyPairResponse := &api.GenerateKeyPairResponse{
-		Uuid: uuid,
-	}
-
-	result, errors, err := client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE), privateKey, versions.EntitiesManagementAgentApiVersion)
-	generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err)
-
-	if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 {
-		result, errors, err = client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PUBLIC), publicKey, versions.EntitiesManagementAgentApiVersion)
-		generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err)
-	}
-
-	if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 {
-		generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList, "200", api.StatusType_INFO, result)
-	}
-
-	return generateKeyPairResponse, nil
-}
-
-func (s *KeyStorageServerImpl) GenerateCertificate(ctx context.Context, in *api.GenerateCertificateRequest) (*api.GenerateCertificateResponse, error) {
+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.CertPath)
+	client.SetUpClient(auth, s.DataStorageUrl, s.CertFilePath)
 	defer client.CloseClient()
 
-	generateCertificateResponse := &api.GenerateCertificateResponse{}
-
-	privateKeyMessage := &api.Key{}
-	publicKeyMessage := &api.Key{}
-
-	data, _ := client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE))
-	if data.Errors != "" {
-		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList, "400", api.StatusType_ERROR, data.Errors)
-	} else {
-		proto.Unmarshal(data.Data.Data, privateKeyMessage)
-	}
-
-	data, _ = client.DoGetDataCall("keys", in.Uuid+"/"+api.KeyType.String(api.KeyType_PUBLIC))
-	if data.Errors != "" {
-		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList, "400", api.StatusType_ERROR, data.Errors)
-	} else {
-		proto.Unmarshal(data.Data.Data, publicKeyMessage)
-	}
+	reserveKeyUUIDResponse := &api.ReserveKeyUUIDResponse{}
 
-	certificateBytes, err := generateCertificate(privateKeyMessage.Content, publicKeyMessage.Content, in.CertificateData)
+	uuid, err := generateUnusedUUID(client)
 	if err != nil {
-		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList, "400", api.StatusType_ERROR, err.Error())
+		reserveKeyUUIDResponse.StatusList = utils.AddStatus(reserveKeyUUIDResponse.StatusList,
+			"500", api.StatusType_INFO, err.Error())
 	}
 
-	certificateMessage := &api.Key{
-		Content: certificateBytes,
-	}
-
-	result, errors, err := client.DoPutDataCall("keys", in.Uuid+"/"+api.KeyType.String(api.KeyType_CERTIFICATE), certificateMessage, versions.EntitiesManagementAgentApiVersion)
-	generateCertificateResponse.StatusList = handlePutDataErrors(generateCertificateResponse.StatusList, errors, err)
-
-	if generateCertificateResponse.StatusList == nil || len(generateCertificateResponse.StatusList) == 0 {
-		generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList, "200", api.StatusType_INFO, result)
-	}
-
-	return generateCertificateResponse, 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.CertPath)
-	defer client.CloseClient()
-
-	uuid, err := newUUID()
 	emptyKey := &api.Key{
 		Content: []byte{},
 	}
 
-	reserveKeyUUIDResponse := &api.ReserveKeyUUIDResponse{
-		Uuid: uuid,
-	}
-
 	result, errors, err := client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE), emptyKey, versions.EntitiesManagementAgentApiVersion)
 	reserveKeyUUIDResponse.StatusList = handlePutDataErrors(reserveKeyUUIDResponse.StatusList, errors, err)
 
@@ -226,88 +158,10 @@ func (s *KeyStorageServerImpl) ReserveKeyUUID(ctx context.Context, in *api.Reser
 	}
 
 	if reserveKeyUUIDResponse.StatusList == nil || len(reserveKeyUUIDResponse.StatusList) == 0 {
-		reserveKeyUUIDResponse.StatusList = utils.AddStatus(reserveKeyUUIDResponse.StatusList, "200", api.StatusType_INFO, result)
+		reserveKeyUUIDResponse.Uuid = uuid
+		reserveKeyUUIDResponse.StatusList = utils.AddStatus(reserveKeyUUIDResponse.StatusList,
+			"200", api.StatusType_INFO, result)
 	}
 
 	return reserveKeyUUIDResponse, nil
 }
-
-func generateKeyPair(bitSize int) ([]byte, []byte, error) {
-	privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	err = privateKey.Validate()
-	if err != nil {
-		return nil, nil, err
-	}
-
-	publicKey := &privateKey.PublicKey
-
-	privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)
-	publicKeyBytes := x509.MarshalPKCS1PublicKey(publicKey)
-
-	return privateKeyBytes, publicKeyBytes, nil
-}
-
-func generateCertificate(privateKeyBytes []byte, publicKeyBytes []byte, certificateData *api.GenerateCertificateRequest_CertificateData) ([]byte, error) {
-
-	privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBytes)
-	if err != nil {
-		return nil, err
-	}
-	publicKey, err := x509.ParsePKCS1PublicKey(publicKeyBytes)
-	if err != nil {
-		return nil, err
-	}
-
-	notBeforeTime := time.Unix(certificateData.NotBefore.Seconds, int64(certificateData.NotBefore.Nanos)).UTC()
-	notAfterTime := time.Unix(certificateData.NotAfter.Seconds, int64(certificateData.NotAfter.Nanos)).UTC()
-
-	template := x509.Certificate{
-		SerialNumber: big.NewInt(1),
-		Subject: pkix.Name{
-			Country:            []string{certificateData.Country},
-			Organization:       []string{certificateData.Organization},
-			OrganizationalUnit: []string{certificateData.OrganizationalUnit},
-			CommonName:         certificateData.CommonName,
-		},
-		NotBefore:             notBeforeTime,
-		NotAfter:              notAfterTime,
-		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
-		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
-		BasicConstraintsValid: true,
-		IsCA:     true,
-		DNSNames: []string{certificateData.Host},
-	}
-
-	certificateBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey, privateKey)
-	if err != nil {
-		log.Fatalf("Failed to create certificate: %s", err)
-	}
-
-	return certificateBytes, nil
-}
-func newUUID() (string, error) {
-	uuid := make([]byte, 16)
-	n, err := io.ReadFull(rand.Reader, uuid)
-	if n != len(uuid) || err != nil {
-		return "", err
-	}
-
-	uuid[8] = uuid[8]&^0xc0 | 0x80
-	uuid[6] = uuid[6]&^0xf0 | 0x40
-
-	return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
-}
-
-func handlePutDataErrors(statusList []*api.Status, errors string, err error) []*api.Status {
-	if err != nil {
-		statusList = utils.AddStatus(statusList, "500", api.StatusType_ERROR, err.Error())
-	} else if errors != "" {
-		statusList = utils.AddStatus(statusList, "400", api.StatusType_ERROR, errors)
-	}
-
-	return statusList
-}
diff --git a/handler/revoke.go b/handler/revoke.go
new file mode 100644
index 0000000000000000000000000000000000000000..2b779ed3372b1ef99fa2ba7d12823a8596386d84
--- /dev/null
+++ b/handler/revoke.go
@@ -0,0 +1,79 @@
+/*
+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/data-storage-agent/client"
+	"code.vereign.com/code/viam-apis/key-storage-agent/api"
+	"code.vereign.com/code/viam-apis/utils"
+	"code.vereign.com/code/viam-apis/versions"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+func (s *KeyStorageServerImpl) Revoke(ctx context.Context, in *api.RevokeRequest) (*api.RevokeResponse, error) {
+	auth := s.CreateAuthentication(ctx)
+
+	client := &client.DataStorageClientImpl{}
+	client.SetUpClient(auth, s.DataStorageUrl, s.CertFilePath)
+	defer client.CloseClient()
+
+	revokeResponse := &api.RevokeResponse{}
+
+	revokeResponse.StatusList = revokeKey(client, in.Uuid, api.KeyType_PRIVATE)
+	if revokeResponse.StatusList != nil {
+		return revokeResponse, nil
+	}
+
+	revokeResponse.StatusList = revokeKey(client, in.Uuid, api.KeyType_PUBLIC)
+	if revokeResponse.StatusList != nil {
+		return revokeResponse, nil
+	}
+
+	revokeResponse.StatusList = revokeKey(client, in.Uuid, api.KeyType_CERTIFICATE)
+	if revokeResponse.StatusList != nil {
+		return revokeResponse, nil
+	}
+
+	revokeResponse.StatusList = utils.AddStatus(revokeResponse.StatusList, "200", api.StatusType_INFO, "Keys revoked")
+	return revokeResponse, nil
+}
+
+func revokeKey(client *client.DataStorageClientImpl, uuid string, keyType api.KeyType) []*api.Status {
+
+	statusList := []*api.Status{}
+
+	data, _ := client.DoGetDataCall("keys", uuid+"/"+api.KeyType.String(keyType))
+	if data.Errors != "" {
+		statusList = utils.AddStatus(statusList, "400", api.StatusType_ERROR, data.Errors)
+		return statusList
+	}
+
+	key := &api.Key{}
+	proto.Unmarshal(data.Data.Data, key)
+
+	key.Revoked = true
+
+	_, errors, err := client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(keyType), key, versions.EntitiesManagementAgentApiVersion)
+	statusList = handlePutDataErrors(statusList, errors, err)
+	if statusList != nil && len(statusList) > 0 {
+		return statusList
+	}
+
+	return nil
+}
diff --git a/handler/utils.go b/handler/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..a489edca30ce359b8bf3431d6faced0b2797c520
--- /dev/null
+++ b/handler/utils.go
@@ -0,0 +1,85 @@
+/*
+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 (
+	"crypto/rand"
+	"crypto/x509"
+	"errors"
+	"fmt"
+	"io"
+
+	"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"
+)
+
+func generateUnusedUUID(client *client.DataStorageClientImpl) (string, error) {
+	count := 0
+	for {
+		uuid, err := newUUID()
+
+		// check that uuid is not used
+		data, _ := client.DoGetDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE))
+
+		if data.Errors != "" || err != nil {
+			return uuid, nil
+		}
+		if count >= 10 {
+			return "", errors.New("Could not generate unused UUID in 10 tries")
+		}
+		count++
+	}
+}
+
+func newUUID() (string, error) {
+	uuid := make([]byte, 16)
+	n, err := io.ReadFull(rand.Reader, uuid)
+	if n != len(uuid) || err != nil {
+		return "", err
+	}
+
+	uuid[8] = uuid[8]&^0xc0 | 0x80
+	uuid[6] = uuid[6]&^0xf0 | 0x40
+
+	return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
+}
+
+func handlePutDataErrors(statusList []*api.Status, errors string, err error) []*api.Status {
+	if err != nil {
+		statusList = utils.AddStatus(statusList, "500", api.StatusType_ERROR, err.Error())
+	} else if errors != "" {
+		statusList = utils.AddStatus(statusList, "400", api.StatusType_ERROR, errors)
+	}
+
+	return statusList
+}
+
+func readCertificateFromFile(fileName string) (*x509.Certificate, error) {
+	certificatePemBlock, err := readPemBlockFromFile(fileName)
+	if err != nil {
+		return nil, err
+	}
+
+	certificate, err := x509.ParseCertificate(certificatePemBlock.Bytes)
+	if err != nil {
+		return nil, err
+	}
+
+	return certificate, nil
+}
diff --git a/main.go b/main.go
index 8cadaaafeb8faa93c0a0383cadb741b23c9a615a..0ed788dfa721c3818628fccaee0d525e01a7c1b3 100644
--- a/main.go
+++ b/main.go
@@ -39,12 +39,15 @@ func main() {
 	restAddress := fmt.Sprintf("%s:%d", "localhost", 7878)
 	dataStorageAddress := fmt.Sprintf("%s:%d", "localhost", 7777)
 
-	certFile := certDir + "/server.crt"
-	keyFile := certDir + "/server.key"
+	certFilePath := certDir + "/server.crt"
+	privateKeyFilePath := certDir + "/server.key"
+	vereignCertFilePath := certDir + "/vereign_ca.cer"
+	vereignPrivateKeyFilePath := certDir + "/vereign_ca.key"
 
 	// fire the gRPC server in a goroutine
 	go func() {
-		err := server.StartGRPCServer(grpcAddress, certFile, keyFile, dataStorageAddress)
+		err := server.StartGRPCServer(grpcAddress, certFilePath, privateKeyFilePath, vereignCertFilePath,
+			vereignPrivateKeyFilePath, dataStorageAddress)
 		if err != nil {
 			log.Fatalf("failed to start gRPC server: %s", err)
 		}
@@ -52,7 +55,7 @@ func main() {
 
 	// fire the REST server in a goroutine
 	go func() {
-		err := server.StartRESTServer(restAddress, grpcAddress, certFile)
+		err := server.StartRESTServer(restAddress, grpcAddress, certFilePath)
 		if err != nil {
 			log.Fatalf("failed to start gRPC server: %s", err)
 		}
diff --git a/server/server.go b/server/server.go
index fa6892a8ba25068b898872887bdca0f0940a8d20..40e6a427ae6e7f8f8a88598daba917a20cf12029 100644
--- a/server/server.go
+++ b/server/server.go
@@ -106,8 +106,8 @@ func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServ
 	return handler1(ctx, req)
 }
 
-func StartGRPCServer(address, certFile, keyFile, dataStorageAddress string) error {
-	pkgCertFile = certFile
+func StartGRPCServer(address, certFilePath, privateKeyFilePath, vereignCertFilePath, vereignPrivateKeyFilePath, dataStorageAddress string) error {
+	pkgCertFile = certFilePath
 
 	// create a listener on TCP port
 	lis, err := net.Listen("tcp", address)
@@ -117,12 +117,14 @@ func StartGRPCServer(address, certFile, keyFile, dataStorageAddress string) erro
 
 	// create a server instance
 	s := handler.KeyStorageServerImpl{
-		DataStorageUrl: dataStorageAddress,
-		CertPath:       certFile,
+		DataStorageUrl:            dataStorageAddress,
+		CertFilePath:              certFilePath,
+		VereignCertFilePath:       vereignCertFilePath,
+		VereignPrivateKeyFilePath: vereignPrivateKeyFilePath,
 	}
 
 	// Create the TLS credentials
-	creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
+	creds, err := credentials.NewServerTLSFromFile(certFilePath, privateKeyFilePath)
 	if err != nil {
 		return fmt.Errorf("could not load TLS keys: %s", err)
 	}
diff --git a/server/server_test.go b/server/server_test.go
index 42c383b5e849f108af2c4b727ebd2a83f845c517..33f1aa4d0e21242e0f5dc38e3b171c25c5b12147 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -32,14 +32,16 @@ import (
 )
 
 const (
-	dataStorageGrpcAddress = "localhost:7777"
-	keyStorageGrpcAddress  = "localhost:7877"
-	certFile               = "../cert/server.crt"
-	keyFile                = "../cert/server.key"
+	dataStorageGrpcAddress    = "localhost:7777"
+	keyStorageGrpcAddress     = "localhost:7877"
+	certFilePath              = "../cert/server.crt"
+	privateKeyFilePath        = "../cert/server.key"
+	vereignCertFilePath       = "../cert/vereign_ca.cer"
+	vereignPrivateKeyFilePath = "../cert/vereign_ca.key"
 )
 
 func TestSetAndGetKeys(t *testing.T) {
-	dataStorageClient := utils.CreateClientFromUuidAndSession("viam-system", "viam-session", dataStorageGrpcAddress, certFile)
+	dataStorageClient := utils.CreateClientFromUuidAndSession("viam-system", "viam-session", dataStorageGrpcAddress, certFilePath)
 
 	keyStorageAuth := &authentication.Authentication{
 		Uuid:    "some-uuid",
@@ -49,7 +51,7 @@ func TestSetAndGetKeys(t *testing.T) {
 	_, _, _ = dataStorageClient.RenewSession(keyStorageAuth.Uuid, keyStorageAuth.Session)
 
 	keyStorageClient := &ksclient.KeyStorageClientImpl{}
-	keyStorageClient.SetUpClient(keyStorageAuth, keyStorageGrpcAddress, certFile)
+	keyStorageClient.SetUpClient(keyStorageAuth, keyStorageGrpcAddress, certFilePath)
 	defer keyStorageClient.CloseClient()
 
 	uuid, statusList, _ := keyStorageClient.DoReserveKeyUUID()
@@ -83,6 +85,15 @@ func TestSetAndGetKeys(t *testing.T) {
 			[]byte{0, 1, 2}, privateKeyResult.Content)
 	}
 
+	// Test setting the same key twice
+	statusList, _ = keyStorageClient.DoSetKey(uuid, ksapi.KeyType_PRIVATE, privateKey)
+	for _, status := range statusList {
+		if status.StatusType != ksapi.StatusType_ERROR {
+			t.Errorf("DoSetKey, expected error, but got success")
+			return
+		}
+	}
+
 	publicKey := &ksapi.Key{
 		Content: []byte{3, 4, 2},
 	}
@@ -104,9 +115,34 @@ func TestSetAndGetKeys(t *testing.T) {
 		t.Errorf("DoGetKey, incorrect publicKeyResult.Content, expected: %v, but was: %v",
 			[]byte{3, 4, 2}, publicKeyResult.Content)
 	}
+
+	statusList, _ = keyStorageClient.DoRevoke(uuid)
+	for _, status := range statusList {
+		if status.StatusType == ksapi.StatusType_ERROR {
+			t.Errorf("DoRevoke, returned error: %s.", status.Code+":"+status.Description)
+		}
+	}
+	revokedPrivateKeyResult, statusList, _ := keyStorageClient.DoGetKey(uuid, ksapi.KeyType_PRIVATE)
+	for _, status := range statusList {
+		if status.StatusType == ksapi.StatusType_ERROR {
+			t.Errorf("DoGetKey, returned error: %s.", status.Code+":"+status.Description)
+		}
+	}
+	if revokedPrivateKeyResult.Revoked == false {
+		t.Errorf("DoRevoke, key was not revoked")
+	}
+	revokedPublicKeyResult, statusList, _ := keyStorageClient.DoGetKey(uuid, ksapi.KeyType_PUBLIC)
+	for _, status := range statusList {
+		if status.StatusType == ksapi.StatusType_ERROR {
+			t.Errorf("DoGetKey, returned error: %s.", status.Code+":"+status.Description)
+		}
+	}
+	if revokedPublicKeyResult.Revoked == false {
+		t.Errorf("DoRevoke, key was not revoked")
+	}
 }
 func TestGenerateKeyPairAndCertificate(t *testing.T) {
-	dataStorageClient := utils.CreateClientFromUuidAndSession("viam-system", "viam-session", dataStorageGrpcAddress, certFile)
+	dataStorageClient := utils.CreateClientFromUuidAndSession("viam-system", "viam-session", dataStorageGrpcAddress, certFilePath)
 
 	keyStorageAuth := &authentication.Authentication{
 		Uuid:    "some-uuid",
@@ -116,10 +152,10 @@ func TestGenerateKeyPairAndCertificate(t *testing.T) {
 	_, _, _ = dataStorageClient.RenewSession(keyStorageAuth.Uuid, keyStorageAuth.Session)
 
 	keyStorageClient := &ksclient.KeyStorageClientImpl{}
-	keyStorageClient.SetUpClient(keyStorageAuth, keyStorageGrpcAddress, certFile)
+	keyStorageClient.SetUpClient(keyStorageAuth, keyStorageGrpcAddress, certFilePath)
 	defer keyStorageClient.CloseClient()
 
-	uuid, statusList, _ := keyStorageClient.DoGenerateKeyPair(256)
+	uuid, statusList, _ := keyStorageClient.DoGenerateKeyPair(2048)
 	for _, status := range statusList {
 		if status.StatusType == ksapi.StatusType_ERROR {
 			t.Errorf("DoGenerateKeyPair, returned error: %s.", status.Code+":"+status.Description)
@@ -191,15 +227,15 @@ func TestGenerateKeyPairAndCertificate(t *testing.T) {
 			t.Errorf("DoGetKey, returned error: %s.", status.Code+":"+status.Description)
 		}
 	}
-	if certificate.Content == nil {
-		t.Errorf("DoGetKey, certificate.Content is nil")
+	if certificate == nil || certificate.Content == nil {
+		t.Errorf("DoGetKey, certificate is nil")
 	}
 }
 
 func TestMain(m *testing.M) {
 	// fire the gRPC server in a goroutine
 	go func() {
-		err := dataStorageServer.StartGRPCServer(dataStorageGrpcAddress, certFile, keyFile)
+		err := dataStorageServer.StartGRPCServer(dataStorageGrpcAddress, certFilePath, privateKeyFilePath)
 		if err != nil {
 			log.Fatalf("failed to start gRPC server: %s", err)
 		}
@@ -210,7 +246,8 @@ func TestMain(m *testing.M) {
 
 	// fire the gRPC server in a goroutine
 	go func() {
-		err := StartGRPCServer(keyStorageGrpcAddress, certFile, keyFile, dataStorageGrpcAddress)
+		err := StartGRPCServer(keyStorageGrpcAddress, certFilePath, privateKeyFilePath,
+			vereignCertFilePath, vereignPrivateKeyFilePath, dataStorageGrpcAddress)
 		if err != nil {
 			log.Fatalf("failed to start gRPC server: %s", err)
 		}