1 # Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
3 # Permission to use, copy, modify, and distribute this software and its
4 # documentation for any purpose with or without fee is hereby granted,
5 # provided that the above copyright notice and this permission notice
6 # appear in all copies.
8 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 class BadSigTime(dns
.exception
.DNSException
):
26 """Raised when a SIG or RRSIG RR's time cannot be parsed."""
29 def sigtime_to_posixtime(what
):
33 month
= int(what
[4:6])
35 hour
= int(what
[8:10])
36 minute
= int(what
[10:12])
37 second
= int(what
[12:14])
38 return calendar
.timegm((year
, month
, day
, hour
, minute
, second
,
41 def posixtime_to_sigtime(what
):
42 return time
.strftime('%Y%m%d%H%M%S', time
.gmtime(what
))
44 class RRSIG(dns
.rdata
.Rdata
):
47 @ivar type_covered: the rdata type this signature covers
48 @type type_covered: int
49 @ivar algorithm: the algorithm used for the sig
51 @ivar labels: number of labels
53 @ivar original_ttl: the original TTL
54 @type original_ttl: long
55 @ivar expiration: signature expiration time
56 @type expiration: long
57 @ivar inception: signature inception time
59 @ivar key_tag: the key tag
61 @ivar signer: the signer
62 @type signer: dns.name.Name object
63 @ivar signature: the signature
64 @type signature: string"""
66 __slots__
= ['type_covered', 'algorithm', 'labels', 'original_ttl',
67 'expiration', 'inception', 'key_tag', 'signer',
70 def __init__(self
, rdclass
, rdtype
, type_covered
, algorithm
, labels
,
71 original_ttl
, expiration
, inception
, key_tag
, signer
,
73 super(RRSIG
, self
).__init
__(rdclass
, rdtype
)
74 self
.type_covered
= type_covered
75 self
.algorithm
= algorithm
77 self
.original_ttl
= original_ttl
78 self
.expiration
= expiration
79 self
.inception
= inception
80 self
.key_tag
= key_tag
82 self
.signature
= signature
85 return self
.type_covered
87 def to_text(self
, origin
=None, relativize
=True, **kw
):
88 return '%s %d %d %d %s %s %d %s %s' % (
89 dns
.rdatatype
.to_text(self
.type_covered
),
93 posixtime_to_sigtime(self
.expiration
),
94 posixtime_to_sigtime(self
.inception
),
97 dns
.rdata
._base
64ify
(self
.signature
)
100 def from_text(cls
, rdclass
, rdtype
, tok
, origin
= None, relativize
= True):
101 type_covered
= dns
.rdatatype
.from_text(tok
.get_string())
102 algorithm
= dns
.dnssec
.algorithm_from_text(tok
.get_string())
103 labels
= tok
.get_int()
104 original_ttl
= tok
.get_ttl()
105 expiration
= sigtime_to_posixtime(tok
.get_string())
106 inception
= sigtime_to_posixtime(tok
.get_string())
107 key_tag
= tok
.get_int()
108 signer
= tok
.get_name()
109 signer
= signer
.choose_relativity(origin
, relativize
)
112 t
= tok
.get().unescape()
113 if t
.is_eol_or_eof():
115 if not t
.is_identifier():
116 raise dns
.exception
.SyntaxError
117 chunks
.append(t
.value
)
118 b64
= ''.join(chunks
)
119 signature
= b64
.decode('base64_codec')
120 return cls(rdclass
, rdtype
, type_covered
, algorithm
, labels
,
121 original_ttl
, expiration
, inception
, key_tag
, signer
,
124 from_text
= classmethod(from_text
)
126 def to_wire(self
, file, compress
= None, origin
= None):
127 header
= struct
.pack('!HBBIIIH', self
.type_covered
,
128 self
.algorithm
, self
.labels
,
129 self
.original_ttl
, self
.expiration
,
130 self
.inception
, self
.key_tag
)
132 self
.signer
.to_wire(file, None, origin
)
133 file.write(self
.signature
)
135 def from_wire(cls
, rdclass
, rdtype
, wire
, current
, rdlen
, origin
= None):
136 header
= struct
.unpack('!HBBIIIH', wire
[current
: current
+ 18])
139 (signer
, cused
) = dns
.name
.from_wire(wire
[: current
+ rdlen
], current
)
142 if not origin
is None:
143 signer
= signer
.relativize(origin
)
144 signature
= wire
[current
: current
+ rdlen
].unwrap()
145 return cls(rdclass
, rdtype
, header
[0], header
[1], header
[2],
146 header
[3], header
[4], header
[5], header
[6], signer
,
149 from_wire
= classmethod(from_wire
)
151 def choose_relativity(self
, origin
= None, relativize
= True):
152 self
.signer
= self
.signer
.choose_relativity(origin
, relativize
)
154 def _cmp(self
, other
):
155 return self
._wire
_cmp
(other
)