diff --git a/handler/generate_certificate.go b/handler/generate_certificate.go index 07caca54c709261075ae497db352e848c7c74f95..54364e9f767976ba703820da6e2125662cfaf566 100644 --- a/handler/generate_certificate.go +++ b/handler/generate_certificate.go @@ -18,11 +18,8 @@ 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" @@ -34,7 +31,6 @@ import ( "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" ) @@ -47,48 +43,14 @@ func (s *KeyStorageServerImpl) GenerateCertificate(ctx context.Context, in *api. generateCertificateResponse := &api.GenerateCertificateResponse{} - aesKeyBytes, err := rsaDecryptWithServerKey(s.VereignPrivateKeyFilePath, in.EncryptedAesKey, []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) + publicKeyMessage, statusList := getKey(client, in.Uuid, api.KeyType_PUBLIC) + if statusList != nil { + generateCertificateResponse.StatusList = statusList return generateCertificateResponse, nil } - proto.Unmarshal(data.Data.Data, encryptedPrivateKeyMessage) - privateKeyBytes, err := aesDecrypt(aesKeyBytes, in.PrivateKeyNonce, 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) - - publicKeyBytes, err := aesDecrypt(aesKeyBytes, in.PublicKeyNonce, 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) + certificateBytes, err := generateCertificate(publicKeyMessage.Content, s.VereignCertFilePath, + s.VereignPrivateKeyFilePath, in.CertificateData) if err != nil { generateCertificateResponse.StatusList = utils.AddStatus(generateCertificateResponse.StatusList, "400", api.StatusType_ERROR, err.Error()) @@ -110,13 +72,9 @@ func (s *KeyStorageServerImpl) GenerateCertificate(ctx context.Context, in *api. return generateCertificateResponse, nil } -func generateCertificate(privateKeyBytes []byte, publicKeyBytes []byte, caCertFilePath string, +func generateCertificate(publicKeyBytes []byte, caCertFilePath string, caPrivateKeyFilePath 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 @@ -146,8 +104,12 @@ func generateCertificate(privateKeyBytes []byte, publicKeyBytes []byte, caCertFi if err != nil { return nil, err } + caPrivateKey, err := readPrivateKeyFromFile(caPrivateKeyFilePath) + if err != nil { + return nil, err + } - certificateBytes, err := x509.CreateCertificate(rand.Reader, &template, caCertificate, publicKey, privateKey) + certificateBytes, err := x509.CreateCertificate(rand.Reader, &template, caCertificate, publicKey, caPrivateKey) if err != nil { return nil, err } @@ -180,36 +142,3 @@ func readPemBlockFromFile(fileName string) (*pem.Block, error) { 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 index 0b106cd0e7c58d9b59b82a9b8fcb1709b26ddf5e..18ae859aaa4f19fe691c183d70a0bd7d604c671e 100644 --- a/handler/generate_keypair.go +++ b/handler/generate_keypair.go @@ -32,7 +32,9 @@ import ( "golang.org/x/net/context" ) -func (s *KeyStorageServerImpl) GenerateKeyPair(ctx context.Context, in *api.GenerateKeyPairRequest) (*api.GenerateKeyPairResponse, error) { +func (s *KeyStorageServerImpl) GenerateKeyPair(ctx context.Context, + in *api.GenerateKeyPairRequest) (*api.GenerateKeyPairResponse, error) { + auth := s.CreateAuthentication(ctx) client := &client.DataStorageClientImpl{} @@ -66,35 +68,47 @@ func (s *KeyStorageServerImpl) GenerateKeyPair(ctx context.Context, in *api.Gene return generateKeyPairResponse, nil } encryptedPrivateKey := &api.Key{Content: encryptedPrivateKeyBytes} - result, errors, err := client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE), encryptedPrivateKey, versions.EntitiesManagementAgentApiVersion) + result, errors, err := client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE), + encryptedPrivateKey, versions.EntitiesManagementAgentApiVersion) generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err) - publicKeyNonce := []byte{} if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 { - encryptedPublicKeyBytes, publicKeyNonceLocal, err := aesEncrypt(aesKeyBytes, publicKeyBytes) - publicKeyNonce = publicKeyNonceLocal + publicKey := &api.Key{Content: publicKeyBytes} + 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 { + 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 } - encryptedPublicKey := &api.Key{Content: encryptedPublicKeyBytes} - result, errors, err = client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PUBLIC), encryptedPublicKey, versions.EntitiesManagementAgentApiVersion) + + encryptedAesKey := &api.Key{Content: encryptedAesKeyBytes} + + result, errors, err = client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_PRIVATE), encryptedAesKey, versions.EntitiesManagementAgentApiVersion) generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err) } - 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 + if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 { + encryptedPrivateKeyNonceBytes, err := rsaEncryptWithServerKey(s.VereignCertFilePath, privateKeyNonce, []byte("nonce")) + if err != nil { + generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList, + "500", api.StatusType_ERROR, err.Error()) + return generateKeyPairResponse, nil + } + + encryptedNonce := &api.Key{Content: encryptedPrivateKeyNonceBytes} + + result, errors, err = client.DoPutDataCall("keys", uuid+"/"+api.KeyType.String(api.KeyType_NONCE), encryptedNonce, versions.EntitiesManagementAgentApiVersion) + generateKeyPairResponse.StatusList = handlePutDataErrors(generateKeyPairResponse.StatusList, errors, err) } if generateKeyPairResponse.StatusList == nil || len(generateKeyPairResponse.StatusList) == 0 { generateKeyPairResponse.Uuid = uuid - generateKeyPairResponse.EncryptedAesKey = encryptedAesKeyBytes - generateKeyPairResponse.PrivateKeyNonce = privateKeyNonce - generateKeyPairResponse.PublicKeyNonce = publicKeyNonce generateKeyPairResponse.StatusList = utils.AddStatus(generateKeyPairResponse.StatusList, "200", api.StatusType_INFO, result) } diff --git a/handler/revoke.go b/handler/revoke.go index 2b779ed3372b1ef99fa2ba7d12823a8596386d84..8f757b298b6d750587f54e312a3bb8388e8038a7 100644 --- a/handler/revoke.go +++ b/handler/revoke.go @@ -22,7 +22,6 @@ import ( "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" ) @@ -56,17 +55,11 @@ func (s *KeyStorageServerImpl) Revoke(ctx context.Context, in *api.RevokeRequest 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) + key, statusList := getKey(client, uuid, keyType) + if statusList != nil { 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) diff --git a/handler/utils.go b/handler/utils.go index a489edca30ce359b8bf3431d6faced0b2797c520..7a2b0d1ff6d8cc7c2ec1155c7bf7a4e13bc565d8 100644 --- a/handler/utils.go +++ b/handler/utils.go @@ -27,6 +27,7 @@ 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" + "github.com/golang/protobuf/proto" ) func generateUnusedUUID(client *client.DataStorageClientImpl) (string, error) { @@ -83,3 +84,18 @@ func readCertificateFromFile(fileName string) (*x509.Certificate, error) { return certificate, nil } + +func getKey(client *client.DataStorageClientImpl, uuid string, keyType api.KeyType) (*api.Key, []*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 nil, statusList + } + + key := &api.Key{} + proto.Unmarshal(data.Data.Data, key) + + return key, nil +} diff --git a/server/server_test.go b/server/server_test.go index aded86e9ddb5eecf3eda86d5b808103e96c093fc..33f1aa4d0e21242e0f5dc38e3b171c25c5b12147 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -155,7 +155,7 @@ func TestGenerateKeyPairAndCertificate(t *testing.T) { keyStorageClient.SetUpClient(keyStorageAuth, keyStorageGrpcAddress, certFilePath) defer keyStorageClient.CloseClient() - uuid, encryptedAesKey, privateKeyNonce, publicKeyNonce, statusList, _ := keyStorageClient.DoGenerateKeyPair(2048) + 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) @@ -214,7 +214,7 @@ func TestGenerateKeyPairAndCertificate(t *testing.T) { Host: "abcde.com", } - statusList, _ = keyStorageClient.DoGenerateCertificate(uuid, certificateData, encryptedAesKey, privateKeyNonce, publicKeyNonce) + statusList, _ = keyStorageClient.DoGenerateCertificate(uuid, certificateData) for _, status := range statusList { if status.StatusType == ksapi.StatusType_ERROR { t.Errorf("DoGenerateCertificate, returned error: %s.", status.Code+":"+status.Description)