]> git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.api/test_cryptokeys.py
Merge pull request #5556 from zilopbg/luabackend-getsoa
[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_delete_wrong_zone(self):
51 self.keyid = self.add_zone_key()
52 #checks for not covered zonename
53 r = self.session.delete(self.url("/api/v1/servers/localhost/zones/"+self.zone+"fail/cryptokeys/"+self.keyid))
54 self.assertEquals(r.status_code, 400)
55
56 def test_delete_key_is_gone(self):
57 self.keyid = self.add_zone_key()
58 self.remove_zone_key(self.keyid)
59 #checks for key is gone. Its ok even if no key had to be deleted. Or something went wrong with the backend.
60 r = self.session.delete(self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid))
61 self.assertEquals(r.status_code, 200)
62 self.assertEquals(r.content, "")
63
64 # Prepares the json object for Post and sends it to the server
65 def add_key(self, content='', type='ksk', active='true' , algo='', bits=0):
66 if algo == '':
67 payload = {
68 'keytype': type,
69 'active' : active
70 }
71 else:
72 payload = {
73 'keytype': type,
74 'active' : active,
75 'algo' : algo
76 }
77 if bits > 0:
78 payload['bits'] = bits
79 if content != '':
80 payload['content'] = content
81 r = self.session.post(
82 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys"),
83 data=json.dumps(payload),
84 headers={'content-type': 'application/json'})
85
86 return r
87
88 # Test POST for a positive result and delete the added key
89 def post_helper(self,content='', algo='', bits=0):
90 r = self.add_key(content=content, algo=algo, bits=bits)
91 self.assert_success_json(r)
92 self.assertEquals(r.status_code, 201)
93 response = r.json()
94 # Only a ksk added, so expected type is csk
95 self.assertEquals(response['keytype'], 'csk')
96 self.keyid = response['id']
97 # Check if the key is actually added
98 try:
99 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "list-keys", self.zone])
100 self.assertIn(self.zone, out)
101 except subprocess.CalledProcessError as e:
102 self.fail("pdnsutil list-keys failed: " + e.output)
103
104 # Test POST to add a key with default algorithm
105 def test_post(self):
106 self.post_helper()
107
108 # Test POST to add a key with specific algorithm number
109 def test_post_specific_number(self):
110 self.post_helper(algo=10, bits=512)
111
112 # Test POST to add a key with specific name and bits
113 def test_post_specific_name_bits(self):
114 self.post_helper(algo="rsasha256", bits=256)
115
116 # Test POST to add a key with specific name
117 def test_post_specific_name(self):
118 self.post_helper(algo='ecdsa256')
119
120 # Test POST to add a private key from external resource
121 def test_post_content(self):
122 self.post_helper(content="Private-key-format: v1.2\n"+
123 "Algorithm: 8 (RSASHA256)\n"+
124 "Modulus: 4GlYLGgDI7ohnP8SmEW8EBERbNRusDcg0VQda/EPVHU=\n"+
125 "PublicExponent: AQAB\n"+
126 "PrivateExponent: JBnuXF5zOtkjtSz3odV+Fk5UNUTTeCsiI16dkcM7TVU=\n"+
127 "Prime1: /w7TM4118RoSEvP8+dgnCw==\n"+
128 "Prime2: 4T2KhkYLa3w7rdK3Cb2ifw==\n"+
129 "Exponent1: 3aeKj9Ct4JuhfWsgPBhGxQ==\n"+
130 "Exponent2: tfh1OMPQKBdnU6iATjNR2w==\n"+
131 "Coefficient: eVrHe/kauqOewSKndIImrg==)\n")
132
133 def test_post_wrong_key_format(self):
134 r = self.add_key(content="trollololoooolll")
135 self.assert_error_json(r)
136 self.assertEquals(r.status_code, 422)
137 self.assertIn("Key could not be parsed. Make sure your key format is correct.",r.json()['error'])
138
139 def test_post_wrong_keytype(self):
140 r = self.add_key(type='sdfdhhgj')
141 self.assert_error_json(r)
142 self.assertEquals(r.status_code, 422)
143 self.assertIn("Invalid keytype",r.json()['error'])
144
145 def test_post_wrong_bits_format(self):
146 r = self.add_key(bits='sdfdhhgj')
147 self.assert_error_json(r)
148 self.assertEquals(r.status_code, 422)
149 self.assertIn("'bits' must be a positive integer value",r.json()['error'])
150
151 r = self.add_key(bits='5.5')
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='-6')
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 def test_post_unsupported_algorithm(self):
162 r = self.add_key(algo='lkjhgf')
163 self.assert_error_json(r)
164 self.assertEquals(r.status_code, 422)
165 self.assertIn("Unknown algorithm:",r.json()['error'])
166
167 def test_post_forgot_bits(self):
168 r = self.add_key(algo="rsasha256")
169 self.assert_error_json(r)
170 self.assertEquals(r.status_code, 422)
171 self.assertIn("key requires the size (in bits) to be passed", r.json()['error'])
172
173 def test_post_wrong_bit_size(self):
174 r = self.add_key(algo=10, bits=30)
175 self.assert_error_json(r)
176 self.assertEquals(r.status_code,422)
177 self.assertIn("The algorithm does not support the given bit size.", r.json()['error'])
178
179 def test_post_can_not_guess_key_size(self):
180 r = self.add_key(algo=17)
181 self.assert_error_json(r)
182 self.assertEquals(r.status_code,422)
183 self.assertIn("Can not guess key size for algorithm", r.json()['error'])
184
185 def test_put_activate_key(self):
186 self.keyid = self.add_zone_key()
187
188 payload = {
189 'active': True
190 }
191 r = self.session.put(
192 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
193 data=json.dumps(payload),
194 headers={'content-type': 'application/json'})
195 self.assertEquals(r.status_code, 204)
196 self.assertEquals(r.content, "")
197
198 # check if key is activated
199 try:
200 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "show-zone", self.zone])
201 self.assertIn("Active", out)
202 except subprocess.CalledProcessError as e:
203 self.fail("pdnsutil show-zone failed: " + e.output)
204
205 def test_put_deactivate_key(self):
206 self.keyid= self.add_zone_key(status='active')
207 # deactivate key
208 payload2 = {
209 'active': False
210 }
211
212 r = self.session.put(
213 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
214 data=json.dumps(payload2),
215 headers={'content-type': 'application/json'})
216 self.assertEquals(r.status_code, 204)
217 self.assertEquals(r.content, "")
218
219 # check if key is deactivated
220 try:
221 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "show-zone", self.zone])
222 self.assertIn("Inactive", out)
223 except subprocess.CalledProcessError as e:
224 self.fail("pdnsutil show-zone failed: " + e.output)
225
226 def test_put_deactivate_inactive_key(self):
227 self.keyid = self.add_zone_key()
228
229 # deactivate key
230 payload = {
231 'active': False
232 }
233
234 r = self.session.put(
235 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
236 data=json.dumps(payload),
237 headers={'content-type': 'application/json'})
238 self.assertEquals(r.status_code, 204)
239 self.assertEquals(r.content, "")
240
241 # check if key is still deactivated
242 try:
243 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "show-zone", self.zone])
244 self.assertIn("Inactive", out)
245 except subprocess.CalledProcessError as e:
246 self.fail("pdnsutil show-zone failed: " + e.output)
247
248 def test_put_activate_active_key(self):
249 self.keyid =self.add_zone_key(status='active')
250
251 # activate key
252 payload2 = {
253 'active': True
254 }
255 r = self.session.put(
256 self.url("/api/v1/servers/localhost/zones/"+self.zone+"/cryptokeys/"+self.keyid),
257 data=json.dumps(payload2),
258 headers={'content-type': 'application/json'})
259 self.assertEquals(r.status_code, 204)
260 self.assertEquals(r.content, "")
261
262 # check if key is activated
263 try:
264 out = subprocess.check_output(["../pdns/pdnsutil", "--config-dir=.", "show-zone", self.zone])
265 self.assertIn("Active", out)
266 except subprocess.CalledProcessError as e:
267 self.fail("pdnsutil show-zone failed: " + e.output)