]> git.ipfire.org Git - thirdparty/pdns.git/blame - regression-tests.dnsdist/test_OCSP.py
dnsdist: Test both incoming DoH implementations in Async tests
[thirdparty/pdns.git] / regression-tests.dnsdist / test_OCSP.py
CommitLineData
8c15553e 1#!/usr/bin/env python
1d896c34 2import base64
8c15553e 3import dns
13291274 4import os
8c15553e 5import subprocess
13291274 6import unittest
630eb526 7from dnsdisttests import DNSDistTest, pickAvailablePort
8c15553e
RG
8
9class DNSDistOCSPStaplingTest(DNSDistTest):
10
11 @classmethod
12 def checkOCSPStaplingStatus(cls, addr, port, serverName, caFile):
13 testcmd = ['openssl', 's_client', '-CAfile', caFile, '-connect', '%s:%d' % (addr, port), '-status', '-servername', serverName ]
14 output = None
15 try:
16 process = subprocess.Popen(testcmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
17 output = process.communicate(input='')
18 except subprocess.CalledProcessError as exc:
1d896c34 19 raise AssertionError('openssl s_client failed (%d): %s' % (exc.returncode, exc.output))
8c15553e
RG
20
21 return output[0].decode()
22
1d896c34
RG
23 @classmethod
24 def getOCSPSerial(cls, output):
25 serialNumber = None
26 for line in output.splitlines():
27 line = line.strip()
28 print(line)
29 if line.startswith('Serial Number:'):
30 (_, serialNumber) = line.split(':')
31 break
32
33 return serialNumber
34
98222dfc
RG
35 def getTLSProvider(self):
36 return self.sendConsoleCommand("getBind(0):getEffectiveTLSProvider()").rstrip()
37
13291274 38@unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled')
8c15553e
RG
39class TestOCSPStaplingDOH(DNSDistOCSPStaplingTest):
40
1d896c34
RG
41 _consoleKey = DNSDistTest.generateConsoleKey()
42 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
8c15553e
RG
43 _serverKey = 'server.key'
44 _serverCert = 'server.chain'
45 _serverName = 'tls.tests.dnsdist.org'
46 _ocspFile = 'server.ocsp'
47 _caCert = 'ca.pem'
48 _caKey = 'ca.key'
630eb526 49 _dohServerPort = pickAvailablePort()
8c15553e
RG
50 _config_template = """
51 newServer{address="127.0.0.1:%s"}
1d896c34
RG
52 setKey("%s")
53 controlSocket("127.0.0.1:%s")
8c15553e
RG
54
55 -- generate an OCSP response file for our certificate, valid one day
56 generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)
57 addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { ocspResponses={"%s"}})
58 """
1d896c34 59 _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_serverCert', '_caCert', '_caKey', '_ocspFile', '_dohServerPort', '_serverCert', '_serverKey', '_ocspFile']
8c15553e 60
13291274
RG
61 @classmethod
62 def setUpClass(cls):
63
64 # for some reason, @unittest.skipIf() is not applied to derived classes with some versions of Python
65 if 'SKIP_DOH_TESTS' in os.environ:
66 raise unittest.SkipTest('DNS over HTTPS tests are disabled')
67
68 cls.startResponders()
69 cls.startDNSDist()
70 cls.setUpSockets()
71
72 print("Launching tests..")
73
8c15553e
RG
74 def testOCSPStapling(self):
75 """
76 OCSP Stapling: DOH
77 """
78 output = self.checkOCSPStaplingStatus('127.0.0.1', self._dohServerPort, self._serverName, self._caCert)
79 self.assertIn('OCSP Response Status: successful (0x0)', output)
80
1d896c34
RG
81 serialNumber = self.getOCSPSerial(output)
82 self.assertTrue(serialNumber)
83
84 self.generateNewCertificateAndKey()
85 self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile))
86 self.sendConsoleCommand("reloadAllCertificates()")
87
88 output = self.checkOCSPStaplingStatus('127.0.0.1', self._dohServerPort, self._serverName, self._caCert)
89 self.assertIn('OCSP Response Status: successful (0x0)', output)
90 serialNumber2 = self.getOCSPSerial(output)
91 self.assertTrue(serialNumber2)
4bfebc93 92 self.assertNotEqual(serialNumber, serialNumber2)
1d896c34 93
d1ce3058
RG
94class TestBrokenOCSPStaplingDoH(DNSDistOCSPStaplingTest):
95
96 _consoleKey = DNSDistTest.generateConsoleKey()
97 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
98 _serverKey = 'server.key'
99 _serverCert = 'server.chain'
100 _serverName = 'tls.tests.dnsdist.org'
101 _caCert = 'ca.pem'
102 # invalid OCSP file!
103 _ocspFile = '/dev/null'
630eb526 104 _tlsServerPort = pickAvailablePort()
d1ce3058
RG
105 _config_template = """
106 newServer{address="127.0.0.1:%s"}
107 setKey("%s")
108 controlSocket("127.0.0.1:%s")
109
110 addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { ocspResponses={"%s"}})
111 """
112 _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_tlsServerPort', '_serverCert', '_serverKey', '_ocspFile']
113
114 def testBrokenOCSPStapling(self):
115 """
116 OCSP Stapling: Broken (DoH)
117 """
118 output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert)
119 self.assertNotIn('OCSP Response Status: successful (0x0)', output)
120
8c15553e
RG
121class TestOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest):
122
1d896c34
RG
123 _consoleKey = DNSDistTest.generateConsoleKey()
124 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
8c15553e
RG
125 _serverKey = 'server.key'
126 _serverCert = 'server.chain'
127 _serverName = 'tls.tests.dnsdist.org'
128 _ocspFile = 'server.ocsp'
129 _caCert = 'ca.pem'
130 _caKey = 'ca.key'
630eb526 131 _tlsServerPort = pickAvailablePort()
8c15553e
RG
132 _config_template = """
133 newServer{address="127.0.0.1:%s"}
1d896c34
RG
134 setKey("%s")
135 controlSocket("127.0.0.1:%s")
8c15553e
RG
136
137 -- generate an OCSP response file for our certificate, valid one day
138 generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)
139 addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="gnutls", ocspResponses={"%s"}})
140 """
1d896c34 141 _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_serverCert', '_caCert', '_caKey', '_ocspFile', '_tlsServerPort', '_serverCert', '_serverKey', '_ocspFile']
8c15553e
RG
142
143 def testOCSPStapling(self):
144 """
145 OCSP Stapling: TLS (GnuTLS)
146 """
147 output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert)
148 self.assertIn('OCSP Response Status: successful (0x0)', output)
630eb526 149 self.assertEqual(self.getTLSProvider(), "gnutls")
8c15553e 150
1d896c34
RG
151 serialNumber = self.getOCSPSerial(output)
152 self.assertTrue(serialNumber)
153
154 self.generateNewCertificateAndKey()
155 self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile))
156 self.sendConsoleCommand("reloadAllCertificates()")
157
158 output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert)
159 self.assertIn('OCSP Response Status: successful (0x0)', output)
160 serialNumber2 = self.getOCSPSerial(output)
161 self.assertTrue(serialNumber2)
4bfebc93 162 self.assertNotEqual(serialNumber, serialNumber2)
1d896c34 163
d1ce3058
RG
164class TestBrokenOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest):
165
166 _consoleKey = DNSDistTest.generateConsoleKey()
167 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
168 _serverKey = 'server.key'
169 _serverCert = 'server.chain'
170 _serverName = 'tls.tests.dnsdist.org'
171 _caCert = 'ca.pem'
172 # invalid OCSP file!
173 _ocspFile = '/dev/null'
630eb526 174 _tlsServerPort = pickAvailablePort()
d1ce3058
RG
175 _config_template = """
176 newServer{address="127.0.0.1:%s"}
177 setKey("%s")
178 controlSocket("127.0.0.1:%s")
179
180 addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="gnutls", ocspResponses={"%s"}})
181 """
182 _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_tlsServerPort', '_serverCert', '_serverKey', '_ocspFile']
183
184 def testBrokenOCSPStapling(self):
185 """
186 OCSP Stapling: Broken (GnuTLS)
187 """
188 output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert)
189 self.assertNotIn('OCSP Response Status: successful (0x0)', output)
630eb526 190 self.assertEqual(self.getTLSProvider(), "gnutls")
d1ce3058 191
8c15553e
RG
192class TestOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest):
193
1d896c34
RG
194 _consoleKey = DNSDistTest.generateConsoleKey()
195 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
8c15553e
RG
196 _serverKey = 'server.key'
197 _serverCert = 'server.chain'
198 _serverName = 'tls.tests.dnsdist.org'
199 _ocspFile = 'server.ocsp'
200 _caCert = 'ca.pem'
201 _caKey = 'ca.key'
630eb526 202 _tlsServerPort = pickAvailablePort()
8c15553e
RG
203 _config_template = """
204 newServer{address="127.0.0.1:%s"}
1d896c34
RG
205 setKey("%s")
206 controlSocket("127.0.0.1:%s")
8c15553e
RG
207
208 -- generate an OCSP response file for our certificate, valid one day
209 generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)
210 addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl", ocspResponses={"%s"}})
211 """
1d896c34 212 _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_serverCert', '_caCert', '_caKey', '_ocspFile', '_tlsServerPort', '_serverCert', '_serverKey', '_ocspFile']
8c15553e
RG
213
214 def testOCSPStapling(self):
215 """
216 OCSP Stapling: TLS (OpenSSL)
217 """
218 output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert)
219 self.assertIn('OCSP Response Status: successful (0x0)', output)
630eb526 220 self.assertEqual(self.getTLSProvider(), "openssl")
1d896c34
RG
221
222 serialNumber = self.getOCSPSerial(output)
223 self.assertTrue(serialNumber)
224
225 self.generateNewCertificateAndKey()
226 self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile))
227 self.sendConsoleCommand("reloadAllCertificates()")
228
229 output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert)
230 self.assertIn('OCSP Response Status: successful (0x0)', output)
231 serialNumber2 = self.getOCSPSerial(output)
232 self.assertTrue(serialNumber2)
4bfebc93 233 self.assertNotEqual(serialNumber, serialNumber2)
d1ce3058
RG
234
235class TestBrokenOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest):
236
237 _consoleKey = DNSDistTest.generateConsoleKey()
238 _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii')
239 _serverKey = 'server.key'
240 _serverCert = 'server.chain'
241 _serverName = 'tls.tests.dnsdist.org'
242 _caCert = 'ca.pem'
243 # invalid OCSP file!
244 _ocspFile = '/dev/null'
630eb526 245 _tlsServerPort = pickAvailablePort()
d1ce3058
RG
246 _config_template = """
247 newServer{address="127.0.0.1:%s"}
248 setKey("%s")
249 controlSocket("127.0.0.1:%s")
250
251 addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl", ocspResponses={"%s"}})
252 """
253 _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_tlsServerPort', '_serverCert', '_serverKey', '_ocspFile']
254
255 def testBrokenOCSPStapling(self):
256 """
257 OCSP Stapling: Broken (OpenSSL)
258 """
259 output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert)
260 self.assertNotIn('OCSP Response Status: successful (0x0)', output)
630eb526 261 self.assertEqual(self.getTLSProvider(), "openssl")