def testResponseLargerThanPaddedQuery(self): """ DNSCrypt: response larger than query Send a small encrypted query (don't forget to take the padding into account) and check that the response is truncated. """ client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) name = 'smallquerylargeresponse.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'TXT', 'IN', use_edns=True, payload=4096) response = dns.message.make_response(query) rrset = dns.rrset.from_text(name, 3600, dns.rdataclass.IN, dns.rdatatype.TXT, 'A'*255) response.answer.append(rrset) self._toResponderQueue.put(response) data = client.query(query.to_wire()) receivedQuery = None if not self._fromResponderQueue.empty(): receivedQuery = self._fromResponderQueue.get(query) receivedResponse = dns.message.from_wire(data) self.assertTrue(receivedQuery) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(receivedResponse.question, response.question) self.assertTrue(receivedResponse.flags & ~dns.flags.TC) self.assertTrue(len(receivedResponse.answer) == 0) self.assertTrue(len(receivedResponse.authority) == 0) self.assertTrue(len(receivedResponse.additional) == 0)
def testSimpleA(self): """ Send an encrypted A query. """ client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) name = 'a.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) rrset = dns.rrset.from_text(name, 3600, dns.rdataclass.IN, dns.rdatatype.A, '127.0.0.1') response.answer.append(rrset) self._toResponderQueue.put(response) data = client.query(query.to_wire()) receivedResponse = dns.message.from_wire(data) receivedQuery = None if not self._fromResponderQueue.empty(): receivedQuery = self._fromResponderQueue.get(query) self.assertTrue(receivedQuery) self.assertTrue(receivedResponse) receivedQuery.id = query.id receivedResponse.id = response.id self.assertEquals(query, receivedQuery) self.assertEquals(response, receivedResponse)
def testCertRotation(self): """ DNSCrypt: automatic certificate rotation """ client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) client.refreshResolverCertificates() cert = client.getResolverCertificate() self.assertTrue(cert) firstSerial = cert.serial self.assertGreaterEqual(cert.serial, self._resolverCertificateSerial) time.sleep(3) client.refreshResolverCertificates() cert = client.getResolverCertificate() self.assertTrue(cert) secondSerial = cert.serial self.assertGreater(cert.serial, firstSerial) name = 'automatic-rotation.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) rrset = dns.rrset.from_text(name, 3600, dns.rdataclass.IN, dns.rdatatype.A, '192.2.0.1') response.answer.append(rrset) self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True)
def testProtocolTCP(self): """ DNSCrypt: Test DNSQuestion.Protocol over TCP """ client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) name = 'tcp.protocols.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) self.doDNSCryptQuery(client, query, response, True)
def testSimpleA(self): """ DNSCrypt: encrypted A query """ client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) name = 'a.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) rrset = dns.rrset.from_text(name, 3600, dns.rdataclass.IN, dns.rdatatype.A, '192.2.0.1') response.answer.append(rrset) self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True)
def testCachedSimpleA(self): """ DNSCrypt: encrypted A query served from cache """ misses = 0 client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) name = 'cacheda.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) rrset = dns.rrset.from_text(name, 3600, dns.rdataclass.IN, dns.rdatatype.A, '192.2.0.1') response.answer.append(rrset) # first query to fill the cache self._toResponderQueue.put(response) data = client.query(query.to_wire()) receivedResponse = dns.message.from_wire(data) receivedQuery = None if not self._fromResponderQueue.empty(): receivedQuery = self._fromResponderQueue.get(query) self.assertTrue(receivedQuery) self.assertTrue(receivedResponse) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) misses += 1 # second query should get a cached response data = client.query(query.to_wire()) receivedResponse = dns.message.from_wire(data) receivedQuery = None if not self._fromResponderQueue.empty(): receivedQuery = self._fromResponderQueue.get(query) self.assertEqual(receivedQuery, None) self.assertTrue(receivedResponse) self.assertEqual(response, receivedResponse) total = 0 for key in self._responsesCounter: total += self._responsesCounter[key] self.assertEqual(total, misses)
def testCertRotation(self): """ DNSCrypt: certificate rotation """ client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) client.refreshResolverCertificates() cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEqual(cert.serial, self._resolverCertificateSerial) name = 'rotation.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) rrset = dns.rrset.from_text(name, 3600, dns.rdataclass.IN, dns.rdatatype.A, '192.2.0.1') response.answer.append(rrset) self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True) # generate a new certificate self.sendConsoleCommand("generateDNSCryptCertificate('DNSCryptProviderPrivate.key', 'DNSCryptResolver.cert.2', 'DNSCryptResolver.key.2', {!s}, {:.0f}, {:.0f})".format(self._resolverCertificateSerial + 1, self._resolverCertificateValidFrom, self._resolverCertificateValidUntil)) # add that new certificate self.sendConsoleCommand("getDNSCryptBind(0):loadNewCertificate('DNSCryptResolver.cert.2', 'DNSCryptResolver.key.2')") oldSerial = self.sendConsoleCommand("getDNSCryptBind(0):getCertificate(0):getSerial()") self.assertEqual(int(oldSerial), self._resolverCertificateSerial) effectiveSerial = self.sendConsoleCommand("getDNSCryptBind(0):getCertificate(1):getSerial()") self.assertEqual(int(effectiveSerial), self._resolverCertificateSerial + 1) tsStart = self.sendConsoleCommand("getDNSCryptBind(0):getCertificate(1):getTSStart()") self.assertEqual(int(tsStart), self._resolverCertificateValidFrom) tsEnd = self.sendConsoleCommand("getDNSCryptBind(0):getCertificate(1):getTSEnd()") self.assertEqual(int(tsEnd), self._resolverCertificateValidUntil) # we should still be able to send queries with the previous certificate self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True) cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEqual(cert.serial, self._resolverCertificateSerial) # but refreshing should get us the new one client.refreshResolverCertificates() cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEqual(cert.serial, self._resolverCertificateSerial + 1) # we should still get the old ones certs = client.getAllResolverCertificates(True) self.assertEqual(len(certs), 2) self.assertEqual(certs[0].serial, self._resolverCertificateSerial) self.assertEqual(certs[1].serial, self._resolverCertificateSerial + 1) # generate a third certificate, this time in memory self.sendConsoleCommand("getDNSCryptBind(0):generateAndLoadInMemoryCertificate('DNSCryptProviderPrivate.key', {!s}, {:.0f}, {:.0f})".format(self._resolverCertificateSerial + 2, self._resolverCertificateValidFrom, self._resolverCertificateValidUntil)) # we should still be able to send queries with the previous certificate self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True) cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEqual(cert.serial, self._resolverCertificateSerial + 1) # but refreshing should get us the new one client.refreshResolverCertificates() cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEqual(cert.serial, self._resolverCertificateSerial + 2) # we should still get the old ones certs = client.getAllResolverCertificates(True) self.assertEqual(len(certs), 3) self.assertEqual(certs[0].serial, self._resolverCertificateSerial) self.assertEqual(certs[1].serial, self._resolverCertificateSerial + 1) self.assertEqual(certs[2].serial, self._resolverCertificateSerial + 2) # generate a fourth certificate, still in memory self.sendConsoleCommand("getDNSCryptBind(0):generateAndLoadInMemoryCertificate('DNSCryptProviderPrivate.key', {!s}, {:.0f}, {:.0f})".format(self._resolverCertificateSerial + 3, self._resolverCertificateValidFrom, self._resolverCertificateValidUntil)) # mark the old ones as inactive self.sendConsoleCommand("getDNSCryptBind(0):markInactive({!s})".format(self._resolverCertificateSerial)) self.sendConsoleCommand("getDNSCryptBind(0):markInactive({!s})".format(self._resolverCertificateSerial + 1)) self.sendConsoleCommand("getDNSCryptBind(0):markInactive({!s})".format(self._resolverCertificateSerial + 2)) # we should still be able to send queries with the third one self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True) cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEqual(cert.serial, self._resolverCertificateSerial + 2) # now remove them self.sendConsoleCommand("getDNSCryptBind(0):removeInactiveCertificate({!s})".format(self._resolverCertificateSerial)) self.sendConsoleCommand("getDNSCryptBind(0):removeInactiveCertificate({!s})".format(self._resolverCertificateSerial + 1)) self.sendConsoleCommand("getDNSCryptBind(0):removeInactiveCertificate({!s})".format(self._resolverCertificateSerial + 2)) # we should not be able to send with the old ones anymore try: data = client.query(query.to_wire()) except socket.timeout: data = None self.assertEqual(data, None) # refreshing should get us the fourth one client.refreshResolverCertificates() cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEqual(cert.serial, self._resolverCertificateSerial + 3) # and only that one certs = client.getAllResolverCertificates(True) self.assertEqual(len(certs), 1) # and we should be able to query with it self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True) cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEqual(cert.serial, self._resolverCertificateSerial + 3)
def testCertRotation(self): """ DNSCrypt: certificate rotation """ client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) client.refreshResolverCertificates() cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEquals(cert.serial, self._resolverCertificateSerial) name = 'rotation.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) rrset = dns.rrset.from_text(name, 3600, dns.rdataclass.IN, dns.rdatatype.A, '192.2.0.1') response.answer.append(rrset) self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True) # generate a new certificate self.sendConsoleCommand("generateDNSCryptCertificate('DNSCryptProviderPrivate.key', 'DNSCryptResolver.cert.2', 'DNSCryptResolver.key.2', {!s}, {:.0f}, {:.0f})".format(self._resolverCertificateSerial + 1, self._resolverCertificateValidFrom, self._resolverCertificateValidUntil)) # switch to that new certificate self.sendConsoleCommand("getDNSCryptBind(0):loadNewCertificate('DNSCryptResolver.cert.2', 'DNSCryptResolver.key.2')") oldSerial = self.sendConsoleCommand("getDNSCryptBind(0):getOldCertificate():getSerial()") self.assertEquals(int(oldSerial), self._resolverCertificateSerial) effectiveSerial = self.sendConsoleCommand("getDNSCryptBind(0):getCurrentCertificate():getSerial()") self.assertEquals(int(effectiveSerial), self._resolverCertificateSerial + 1) tsStart = self.sendConsoleCommand("getDNSCryptBind(0):getCurrentCertificate():getTSStart()") self.assertEquals(int(tsStart), self._resolverCertificateValidFrom) tsEnd = self.sendConsoleCommand("getDNSCryptBind(0):getCurrentCertificate():getTSEnd()") self.assertEquals(int(tsEnd), self._resolverCertificateValidUntil) # we should still be able to send queries with the previous certificate self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True) cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEquals(cert.serial, self._resolverCertificateSerial) # but refreshing should get us the new one client.refreshResolverCertificates() cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEquals(cert.serial, self._resolverCertificateSerial + 1) # generate a third certificate, this time in memory self.sendConsoleCommand("getDNSCryptBind(0):generateAndLoadInMemoryCertificate('DNSCryptProviderPrivate.key', {!s}, {:.0f}, {:.0f})".format(self._resolverCertificateSerial + 2, self._resolverCertificateValidFrom, self._resolverCertificateValidUntil)) # we should still be able to send queries with the previous certificate self.doDNSCryptQuery(client, query, response, False) self.doDNSCryptQuery(client, query, response, True) cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEquals(cert.serial, self._resolverCertificateSerial + 1) # but refreshing should get us the new one client.refreshResolverCertificates() cert = client.getResolverCertificate() self.assertTrue(cert) self.assertEquals(cert.serial, self._resolverCertificateSerial + 2)