1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import base64
17 import struct
18
19 import dns.exception
20 import dns.dnssec
21 import dns.rdata
22
23
24 __all__ = ["SEP", "REVOKE", "ZONE",
25 "flags_to_text_set", "flags_from_text_set"]
26
27
28 SEP = 0x0001
29 REVOKE = 0x0080
30 ZONE = 0x0100
31
32 _flag_by_text = {
33 'SEP': SEP,
34 'REVOKE': REVOKE,
35 'ZONE': ZONE
36 }
37
38
39
40
41 _flag_by_value = dict((y, x) for x, y in _flag_by_text.items())
42
43
44 -def flags_to_text_set(flags):
45 """Convert a DNSKEY flags value to set texts
46 @rtype: set([string])"""
47
48 flags_set = set()
49 mask = 0x1
50 while mask <= 0x8000:
51 if flags & mask:
52 text = _flag_by_value.get(mask)
53 if not text:
54 text = hex(mask)
55 flags_set.add(text)
56 mask <<= 1
57 return flags_set
58
59
60 -def flags_from_text_set(texts_set):
61 """Convert set of DNSKEY flag mnemonic texts to DNSKEY flag value
62 @rtype: int"""
63
64 flags = 0
65 for text in texts_set:
66 try:
67 flags += _flag_by_text[text]
68 except KeyError:
69 raise NotImplementedError(
70 "DNSKEY flag '%s' is not supported" % text)
71 return flags
72
75
76 """Base class for rdata that is like a DNSKEY record
77
78 @ivar flags: the key flags
79 @type flags: int
80 @ivar protocol: the protocol for which this key may be used
81 @type protocol: int
82 @ivar algorithm: the algorithm used for the key
83 @type algorithm: int
84 @ivar key: the public key
85 @type key: string"""
86
87 __slots__ = ['flags', 'protocol', 'algorithm', 'key']
88
89 - def __init__(self, rdclass, rdtype, flags, protocol, algorithm, key):
95
96 - def to_text(self, origin=None, relativize=True, **kw):
97 return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm,
98 dns.rdata._base64ify(self.key))
99
100 @classmethod
101 - def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
102 flags = tok.get_uint16()
103 protocol = tok.get_uint8()
104 algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
105 chunks = []
106 while 1:
107 t = tok.get().unescape()
108 if t.is_eol_or_eof():
109 break
110 if not t.is_identifier():
111 raise dns.exception.SyntaxError
112 chunks.append(t.value.encode())
113 b64 = b''.join(chunks)
114 key = base64.b64decode(b64)
115 return cls(rdclass, rdtype, flags, protocol, algorithm, key)
116
117 - def to_wire(self, file, compress=None, origin=None):
121
122 @classmethod
123 - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
124 if rdlen < 4:
125 raise dns.exception.FormError
126 header = struct.unpack('!HBB', wire[current: current + 4])
127 current += 4
128 rdlen -= 4
129 key = wire[current: current + rdlen].unwrap()
130 return cls(rdclass, rdtype, header[0], header[1], header[2],
131 key)
132
134 """Convert a DNSKEY flags value to set texts
135 @rtype: set([string])"""
136 return flags_to_text_set(self.flags)
137