1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import struct
17 import base64
18 import binascii
19
20 import dns.exception
21 import dns.rdata
22 import dns.rdatatype
23
24
25 -class HIP(dns.rdata.Rdata):
26
27 """HIP record
28
29 @ivar hit: the host identity tag
30 @type hit: string
31 @ivar algorithm: the public key cryptographic algorithm
32 @type algorithm: int
33 @ivar key: the public key
34 @type key: string
35 @ivar servers: the rendezvous servers
36 @type servers: list of dns.name.Name objects
37 @see: RFC 5205"""
38
39 __slots__ = ['hit', 'algorithm', 'key', 'servers']
40
41 - def __init__(self, rdclass, rdtype, hit, algorithm, key, servers):
47
48 - def to_text(self, origin=None, relativize=True, **kw):
49 hit = binascii.hexlify(self.hit).decode()
50 key = base64.b64encode(self.key).replace(b'\n', b'').decode()
51 text = u''
52 servers = []
53 for server in self.servers:
54 servers.append(server.choose_relativity(origin, relativize))
55 if len(servers) > 0:
56 text += (u' ' + u' '.join((x.to_unicode() for x in servers)))
57 return u'%u %s %s%s' % (self.algorithm, hit, key, text)
58
59 @classmethod
60 - def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
61 algorithm = tok.get_uint8()
62 hit = binascii.unhexlify(tok.get_string().encode())
63 if len(hit) > 255:
64 raise dns.exception.SyntaxError("HIT too long")
65 key = base64.b64decode(tok.get_string().encode())
66 servers = []
67 while 1:
68 token = tok.get()
69 if token.is_eol_or_eof():
70 break
71 server = dns.name.from_text(token.value, origin)
72 server.choose_relativity(origin, relativize)
73 servers.append(server)
74 return cls(rdclass, rdtype, hit, algorithm, key, servers)
75
76 - def to_wire(self, file, compress=None, origin=None):
77 lh = len(self.hit)
78 lk = len(self.key)
79 file.write(struct.pack("!BBH", lh, self.algorithm, lk))
80 file.write(self.hit)
81 file.write(self.key)
82 for server in self.servers:
83 server.to_wire(file, None, origin)
84
85 @classmethod
86 - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
87 (lh, algorithm, lk) = struct.unpack('!BBH',
88 wire[current: current + 4])
89 current += 4
90 rdlen -= 4
91 hit = wire[current: current + lh].unwrap()
92 current += lh
93 rdlen -= lh
94 key = wire[current: current + lk].unwrap()
95 current += lk
96 rdlen -= lk
97 servers = []
98 while rdlen > 0:
99 (server, cused) = dns.name.from_wire(wire[: current + rdlen],
100 current)
101 current += cused
102 rdlen -= cused
103 if origin is not None:
104 server = server.relativize(origin)
105 servers.append(server)
106 return cls(rdclass, rdtype, hit, algorithm, key, servers)
107
114