[lxc-devel] [lxd/master] lxd/certificates: Make certificate add more robust

stgraber on Github lxc-bot at linuxcontainers.org
Mon Apr 29 17:49:11 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 370 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190429/7b21b34e/attachment.bin>
-------------- next part --------------
From 9e9dbcbed9f31d8b56ed2fa76a929c8cd76a1de7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 29 Apr 2019 13:48:09 -0400
Subject: [PATCH] lxd/certificates: Make certificate add more robust
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #5707

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/certificates.go | 48 ++++++++++++++++++++++-----------------------
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/lxd/certificates.go b/lxd/certificates.go
index 1e205a9be5..187619f7a8 100644
--- a/lxd/certificates.go
+++ b/lxd/certificates.go
@@ -100,18 +100,6 @@ func readSavedClientCAList(d *Daemon) {
 	}
 }
 
-func saveCert(dbObj *db.Cluster, host string, cert *x509.Certificate) error {
-	baseCert := new(db.CertInfo)
-	baseCert.Fingerprint = shared.CertFingerprint(cert)
-	baseCert.Type = 1
-	baseCert.Name = host
-	baseCert.Certificate = string(
-		pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}),
-	)
-
-	return dbObj.CertSave(baseCert)
-}
-
 func certificatesPost(d *Daemon, r *http.Request) Response {
 	// Parse the request
 	req := api.CertificatesPost{}
@@ -173,19 +161,33 @@ func certificatesPost(d *Daemon, r *http.Request) Response {
 
 	fingerprint := shared.CertFingerprint(cert)
 
+	if d.clientCerts == nil {
+		d.clientCerts = map[string]x509.Certificate{}
+	}
+
 	if !isClusterNotification(r) {
-		// Store the certificate in the cluster database.
-		existingCerts, err := d.cluster.CertificatesGet()
-		if err != nil {
-			return SmartError(err)
-		}
-		for _, existingCert := range existingCerts {
-			if fingerprint == existingCert.Fingerprint {
-				return BadRequest(fmt.Errorf("Certificate already in trust store"))
+		// Check if we already have the certificate
+		existingCert, err := d.cluster.CertificateGet(fingerprint)
+		if existingCert != nil {
+			// Deal with the cache being potentially out of sync
+			_, ok := d.clientCerts[fingerprint]
+			if !ok {
+				d.clientCerts[fingerprint] = *cert
+				return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/certificates/%s", version.APIVersion, fingerprint))
 			}
+
+			return BadRequest(fmt.Errorf("Certificate already in trust store"))
+		}
+
+		// Store the certificate in the cluster database
+		dbCert := db.CertInfo{
+			Fingerprint: shared.CertFingerprint(cert),
+			Type:        1,
+			Name:        name,
+			Certificate: string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})),
 		}
 
-		err = saveCert(d.cluster, name, cert)
+		err = d.cluster.CertSave(&dbCert)
 		if err != nil {
 			return SmartError(err)
 		}
@@ -210,10 +212,6 @@ func certificatesPost(d *Daemon, r *http.Request) Response {
 		}
 	}
 
-	if d.clientCerts == nil {
-		d.clientCerts = map[string]x509.Certificate{}
-	}
-
 	d.clientCerts[shared.CertFingerprint(cert)] = *cert
 
 	return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/certificates/%s", version.APIVersion, fingerprint))


More information about the lxc-devel mailing list