in range(0, len(data), chunksize)]).decode()
-def _hexify(data, chunksize=_chunksize):
+def _hexify(data, chunksize=_chunksize, **kw):
"""Convert a binary string into its hex encoding, broken up into chunks
of chunksize characters separated by a space.
"""
return _wordbreak(binascii.hexlify(data), chunksize)
-def _base64ify(data, chunksize=_chunksize):
+def _base64ify(data, chunksize=_chunksize, **kw):
"""Convert a binary string into its base64 encoding, broken up into chunks
of chunksize characters separated by a space.
"""
object.__setattr__(self, 'data', data)
def to_text(self, origin=None, relativize=True, **kw):
- return r'\# %d ' % len(self.data) + _hexify(self.data)
+ return r'\# %d ' % len(self.data) + _hexify(self.data, **kw)
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
certificate_type = _ctype_to_text(self.certificate_type)
return "%s %d %s %s" % (certificate_type, self.key_tag,
dns.dnssec.algorithm_to_text(self.algorithm),
- dns.rdata._base64ify(self.certificate))
+ dns.rdata._base64ify(self.certificate, **kw))
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
self.key = self._as_bytes(key)
def to_text(self, origin=None, relativize=True, **kw):
- return dns.rdata._base64ify(self.key, None)
+ return dns.rdata._base64ify(self.key, chunksize=None, **kw)
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
posixtime_to_sigtime(self.inception),
self.key_tag,
self.signer.choose_relativity(origin, relativize),
- dns.rdata._base64ify(self.signature)
+ dns.rdata._base64ify(self.signature, **kw)
)
@classmethod
self.fingerprint = self._as_bytes(fingerprint, True)
def to_text(self, origin=None, relativize=True, **kw):
+ kw = kw.copy()
+ chunksize = kw.pop('chunksize', 128)
return '%d %d %s' % (self.algorithm,
self.fp_type,
dns.rdata._hexify(self.fingerprint,
- chunksize=128))
+ chunksize=chunksize,
+ **kw))
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
self.data = self._as_bytes(data)
def to_text(self, origin=None, relativize=True, **kw):
- return dns.rdata._base64ify(self.data)
+ return dns.rdata._base64ify(self.data, **kw)
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
relativize)
return '%d %d %d %s %s' % (self.precedence, self.gateway_type,
self.algorithm, gateway,
- dns.rdata._base64ify(self.key))
+ dns.rdata._base64ify(self.key, **kw))
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
def to_text(self, origin=None, relativize=True, **kw):
return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm,
- dns.rdata._base64ify(self.key))
+ dns.rdata._base64ify(self.key, **kw))
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
self.digest = self._as_bytes(digest)
def to_text(self, origin=None, relativize=True, **kw):
+ kw = kw.copy()
+ chunksize = kw.pop('chunksize', 128)
return '%d %d %d %s' % (self.key_tag, self.algorithm,
self.digest_type,
dns.rdata._hexify(self.digest,
- chunksize=128))
+ chunksize=chunksize,
+ **kw))
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
% (self.byte_len * 8, self.byte_len))
def to_text(self, origin=None, relativize=True, **kw):
- return dns.rdata._hexify(self.eui, chunksize=2).replace(' ', '-')
+ return dns.rdata._hexify(self.eui, chunksize=2, **kw).replace(' ', '-')
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
self.cert = self._as_bytes(cert)
def to_text(self, origin=None, relativize=True, **kw):
+ kw = kw.copy()
+ chunksize = kw.pop('chunksize', 128)
return '%d %d %d %s' % (self.usage,
self.selector,
self.mtype,
dns.rdata._hexify(self.cert,
- chunksize=128))
+ chunksize=chunksize,
+ **kw))
@classmethod
def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True,
with self.assertRaises(dns.exception.SyntaxError):
dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SMIMEA, '1 1 1 aGVsbG8gd29ybGQh')
+ def test_DNSKEY_chunking(self):
+ inputs = ( # each with chunking as given by dig, unusual chunking, and no chunking
+ # example 1
+ (
+ '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iDSFZNORnQuHKtJ9Wpyz+kNryq uB78Pyk/NTEoai5bxoipVQQXzHlzyg==',
+ '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocK mnS1iDSFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/ NTEoai5bxoipVQQXzHlzyg==',
+ '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iDSFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/NTEoai5bxoipVQQXzHlzyg==',
+ ),
+ # example 2
+ (
+ '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy9mvL5qGQTuaG5TSrNqEAR6b/ qvxDx6my4JmEmjUPA1JeEI9YfTUieMr2UZflu7aIbZFLw0vqiYrywCGr CHXLalOrEOmrvAxLvq4vHtuTlH7JIszzYBSes8g1vle6KG7xXiP3U5Ll 96Qiu6bZ31rlMQSPB20xbqJJh6psNSrQs41QvdcXAej+K2Hl1Wd8kPri ec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFaW2m7N/Wy4qcFU13roWKDEAst bxH5CHPoBfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lvu9TAiZPc0oysY6as lO7jXv16Gws=',
+ '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeq Hy9mvL5qGQTuaG5TSrNqEA R6b/qvxDx6my4JmEmjUPA1JeEI9Y fTUieMr2UZflu7aIbZFLw0vqiYrywCGrC HXLalOrEOmrvAxLvq4vHtuTlH7JIszzYBSes8g1vle6KG7 xXiP3U5Ll 96Qiu6bZ31rlMQSPB20xbqJJh6psNSrQs41QvdcXAej+K2Hl1Wd8kPriec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFaW2m7N/Wy4qcFU13roWKDEAst bxH5CHPoBfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lvu9TAiZPc0oysY6as lO7jXv16Gws=',
+ '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy9mvL5qGQTuaG5TSrNqEAR6b/qvxDx6my4JmEmjUPA1JeEI9YfTUieMr2UZflu7aIbZFLw0vqiYrywCGrCHXLalOrEOmrvAxLvq4vHtuTlH7JIszzYBSes8g1vle6KG7xXiP3U5Ll96Qiu6bZ31rlMQSPB20xbqJJh6psNSrQs41QvdcXAej+K2Hl1Wd8kPriec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFaW2m7N/Wy4qcFU13roWKDEAstbxH5CHPoBfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lvu9TAiZPc0oysY6aslO7jXv16Gws=',
+ ),
+ # example 3
+ (
+ '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5Ofv4akjQGN2zY5AgB/2jmdR/+ 1PvXFqzKCAGJv4wjABEBNWLLFm7ew1hHMDZEKVL17aml0EBKI6Dsz6Mx t6n7ScvLtHaFRKaxT4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0P+2F+TLK l3D0L/cD',
+ '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5Ofv4akjQGN2zY5 AgB/2jmdR/+1PvXFqzKCAGJv4wjABEBNWLLFm7ew1hHMDZEKVL17aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKaxT4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0P+2F+ TLKl3D0L/cD',
+ '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5Ofv4akjQGN2zY5AgB/2jmdR/+1PvXFqzKCAGJv4wjABEBNWLLFm7ew1hHMDZEKVL17aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKaxT4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0P+2F+TLKl3D0L/cD',
+ ),
+ )
+ output_map = {
+ 32: (
+ '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iD SFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/ NTEoai5bxoipVQQXzHlzyg==',
+ '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy 9mvL5qGQTuaG5TSrNqEAR6b/qvxDx6my 4JmEmjUPA1JeEI9YfTUieMr2UZflu7aI bZFLw0vqiYrywCGrCHXLalOrEOmrvAxL vq4vHtuTlH7JIszzYBSes8g1vle6KG7x XiP3U5Ll96Qiu6bZ31rlMQSPB20xbqJJ h6psNSrQs41QvdcXAej+K2Hl1Wd8kPri ec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFa W2m7N/Wy4qcFU13roWKDEAstbxH5CHPo BfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lv u9TAiZPc0oysY6aslO7jXv16Gws=',
+ '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5O fv4akjQGN2zY5AgB/2jmdR/+1PvXFqzK CAGJv4wjABEBNWLLFm7ew1hHMDZEKVL1 7aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKax T4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0 P+2F+TLKl3D0L/cD',
+ ),
+ 56: (t[0] for t in inputs),
+ 0: (t[0][:12] + t[0][12:].replace(' ', '') for t in inputs)
+ }
+
+ for chunksize, outputs in output_map.items():
+ for input, output in zip(inputs, outputs):
+ for input_variation in input:
+ rr = dns.rdata.from_text('IN', 'DNSKEY', input_variation)
+ new_text = rr.to_text(chunksize=chunksize)
+ self.assertEqual(output, new_text)
+
class UtilTestCase(unittest.TestCase):