From 2158674d17133b712efd1a70c2bdfde688bb1691 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Tue, 27 Feb 2018 02:48:33 +0100 Subject: [PATCH] Implement -test to check certificates expiration --- dnscrypt-proxy/config.go | 5 +++++ dnscrypt-proxy/dnscrypt_certs.go | 6 ++++++ dnscrypt-proxy/proxy.go | 10 ++++++++++ dnscrypt-proxy/serversInfo.go | 6 ++++++ 4 files changed, 27 insertions(+) diff --git a/dnscrypt-proxy/config.go b/dnscrypt-proxy/config.go index c93dd72c..bcb0226d 100644 --- a/dnscrypt-proxy/config.go +++ b/dnscrypt-proxy/config.go @@ -136,6 +136,7 @@ func ConfigLoad(proxy *Proxy, svcFlag *string) error { listAll := flag.Bool("list-all", false, "print the complete list of available resolvers, ignoring filters") jsonOutput := flag.Bool("json", false, "output list as JSON") check := flag.Bool("check", false, "check the configuration file and exit") + testGracePeriod := flag.Int("test", 0, "test that certificates of chosen servers are not going to expire before that number of minutes") flag.Parse() if *svcFlag == "stop" || *svcFlag == "uninstall" { return nil @@ -268,6 +269,10 @@ func ConfigLoad(proxy *Proxy, svcFlag *string) error { } proxy.allWeeklyRanges = allWeeklyRanges + if testGracePeriod != nil && *testGracePeriod > 0 { + proxy.testGracePeriod = testGracePeriod + } + if *listAll { config.ServerNames = nil config.SourceRequireDNSSEC = false diff --git a/dnscrypt-proxy/dnscrypt_certs.go b/dnscrypt-proxy/dnscrypt_certs.go index 34109b3c..8434fa49 100644 --- a/dnscrypt-proxy/dnscrypt_certs.go +++ b/dnscrypt-proxy/dnscrypt_certs.go @@ -95,6 +95,12 @@ func FetchCurrentDNSCryptCert(proxy *Proxy, serverName *string, proto string, pk } else { certInfo.ForwardSecurity = true } + if proxy.testGracePeriod != nil { + if remaining := (tsEnd - now) / 60; uint32(*proxy.testGracePeriod) > remaining { + dlog.Fatalf("Certificate for [%v] is going to expire in %d minutes, before the grace period", + providerName, remaining) + } + } if !proxy.certIgnoreTimestamp { if now > tsEnd || now < tsBegin { dlog.Debugf("[%v] Certificate not valid at the current date", providerName) diff --git a/dnscrypt-proxy/proxy.go b/dnscrypt-proxy/proxy.go index 054f6ca6..7cc8cdf7 100644 --- a/dnscrypt-proxy/proxy.go +++ b/dnscrypt-proxy/proxy.go @@ -6,6 +6,7 @@ import ( "math/rand" "net" "net/http" + "os" "sync/atomic" "time" @@ -52,6 +53,7 @@ type Proxy struct { maxClients uint32 xTransport *XTransport allWeeklyRanges *map[string]WeeklyRanges + testGracePeriod *int } func (proxy *Proxy) StartProxy() { @@ -83,6 +85,14 @@ func (proxy *Proxy) StartProxy() { dlog.Fatal(err) } liveServers, err := proxy.serversInfo.refresh(proxy) + if proxy.testGracePeriod != nil { + if liveServers > 0 { + dlog.Noticef("%d certificates successfully checked", liveServers) + os.Exit(0) + } else { + dlog.Fatal("Unable to check servers certificates") + } + } if liveServers > 0 { dlog.Noticef("dnscrypt-proxy is ready - live servers: %d", liveServers) SystemDNotify() diff --git a/dnscrypt-proxy/serversInfo.go b/dnscrypt-proxy/serversInfo.go index 3cf68720..02e1ed66 100644 --- a/dnscrypt-proxy/serversInfo.go +++ b/dnscrypt-proxy/serversInfo.go @@ -286,6 +286,7 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st showCerts := len(os.Getenv("SHOW_CERTS")) > 0 found := false var wantedHash [32]byte + now := time.Now() for _, cert := range tls.PeerCertificates { h := sha256.Sum256(cert.RawTBSCertificate) if showCerts { @@ -293,6 +294,11 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st } else { dlog.Debugf("Advertised cert: [%s] [%x]", cert.Subject, h) } + if proxy.testGracePeriod != nil { + if remaining := int(cert.NotAfter.Sub(now).Minutes()); *proxy.testGracePeriod > remaining { + dlog.Fatalf("Certificate [%s] for [%s] is going to expire before the grace period, in %d minutes", cert.Subject, name, remaining) + } + } for _, hash := range stamp.hashes { if len(hash) == len(wantedHash) { copy(wantedHash[:], hash)