mirror of https://github.com/portainer/portainer
Finalised ECDSA for Deployment Keys
parent
adf8846c28
commit
7dd9e9e365
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue