]> git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.api/test_cryptokeys.py
Merge pull request #6095 from rgacogne/rec-outgoing-buffer-off
[thirdparty/pdns.git] / regression-tests.api / test_cryptokeys.py
1 import subprocess
2 import json
3 import unittest
4 import os
5
6 from test_helper import ApiTestCase, is_auth
7
8 @unittest.skipIf(not is_auth(), "Not applicable")
9 class Cryptokeys(ApiTestCase):
10
11 def __init__(self, *args, **kwds):
12 super(Cryptokeys, self).__init__(*args, **kwds)
13 self.keyid = 0
14 self.zone = "cryptokeys.org"
15
16 def tearDown(self):
17 super(Cryptokeys,self).tearDown()
18 self.remove_zone_key(self.keyid)
19
20 # Adding a key to self.zone using the pdnsutil command
21 def add_zone_key(self, status='inactive'):
22 try:
23 return subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "add-zone-key", self.zone, "ksk", status], stderr=open(os.devnull, 'wb'))
24 except subprocess.CalledProcessError as e:
25 self.fail("pdnsutil add-zone-key failed: "+e.output)
26
27 # Removes a key from self.zone by id using the pdnsutil command
28 def remove_zone_key(self, key_id):
29 try:
30 subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "remove-zone-key", self.zone, str(key_id)])
31 except subprocess.CalledProcessError as e:
32 self.fail("pdnsutil remove-zone-key failed: "+e.output)
33
34 # This method tests the DELETE api call.
35 def test_delete(self):
36 self.keyid = self.add_zone_key()
37
38 #checks the status code. I don't know how to test explicit that the backend fail removing a key.
39 r = self.session.delete(self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid))
40 self.assertEquals(r.status_code, 200)
41 self.assertEquals(r.content, "")
42
43 # Check that the key is actually deleted
44 try:
45 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "list-keys", self.zone])
46 self.assertNotIn(self.zone, out)
47 except subprocess.CalledProcessError as e:
48 self.fail("pdnsutil list-keys failed: " + e.output)
49
50 def test_get_wrong_zone(self):
51 self.keyid = self.add_zone_key()
52 r = self.session.get(self.url("/api/v1/servers/localhost/zones/"+self.zone+"fail/cryptokeys/"+self.keyid))
53 self.assertEquals(r.status_code, 404)
54
55 def test_delete_wrong_zone(self):
56 self.keyid = self.add_zone_key()
57 #checks for not covered zonename
58 r = self.session.delete(self.url("/api/v1/servers/localhost/zones/"+self.zone+"fail/cryptokeys/"+self.keyid))
59 self.assertEquals(r.status_code, 404)
60
61 def test_delete_key_is_gone(self):
62 self.keyid = self.add_zone_key()
63 self.remove_zone_key(self.keyid)
64 #checks for key is gone. Its ok even if no key had to be deleted. Or something went wrong with the backend.
65 r = self.session.delete(self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid))
66 self.assertEquals(r.status_code, 200)
67 self.assertEquals(r.content, "")
68
69 # Prepares the json object for Post and sends it to the server
70 def add_key(self, content='', type='ksk', active='true' , algo='', bits=0):
71 if algo == '':
72 payload = {
73 'keytype': type,
74 'active' : active
75 }
76 else:
77 payload = {
78 'keytype': type,
79 'active' : active,
80 'algorithm' : algo
81 }
82 if bits > 0:
83 payload['bits'] = bits
84 if content != '':
85 payload['content'] = content
86 r = self.session.post(
87 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys"),
88 data=json.dumps(payload),
89 headers={'content-type': 'application/json'})
90
91 return r
92
93 # Test POST for a positive result and delete the added key
94 def post_helper(self,content='', algo='', bits=0):
95 r = self.add_key(content=content, algo=algo, bits=bits)
96 self.assert_success_json(r)
97 self.assertEquals(r.status_code, 201)
98 response = r.json()
99 # Only a ksk added, so expected type is csk
100 self.assertEquals(response['keytype'], 'csk')
101 self.keyid = response['id']
102 # Check if the key is actually added
103 try:
104 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "list-keys", self.zone])
105 self.assertIn(self.zone, out)
106 except subprocess.CalledProcessError as e:
107 self.fail("pdnsutil list-keys failed: " + e.output)
108
109 # Test POST to add a key with default algorithm
110 def test_post(self):
111 self.post_helper()
112
113 # Test POST to add a key with specific algorithm number
114 def test_post_specific_number(self):
115 self.post_helper(algo=10, bits=512)
116
117 # Test POST to add a key with specific name and bits
118 def test_post_specific_name_bits(self):
119 self.post_helper(algo="rsasha256", bits=256)
120
121 # Test POST to add a key with specific name
122 def test_post_specific_name(self):
123 self.post_helper(algo='ecdsa256')
124
125 # Test POST to add a private key from external resource
126 def test_post_content(self):
127 self.post_helper(content="Private-key-format: v1.2\n"+
128 "Algorithm: 8 (RSASHA256)\n"+
129 "Modulus: 4GlYLGgDI7ohnP8SmEW8EBERbNRusDcg0VQda/EPVHU=\n"+
130 "PublicExponent: AQAB\n"+
131 "PrivateExponent: JBnuXF5zOtkjtSz3odV+Fk5UNUTTeCsiI16dkcM7TVU=\n"+
132 "Prime1: /w7TM4118RoSEvP8+dgnCw==\n"+
133 "Prime2: 4T2KhkYLa3w7rdK3Cb2ifw==\n"+
134 "Exponent1: 3aeKj9Ct4JuhfWsgPBhGxQ==\n"+
135 "Exponent2: tfh1OMPQKBdnU6iATjNR2w==\n"+
136 "Coefficient: eVrHe/kauqOewSKndIImrg==)\n")
137
138 def test_post_wrong_key_format(self):
139 r = self.add_key(content="trollololoooolll")
140 self.assert_error_json(r)
141 self.assertEquals(r.status_code, 422)
142 self.assertIn("Key could not be parsed. Make sure your key format is correct.",r.json()['error'])
143
144 def test_post_wrong_keytype(self):
145 r = self.add_key(type='sdfdhhgj')
146 self.assert_error_json(r)
147 self.assertEquals(r.status_code, 422)
148 self.assertIn("Invalid keytype",r.json()['error'])
149
150 def test_post_wrong_bits_format(self):
151 r = self.add_key(bits='sdfdhhgj')
152 self.assert_error_json(r)
153 self.assertEquals(r.status_code, 422)
154 self.assertIn("'bits' must be a positive integer value",r.json()['error'])
155
156 r = self.add_key(bits='5.5')
157 self.assert_error_json(r)
158 self.assertEquals(r.status_code, 422)
159 self.assertIn("'bits' must be a positive integer value",r.json()['error'])
160
161 r = self.add_key(bits='-6')
162 self.assert_error_json(r)
163 self.assertEquals(r.status_code, 422)
164 self.assertIn("'bits' must be a positive integer value",r.json()['error'])
165
166 def test_post_unsupported_algorithm(self):
167 r = self.add_key(algo='lkjhgf')
168 self.assert_error_json(r)
169 self.assertEquals(r.status_code, 422)
170 self.assertIn("Unknown algorithm:",r.json()['error'])
171
172 def test_post_forgot_bits(self):
173 r = self.add_key(algo="rsasha256")
174 self.assert_error_json(r)
175 self.assertEquals(r.status_code, 422)
176 self.assertIn("key requires the size (in bits) to be passed", r.json()['error'])
177
178 def test_post_wrong_bit_size(self):
179 r = self.add_key(algo=10, bits=30)
180 self.assert_error_json(r)
181 self.assertEquals(r.status_code,422)
182 self.assertIn("The algorithm does not support the given bit size.", r.json()['error'])
183
184 def test_post_can_not_guess_key_size(self):
185 r = self.add_key(algo=17)
186 self.assert_error_json(r)
187 self.assertEquals(r.status_code,422)
188 self.assertIn("Can not guess key size for algorithm", r.json()['error'])
189
190 def test_put_activate_key(self):
191 self.keyid = self.add_zone_key()
192
193 payload = {
194 'active': True
195 }
196 r = self.session.put(
197 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
198 data=json.dumps(payload),
199 headers={'content-type': 'application/json'})
200 self.assertEquals(r.status_code, 204)
201 self.assertEquals(r.content, "")
202
203 # check if key is activated
204 try:
205 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "show-zone", self.zone])
206 self.assertIn("Active", out)
207 except subprocess.CalledProcessError as e:
208 self.fail("pdnsutil show-zone failed: " + e.output)
209
210 def test_put_deactivate_key(self):
211 self.keyid= self.add_zone_key(status='active')
212 # deactivate key
213 payload2 = {
214 'active': False
215 }
216
217 r = self.session.put(
218 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
219 data=json.dumps(payload2),
220 headers={'content-type': 'application/json'})
221 self.assertEquals(r.status_code, 204)
222 self.assertEquals(r.content, "")
223
224 # check if key is deactivated
225 try:
226 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "show-zone", self.zone])
227 self.assertIn("Inactive", out)
228 except subprocess.CalledProcessError as e:
229 self.fail("pdnsutil show-zone failed: " + e.output)
230
231 def test_put_deactivate_inactive_key(self):
232 self.keyid = self.add_zone_key()
233
234 # deactivate key
235 payload = {
236 'active': False
237 }
238
239 r = self.session.put(
240 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
241 data=json.dumps(payload),
242 headers={'content-type': 'application/json'})
243 self.assertEquals(r.status_code, 204)
244 self.assertEquals(r.content, "")
245
246 # check if key is still deactivated
247 try:
248 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "show-zone", self.zone])
249 self.assertIn("Inactive", out)
250 except subprocess.CalledProcessError as e:
251 self.fail("pdnsutil show-zone failed: " + e.output)
252
253 def test_put_activate_active_key(self):
254 self.keyid =self.add_zone_key(status='active')
255
256 # activate key
257 payload2 = {
258 'active': True
259 }
260 r = self.session.put(
261 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
262 data=json.dumps(payload2),
263 headers={'content-type': 'application/json'})
264 self.assertEquals(r.status_code, 204)
265 self.assertEquals(r.content, "")
266
267 # check if key is activated
268 try:
269 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "show-zone", self.zone])
270 self.assertIn("Active", out)
271 except subprocess.CalledProcessError as e:
272 self.fail("pdnsutil show-zone failed: " + e.output)