Finalised ECDSA for Deployment Keys

pull/2972/head
ssbkang 2019-06-30 21:10:47 +12:00
parent adf8846c28
commit 7dd9e9e365
5 changed files with 40 additions and 5 deletions

View File

@ -7,6 +7,8 @@ import (
"crypto/x509" "crypto/x509"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"encoding/pem"
"golang.org/x/crypto/ssh"
"math/big" "math/big"
) )
@ -135,3 +137,28 @@ func (service *ECDSAService) CreateSignature(message string) (string, error) {
return base64.RawStdEncoding.EncodeToString(signature), nil return base64.RawStdEncoding.EncodeToString(signature), nil
} }
// GenerateDeploymentKeyPair will create a new PEM encoded key pairs with ECDSA.
func (service *ECDSAService) GenerateDeploymentKeyPair() ([]byte, string, error) {
pubkeyCurve := elliptic.P256()
privateKey, err := ecdsa.GenerateKey(pubkeyCurve, rand.Reader)
if err != nil {
return nil, "", err
}
x509EncodedBytes, _ := x509.MarshalECPrivateKey(privateKey)
if err != nil {
return nil, "", err
}
pemEncodedPrivate := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: x509EncodedBytes})
publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey)
if err != nil {
return nil, "", err
}
publicKeyAutorizedKey := ssh.MarshalAuthorizedKey(publicKey)
return pemEncodedPrivate, string(publicKeyAutorizedKey), nil
}

View File

@ -38,10 +38,15 @@ func (handler *Handler) deploymentkeyCreate(w http.ResponseWriter, r *http.Reque
// Add a function to call and create public key and private key // Add a function to call and create public key and private key
private, public, err := handler.SignatureService.GenerateDeploymentKeyPair()
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to create private and public key pairs", err}
}
deploymentkey = &portainer.DeploymentKey{ deploymentkey = &portainer.DeploymentKey{
Name: payload.Name, Name: payload.Name,
PublicKey: "SHA256:hellotherepublic", PublicKey: public,
PrivateKey: "SHA256:hellothereprivate", PrivateKey: private,
} }
err = handler.DeploymentKeyService.CreateDeploymentKey(deploymentkey) err = handler.DeploymentKeyService.CreateDeploymentKey(deploymentkey)
@ -49,7 +54,7 @@ func (handler *Handler) deploymentkeyCreate(w http.ResponseWriter, r *http.Reque
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the deployment key inside the database", err} return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the deployment key inside the database", err}
} }
hideFields(deploymentkey) // hideFields(deploymentkey)
return response.JSON(w, deploymentkey) return response.JSON(w, deploymentkey)
} }

View File

@ -13,10 +13,11 @@ import (
type Handler struct { type Handler struct {
*mux.Router *mux.Router
DeploymentKeyService portainer.DeploymentKeyService DeploymentKeyService portainer.DeploymentKeyService
SignatureService portainer.DigitalSignatureService
} }
func hideFields(deploymentkey *portainer.DeploymentKey) { func hideFields(deploymentkey *portainer.DeploymentKey) {
deploymentkey.PrivateKey = "" deploymentkey.PrivateKey = nil
} }
// NewHandler creates a handler to manage settings operations. // NewHandler creates a handler to manage settings operations.

View File

@ -226,6 +226,7 @@ func (server *Server) Start() error {
var deploymentKeyHandler = deploymentkeys.NewHandler(requestBouncer) var deploymentKeyHandler = deploymentkeys.NewHandler(requestBouncer)
deploymentKeyHandler.DeploymentKeyService = server.DeploymentKeyService deploymentKeyHandler.DeploymentKeyService = server.DeploymentKeyService
deploymentKeyHandler.SignatureService = server.SignatureService
server.Handler = &handler.Handler{ server.Handler = &handler.Handler{
RoleHandler: roleHandler, RoleHandler: roleHandler,

View File

@ -225,7 +225,7 @@ type (
ID DeploymentKeyID `json:"Id` ID DeploymentKeyID `json:"Id`
Name string `json:"Name"` Name string `json:"Name"`
PublicKey string `json:"PublicKey"` PublicKey string `json:"PublicKey"`
PrivateKey string `json:"PrivateKey"` PrivateKey []byte `json:"PrivateKey"`
} }
// DockerHub represents all the required information to connect and use the // DockerHub represents all the required information to connect and use the
@ -778,6 +778,7 @@ type (
DigitalSignatureService interface { DigitalSignatureService interface {
ParseKeyPair(private, public []byte) error ParseKeyPair(private, public []byte) error
GenerateKeyPair() ([]byte, []byte, error) GenerateKeyPair() ([]byte, []byte, error)
GenerateDeploymentKeyPair() ([]byte, string, error)
EncodedPublicKey() string EncodedPublicKey() string
PEMHeaders() (string, string) PEMHeaders() (string, string)
CreateSignature(message string) (string, error) CreateSignature(message string) (string, error)