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