Skip to content

Commit

Permalink
Decrypt passwords and private keys of Honeybee's connection info
Browse files Browse the repository at this point in the history
  • Loading branch information
ish-hcc committed Jul 4, 2024
1 parent 3d342ca commit 4c1c2c2
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 4 deletions.
14 changes: 14 additions & 0 deletions cmd/cm-grasshopper/main.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package main

import (
"errors"
"github.com/cloud-barista/cm-grasshopper/common"
"github.com/cloud-barista/cm-grasshopper/db"
"github.com/cloud-barista/cm-grasshopper/lib/config"
"github.com/cloud-barista/cm-grasshopper/lib/rsautil"
"github.com/cloud-barista/cm-grasshopper/pkg/api/rest/controller"
"github.com/cloud-barista/cm-grasshopper/pkg/api/rest/server"
"github.com/jollaman999/utils/fileutil"
"github.com/jollaman999/utils/logger"
"log"
"os"
Expand Down Expand Up @@ -43,6 +46,17 @@ func init() {
logger.Panicln(logger.ERROR, true, err.Error())
}

controller.OkMessage.Message = "Honeybee's RSA private key is not ready"
privateKeyPath := common.RootPath + "/" + common.HoneybeePrivateKeyFileName
if !fileutil.IsExist(privateKeyPath) {
logger.Panicln(logger.ERROR, true, errors.New("Honeybee's private key not found ("+privateKeyPath+")"))
}

common.HoneybeePrivateKey, err = rsautil.ReadPrivateKey(privateKeyPath)
if err != nil {
logger.Panicln(logger.ERROR, true, "error occurred while reading Honeybee's private key")
}

controller.OkMessage.Message = "CM-Grasshopper API server is ready"
controller.IsReady = true

Expand Down
7 changes: 7 additions & 0 deletions common/rsa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package common

import "crypto/rsa"

var HoneybeePrivateKeyFileName = "honeybee.key"

var HoneybeePrivateKey *rsa.PrivateKey
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/glebarez/sqlite v1.11.0
github.com/jollaman999/utils v1.0.10
github.com/labstack/echo/v4 v4.12.0
github.com/labstack/gommon v0.4.2
github.com/melbahja/goph v1.4.0
github.com/swaggo/echo-swagger v1.4.1
github.com/swaggo/swag v1.16.3
Expand All @@ -30,7 +31,6 @@ require (
github.com/jinzhu/now v1.1.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
Expand Down
20 changes: 20 additions & 0 deletions lib/rsautil/readKeyFile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package rsautil

import (
"crypto/rsa"
"os"
)

func ReadPrivateKey(privateKeyFilePath string) (*rsa.PrivateKey, error) {
bytes, err := os.ReadFile(privateKeyFilePath)
if err != nil {
return nil, err
}

privKey, err := BytesToPrivateKey(bytes)
if err != nil {
return nil, err
}

return privKey, nil
}
33 changes: 33 additions & 0 deletions lib/rsautil/rsaUtil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package rsautil

import (
"crypto/rand"
"crypto/rsa"
"crypto/sha512"
"crypto/x509"
"encoding/pem"
"github.com/labstack/gommon/log"
)

// BytesToPrivateKey bytes to private key
func BytesToPrivateKey(priv []byte) (*rsa.PrivateKey, error) {
block, _ := pem.Decode(priv)
b := block.Bytes
var err error
key, err := x509.ParsePKCS1PrivateKey(b)
if err != nil {
return nil, err
}

return key, nil
}

// DecryptWithPrivateKey decrypts data with private key
func DecryptWithPrivateKey(ciphertext []byte, priv *rsa.PrivateKey) []byte {
hash := sha512.New()
plaintext, err := rsa.DecryptOAEP(hash, rand.Reader, priv, ciphertext, nil)
if err != nil {
log.Error(err)
}
return plaintext
}
39 changes: 36 additions & 3 deletions lib/ssh/client.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package ssh

import (
"encoding/base64"
"encoding/json"
"errors"
grasshopperCommon "github.com/cloud-barista/cm-grasshopper/common"
"github.com/cloud-barista/cm-grasshopper/lib/config"
"github.com/cloud-barista/cm-grasshopper/lib/rsautil"
"github.com/cloud-barista/cm-grasshopper/pkg/api/rest/common"
honeybee "github.com/cloud-barista/cm-honeybee/server/pkg/api/rest/model"
"github.com/jollaman999/utils/logger"
"github.com/melbahja/goph"
"golang.org/x/crypto/ssh"
"net"
Expand All @@ -32,6 +36,30 @@ func AddKnownHost(host string, remote net.Addr, key ssh.PublicKey) error {
return goph.AddKnownHost(host, remote, key, "")
}

func decryptPasswordAndPrivateKey(connectionInfo *honeybee.ConnectionInfo) (*honeybee.ConnectionInfo, error) {
encryptedPassword, err := base64.StdEncoding.DecodeString(connectionInfo.Password)
if err != nil {
errMsg := "error occurred while decrypting the base64 encoded encrypted password (" + err.Error() + ")"
logger.Println(logger.ERROR, true, errMsg)
return nil, errors.New(errMsg)
}

decryptedPasswordBytes := rsautil.DecryptWithPrivateKey(encryptedPassword, grasshopperCommon.HoneybeePrivateKey)
connectionInfo.Password = string(decryptedPasswordBytes)

encryptedPrivateKey, err := base64.StdEncoding.DecodeString(connectionInfo.PrivateKey)
if err != nil {
errMsg := "error occurred while decrypting the base64 encoded encrypted private key (" + err.Error() + ")"
logger.Println(logger.ERROR, true, errMsg)
return nil, errors.New(errMsg)
}

decryptedPrivateKeyBytes := rsautil.DecryptWithPrivateKey(encryptedPrivateKey, grasshopperCommon.HoneybeePrivateKey)
connectionInfo.PrivateKey = string(decryptedPrivateKeyBytes)

return connectionInfo, nil
}

func NewSSHClient(connectionInfoID string) (*Client, error) {
data, err := common.GetHTTPRequest("http://" + config.CMGrasshopperConfig.CMGrasshopper.Honeybee.ServerAddress +
":" + config.CMGrasshopperConfig.CMGrasshopper.Honeybee.ServerPort +
Expand All @@ -40,8 +68,13 @@ func NewSSHClient(connectionInfoID string) (*Client, error) {
return nil, err
}

var connectionInfo honeybee.ConnectionInfo
err = json.Unmarshal(data, &connectionInfo)
var encryptedConnectionInfo honeybee.ConnectionInfo
err = json.Unmarshal(data, &encryptedConnectionInfo)
if err != nil {
return nil, err
}

connectionInfo, err := decryptPasswordAndPrivateKey(&encryptedConnectionInfo)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -72,6 +105,6 @@ func NewSSHClient(connectionInfoID string) (*Client, error) {

return &Client{
client,
connectionInfo,
*connectionInfo,
}, nil
}

0 comments on commit 4c1c2c2

Please sign in to comment.