Browse Source

send csr and get cert

Matthew R. Kasun 3 years ago
parent
commit
5008462b3e
4 changed files with 63 additions and 8 deletions
  1. 29 4
      controllers/server.go
  2. 2 1
      netclient/config/config.go
  3. 29 3
      netclient/functions/register.go
  4. 3 0
      tls/tls.go

+ 29 - 4
controllers/server.go

@@ -111,7 +111,6 @@ func getConfig(w http.ResponseWriter, r *http.Request) {
 func register(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "application/json")
 	bearerToken := r.Header.Get("Authorization")
-
 	var tokenSplit = strings.Split(bearerToken, " ")
 	var token = ""
 	if len(tokenSplit) < 2 {
@@ -123,7 +122,15 @@ func register(w http.ResponseWriter, r *http.Request) {
 	} else {
 		token = tokenSplit[1]
 	}
-
+	//decode body
+	var request config.RegisterRequest
+	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
+		logger.Log(3, "error decoding request")
+		errorResponse := models.ErrorResponse{
+			Code: http.StatusBadRequest, Message: "invalid request",
+		}
+		returnErrorResponse(w, r, errorResponse)
+	}
 	found := false
 	networks, err := logic.GetNetworks()
 	if err != nil {
@@ -157,10 +164,28 @@ func register(w http.ResponseWriter, r *http.Request) {
 		}
 		returnErrorResponse(w, r, errorResponse)
 		return
-		//return err
+	}
+	key, err := tls.ReadKey("etc/netmaker/root.key")
+	if err != nil {
+		logger.Log(2, "root ca not found")
+		errorResponse := models.ErrorResponse{
+			Code: http.StatusNotFound, Message: "root ca not found",
+		}
+		returnErrorResponse(w, r, errorResponse)
+		return
+	}
+	cert, err := tls.NewEndEntityCert(*key, &request.CSR, ca, tls.CERTIFICATE_VALIDITY)
+	if err != nil {
+		logger.Log(2, "unable to generate client certificate")
+		errorResponse := models.ErrorResponse{
+			Code: http.StatusNotFound, Message: err.Error(),
+		}
+		returnErrorResponse(w, r, errorResponse)
+		return
 	}
 	response := config.RegisterResponse{
-		CA: *ca,
+		CA:   *ca,
+		Cert: *cert,
 	}
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(response)

+ 2 - 1
netclient/config/config.go

@@ -45,7 +45,8 @@ type RegisterRequest struct {
 }
 
 type RegisterResponse struct {
-	CA x509.Certificate
+	CA   x509.Certificate
+	Cert x509.Certificate
 }
 
 // Write - writes the config of a client to disk

+ 29 - 3
netclient/functions/register.go

@@ -1,10 +1,14 @@
 package functions
 
 import (
+	"bytes"
+	"crypto/ed25519"
+	"crypto/rand"
 	"encoding/json"
 	"errors"
 	"log"
 	"net/http"
+	"os"
 
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/netclient/config"
@@ -19,12 +23,28 @@ func Register(cfg *config.ClientConfig) error {
 	if cfg.Server.AccessKey == "" {
 		return errors.New("no access key provided")
 	}
+	//create certificate request
+	_, key, err := ed25519.GenerateKey(rand.Reader)
+	if err != nil {
+		return err
+	}
+	name := tls.NewCName(os.Getenv("HOSTNAME"))
+	csr, err := tls.NewCSR(key, name)
+	if err != nil {
+		return err
+	}
+	data := config.RegisterRequest{
+		CSR: *csr,
+	}
+	payload, err := json.Marshal(data)
 	url := cfg.Server.API + "/api/server/register"
-	log.Println("regsiter at ", url)
-	request, err := http.NewRequest(http.MethodPost, url, nil)
+	log.Println("registering at ", url)
+
+	request, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(payload))
 	if err != nil {
 		return err
 	}
+	request.Header.Set("Content-Type", "application/json")
 	request.Header.Set("authorization", "Bearer "+cfg.Server.AccessKey)
 	client := http.Client{}
 	response, err := client.Do(request)
@@ -41,6 +61,12 @@ func Register(cfg *config.ClientConfig) error {
 	if err := tls.SaveCert(ncutils.GetNetclientPath()+cfg.Server.Server, "root.cert", &resp.CA); err != nil {
 		return err
 	}
-	logger.Log(0, "server certificate saved ")
+	if err := tls.SaveCert(ncutils.GetNetclientPath(), "client.cert", &resp.Cert); err != nil {
+		return err
+	}
+	if err := tls.SaveKey(ncutils.GetNetclientPath(), "client.key", key); err != nil {
+		return err
+	}
+	logger.Log(0, "certificates/key saved ")
 	return nil
 }

+ 3 - 0
tls/tls.go

@@ -18,6 +18,9 @@ import (
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
+// certificate validity in days
+const CERTIFICATE_VALIDITY = 365
+
 type (
 	Key struct {
 		point *edwards25519.Point