]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Fix a race in TLS certificate generation in the tests 13253/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 13 Sep 2023 14:27:51 +0000 (16:27 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 13 Sep 2023 14:27:51 +0000 (16:27 +0200)
The OCSP and TLS tests are generating new TLS certificate and key,
so there was a time window for a certificate/key mismatch if a test
is starting right at the moment the OCSP and TLS tests are generating
new material. This commit fixes it by using different file names for
these tests.

regression-tests.dnsdist/.gitignore
regression-tests.dnsdist/dnsdisttests.py
regression-tests.dnsdist/test_OCSP.py
regression-tests.dnsdist/test_TLS.py

index bde839b044138d2059989a17f96e35c02d53eb14..78d7bc1ccb7aec879ea7e992c5862f6a17369881 100644 (file)
 /server.csr
 /server.key
 /server.pem
-/server.ocsp
 /server.p12
+/server-ocsp.chain
+/server-ocsp.csr
+/server-ocsp.key
+/server-ocsp.pem
+/server-ocsp.p12
+/server-tls.chain
+/server-tls.csr
+/server-tls.key
+/server-tls.pem
+/server-tls.p12
+/server.ocsp
 /configs
 /dnsdist.log
 /dnsdist_test.conf
index c82f2b9ac9ddd08563762c21a92c0cdd720ae197..75f12e6202211f9141dd145b5b83c0757a779533 100644 (file)
@@ -905,16 +905,17 @@ class DNSDistTest(AssertEqualDNSMessageMixin, unittest.TestCase):
     def checkResponseNoEDNS(self, expected, received):
         self.checkMessageNoEDNS(expected, received)
 
-    def generateNewCertificateAndKey(self):
+    @staticmethod
+    def generateNewCertificateAndKey(filePrefix):
         # generate and sign a new cert
-        cmd = ['openssl', 'req', '-new', '-newkey', 'rsa:2048', '-nodes', '-keyout', 'server.key', '-out', 'server.csr', '-config', 'configServer.conf']
+        cmd = ['openssl', 'req', '-new', '-newkey', 'rsa:2048', '-nodes', '-keyout', filePrefix + '.key', '-out', filePrefix + '.csr', '-config', 'configServer.conf']
         output = None
         try:
             process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
             output = process.communicate(input='')
         except subprocess.CalledProcessError as exc:
             raise AssertionError('openssl req failed (%d): %s' % (exc.returncode, exc.output))
-        cmd = ['openssl', 'x509', '-req', '-days', '1', '-CA', 'ca.pem', '-CAkey', 'ca.key', '-CAcreateserial', '-in', 'server.csr', '-out', 'server.pem', '-extfile', 'configServer.conf', '-extensions', 'v3_req']
+        cmd = ['openssl', 'x509', '-req', '-days', '1', '-CA', 'ca.pem', '-CAkey', 'ca.key', '-CAcreateserial', '-in', filePrefix + '.csr', '-out', filePrefix + '.pem', '-extfile', 'configServer.conf', '-extensions', 'v3_req']
         output = None
         try:
             process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
@@ -922,12 +923,12 @@ class DNSDistTest(AssertEqualDNSMessageMixin, unittest.TestCase):
         except subprocess.CalledProcessError as exc:
             raise AssertionError('openssl x509 failed (%d): %s' % (exc.returncode, exc.output))
 
-        with open('server.chain', 'w') as outFile:
-            for inFileName in ['server.pem', 'ca.pem']:
+        with open(filePrefix + '.chain', 'w') as outFile:
+            for inFileName in [filePrefix + '.pem', 'ca.pem']:
                 with open(inFileName) as inFile:
                     outFile.write(inFile.read())
 
-        cmd = ['openssl', 'pkcs12', '-export', '-passout', 'pass:passw0rd', '-clcerts', '-in', 'server.pem', '-CAfile', 'ca.pem', '-inkey', 'server.key', '-out', 'server.p12']
+        cmd = ['openssl', 'pkcs12', '-export', '-passout', 'pass:passw0rd', '-clcerts', '-in', filePrefix + '.pem', '-CAfile', 'ca.pem', '-inkey', filePrefix + '.key', '-out', filePrefix + '.p12']
         output = None
         try:
             process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
index de520dcdaf502e66c2ecc0327177e9f4b3ef2019..695863151c2ff33cbea938dc7ba61fe97d0aab83 100644 (file)
@@ -35,13 +35,20 @@ class DNSDistOCSPStaplingTest(DNSDistTest):
     def getTLSProvider(self):
         return self.sendConsoleCommand("getBind(0):getEffectiveTLSProvider()").rstrip()
 
+    @classmethod
+    def setUpClass(cls):
+        cls.generateNewCertificateAndKey('server-ocsp')
+        cls.startResponders()
+        cls.startDNSDist()
+        cls.setUpSockets()
+
 @unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled')
 class TestOCSPStaplingDOH(DNSDistOCSPStaplingTest):
 
     _consoleKey = DNSDistTest.generateConsoleKey()
     _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
+    _serverKey = 'server-ocsp.key'
+    _serverCert = 'server-ocsp.chain'
     _serverName = 'tls.tests.dnsdist.org'
     _ocspFile = 'server.ocsp'
     _caCert = 'ca.pem'
@@ -67,6 +74,7 @@ class TestOCSPStaplingDOH(DNSDistOCSPStaplingTest):
         if 'SKIP_DOH_TESTS' in os.environ:
             raise unittest.SkipTest('DNS over HTTPS tests are disabled')
 
+        cls.generateNewCertificateAndKey('server-ocsp')
         cls.startResponders()
         cls.startDNSDist()
         cls.setUpSockets()
@@ -84,7 +92,7 @@ class TestOCSPStaplingDOH(DNSDistOCSPStaplingTest):
             serialNumber = self.getOCSPSerial(output)
             self.assertTrue(serialNumber)
 
-            self.generateNewCertificateAndKey()
+            self.generateNewCertificateAndKey('server-ocsp')
             self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile))
             self.sendConsoleCommand("reloadAllCertificates()")
 
@@ -98,8 +106,8 @@ class TestBrokenOCSPStaplingDoH(DNSDistOCSPStaplingTest):
 
     _consoleKey = DNSDistTest.generateConsoleKey()
     _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
+    _serverKey = 'server-ocsp.key'
+    _serverCert = 'server-ocsp.chain'
     _serverName = 'tls.tests.dnsdist.org'
     _caCert = 'ca.pem'
     # invalid OCSP file!
@@ -129,8 +137,8 @@ class TestOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest):
 
     _consoleKey = DNSDistTest.generateConsoleKey()
     _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
+    _serverKey = 'server-ocsp.key'
+    _serverCert = 'server-ocsp.chain'
     _serverName = 'tls.tests.dnsdist.org'
     _ocspFile = 'server.ocsp'
     _caCert = 'ca.pem'
@@ -158,7 +166,7 @@ class TestOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest):
         serialNumber = self.getOCSPSerial(output)
         self.assertTrue(serialNumber)
 
-        self.generateNewCertificateAndKey()
+        self.generateNewCertificateAndKey('server-ocsp')
         self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile))
         self.sendConsoleCommand("reloadAllCertificates()")
 
@@ -172,8 +180,8 @@ class TestBrokenOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest):
 
     _consoleKey = DNSDistTest.generateConsoleKey()
     _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
+    _serverKey = 'server-ocsp.key'
+    _serverCert = 'server-ocsp.chain'
     _serverName = 'tls.tests.dnsdist.org'
     _caCert = 'ca.pem'
     # invalid OCSP file!
@@ -200,8 +208,8 @@ class TestOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest):
 
     _consoleKey = DNSDistTest.generateConsoleKey()
     _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
+    _serverKey = 'server-ocsp.key'
+    _serverCert = 'server-ocsp.chain'
     _serverName = 'tls.tests.dnsdist.org'
     _ocspFile = 'server.ocsp'
     _caCert = 'ca.pem'
@@ -229,7 +237,7 @@ class TestOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest):
         serialNumber = self.getOCSPSerial(output)
         self.assertTrue(serialNumber)
 
-        self.generateNewCertificateAndKey()
+        self.generateNewCertificateAndKey('server-ocsp')
         self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile))
         self.sendConsoleCommand("reloadAllCertificates()")
 
@@ -243,8 +251,8 @@ class TestBrokenOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest):
 
     _consoleKey = DNSDistTest.generateConsoleKey()
     _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
+    _serverKey = 'server-ocsp.key'
+    _serverCert = 'server-ocsp.chain'
     _serverName = 'tls.tests.dnsdist.org'
     _caCert = 'ca.pem'
     # invalid OCSP file!
index 12db4639453d64afce1ecd90ec1ca13c1c6508c8..9803ed550f961300ecfb656ede0eddd6edaa9a65 100644 (file)
@@ -58,7 +58,7 @@ class TLSTests(object):
         self.assertEqual(names, ['tls.tests.dnsdist.org', 'powerdns.com', '127.0.0.1'])
         serialNumber = cert['serialNumber']
 
-        self.generateNewCertificateAndKey()
+        self.generateNewCertificateAndKey('server-tls')
         self.sendConsoleCommand("reloadAllCertificates()")
 
         conn.close()
@@ -268,8 +268,8 @@ class TestOpenSSL(DNSDistTest, TLSTests):
     _extraStartupSleep = 1
     _consoleKey = DNSDistTest.generateConsoleKey()
     _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
+    _serverKey = 'server-tls.key'
+    _serverCert = 'server-tls.chain'
     _serverName = 'tls.tests.dnsdist.org'
     _caCert = 'ca.pem'
     _tlsServerPort = pickAvailablePort()
@@ -283,6 +283,13 @@ class TestOpenSSL(DNSDistTest, TLSTests):
     """
     _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey']
 
+    @classmethod
+    def setUpClass(cls):
+        cls.generateNewCertificateAndKey('server-tls')
+        cls.startResponders()
+        cls.startDNSDist()
+        cls.setUpSockets()
+
     def testProvider(self):
         self.assertEqual(self.getTLSProvider(), "openssl")
 
@@ -290,8 +297,8 @@ class TestGnuTLS(DNSDistTest, TLSTests):
 
     _consoleKey = DNSDistTest.generateConsoleKey()
     _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
-    _serverKey = 'server.key'
-    _serverCert = 'server.chain'
+    _serverKey = 'server-tls.key'
+    _serverCert = 'server-tls.chain'
     _serverName = 'tls.tests.dnsdist.org'
     _caCert = 'ca.pem'
     _tlsServerPort = pickAvailablePort()
@@ -305,6 +312,13 @@ class TestGnuTLS(DNSDistTest, TLSTests):
     """
     _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey']
 
+    @classmethod
+    def setUpClass(cls):
+        cls.generateNewCertificateAndKey('server-tls')
+        cls.startResponders()
+        cls.startDNSDist()
+        cls.setUpSockets()
+
     def testProvider(self):
         self.assertEqual(self.getTLSProvider(), "gnutls")
 
@@ -481,7 +495,7 @@ class TestProtocols(DNSDistTest):
 class TestPKCSTLSCertificate(DNSDistTest, TLSTests):
     _consoleKey = DNSDistTest.generateConsoleKey()
     _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
-    _serverCert = 'server.p12'
+    _serverCert = 'server-tls.p12'
     _pkcsPassphrase = 'passw0rd'
     _serverName = 'tls.tests.dnsdist.org'
     _caCert = 'ca.pem'
@@ -495,3 +509,10 @@ class TestPKCSTLSCertificate(DNSDistTest, TLSTests):
     addAction(SNIRule("powerdns.com"), SpoofAction("1.2.3.4"))
     """
     _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_serverCert', '_pkcsPassphrase', '_tlsServerPort']
+
+    @classmethod
+    def setUpClass(cls):
+        cls.generateNewCertificateAndKey('server-tls')
+        cls.startResponders()
+        cls.startDNSDist()
+        cls.setUpSockets()