Skip to content

Commit

Permalink
Prevent race conditions for the certificate list
Browse files Browse the repository at this point in the history
  • Loading branch information
imdawon committed Jun 30, 2024
1 parent 1db1d89 commit 3865539
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 17 deletions.
20 changes: 11 additions & 9 deletions cmd/drawbridge/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,17 @@ func (d *Drawbridge) handleClientAuthorizationRequest(w http.ResponseWriter, req
// as well as provisioning mTLS certificates for them.
// Proxying requests for TCP and UDP traffic is handled by the reverse proxy.
func (d *Drawbridge) SetUpEmissaryAPI(hostAndPort string) {
r := http.NewServeMux()
r.HandleFunc("/emissary/v1/auth", d.handleClientAuthorizationRequest)
server := http.Server{
TLSConfig: d.CA.ServerTLSConfig,
Addr: hostAndPort,
Handler: r,
}
slog.Info(fmt.Sprintf("Starting Emissary API server on http://%s", server.Addr))
// r := http.NewServeMux()
// r.HandleFunc("/emissary/v1/auth", d.handleClientAuthorizationRequest)
// server := http.Server{
// TLSConfig: d.CA.ServerTLSConfig,
// Addr: hostAndPort,
// Handler: r,
// }
// slog.Info(fmt.Sprintf("Starting Emissary API server on http://%s", server.Addr))

// We pass "" into listen and serve since we have already configured cert and keyfile for server.
slog.Error("Error starting Emissary API server: %s", server.ListenAndServeTLS("", ""))
// slog.Error("Error starting Emissary API server: %s", server.ListenAndServeTLS("", ""))
}

func (d *Drawbridge) SetUpCAAndDependentServices(protectedServices []services.ProtectedService) {
Expand Down Expand Up @@ -260,7 +260,9 @@ func (d *Drawbridge) StopRunningProtectedService(id int64) {
// VerifyPeerCertificateWithRevocationCheck is a custom VerifyPeerCertificate callback
// that checks if the peer's certificate is in the revoked certificates list
func (d *Drawbridge) VerifyPeerCertificateWithRevocationCheck(cert string) error {
d.CA.CertificateListMutex.RLock()
deviceUUID := d.CA.CertificateList[cert]
d.CA.CertificateListMutex.RUnlock()
if deviceUUID.Revoked == 1 {
return errors.New("certificate is revoked")
}
Expand Down
15 changes: 7 additions & 8 deletions cmd/reverse_proxy/ca/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ type CA struct {
CertificateAuthority *x509.Certificate
PrivateKey crypto.PrivateKey
DB *persistence.SQLiteRepository
// sha256 key of certificate -> device uuid and revoked
CertificateList map[string]emissary.DeviceCertificate
// sha256 key of certificate -> device uuid and revoked value (0 for false| 1 for true)
CertificateList map[string]emissary.DeviceCertificate
CertificateListMutex sync.RWMutex
}

var CertificateAuthority *CA
Expand Down Expand Up @@ -325,25 +326,23 @@ func (c *CA) verifyEmissaryCertificate(rawCerts [][]byte, verifiedChains [][]*x5
return nil
}

var revokedCertsMutex sync.RWMutex

// RevokeCertInCertificateRevocationList adds a certificate to the revoked certificates list
func (c *CA) RevokeCertInCertificateRevocationList(shaCert string) {
revokedCertsMutex.Lock()
defer revokedCertsMutex.Unlock()
c.CertificateListMutex.Lock()
cert, ok := c.CertificateList[shaCert]
if !ok {
slog.Error("Unable to revoke certificate as it doesn't exist in the certificate list", shaCert)
}
c.CertificateListMutex.Unlock()
certCopy := cert
certCopy.Revoked = 1
c.CertificateList[shaCert] = certCopy
}

// RevokeCertInCertificateRevocationList adds a certificate to the revoked certificates list
func (c *CA) UnRevokeCertInCertificateRevocationList(shaCert string) {
revokedCertsMutex.Lock()
defer revokedCertsMutex.Unlock()
c.CertificateListMutex.Lock()
defer c.CertificateListMutex.Unlock()
cert, ok := c.CertificateList[shaCert]
if !ok {
slog.Error("Unable to unrevoke certificate as it doesn't exist in the certificate list", shaCert)
Expand Down

0 comments on commit 3865539

Please sign in to comment.