Package dns :: Package rdtypes :: Package ANY :: Module RRSIG |
[hide private]
[frames] | no frames]

# Source Code for Module dns.rdtypes.ANY.RRSIG

      1  # Copyright (C) 2004-2007, 2009-2011 Nominum, Inc.
      2  #
      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.
      7  #
      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.
     15
     16  import base64
     17  import calendar
     18  import struct
     19  import time
     20
     21  import dns.dnssec
     22  import dns.exception
     23  import dns.rdata
     24  import dns.rdatatype
     25
     26
     27 -class BadSigTime(dns.exception.DNSException):
     28
     29      """Time in DNS SIG or RRSIG resource record cannot be parsed."""
     30
     31
     32 -def sigtime_to_posixtime(what):
     33      if len(what) != 14:
     34          raise BadSigTime
     35      year = int(what[0:4])
     36      month = int(what[4:6])
     37      day = int(what[6:8])
     38      hour = int(what[8:10])
     39      minute = int(what[10:12])
     40      second = int(what[12:14])
     41      return calendar.timegm((year, month, day, hour, minute, second,
     42                              0, 0, 0))
     43
     44
     45 -def posixtime_to_sigtime(what):
     46      return time.strftime('%Y%m%d%H%M%S', time.gmtime(what))
     47
     48
     49 -class RRSIG(dns.rdata.Rdata):
     50
     51      """RRSIG record
     52
     53      @ivar type_covered: the rdata type this signature covers
     54      @type type_covered: int
     55      @ivar algorithm: the algorithm used for the sig
     56      @type algorithm: int
     57      @ivar labels: number of labels
     58      @type labels: int
     59      @ivar original_ttl: the original TTL
     60      @type original_ttl: long
     61      @ivar expiration: signature expiration time
     62      @type expiration: long
     63      @ivar inception: signature inception time
     64      @type inception: long
     65      @ivar key_tag: the key tag
     66      @type key_tag: int
     67      @ivar signer: the signer
     68      @type signer: dns.name.Name object
     69      @ivar signature: the signature
     70      @type signature: string"""
     71
     72      __slots__ = ['type_covered', 'algorithm', 'labels', 'original_ttl',
     73                   'expiration', 'inception', 'key_tag', 'signer',
     74                   'signature']
     75
     76 -    def __init__(self, rdclass, rdtype, type_covered, algorithm, labels,
     77                   original_ttl, expiration, inception, key_tag, signer,
     78                   signature):
     79          super(RRSIG, self).__init__(rdclass, rdtype)
     80          self.type_covered = type_covered
     81          self.algorithm = algorithm
     82          self.labels = labels
     83          self.original_ttl = original_ttl
     84          self.expiration = expiration
     85          self.inception = inception
     86          self.key_tag = key_tag
     87          self.signer = signer
     88          self.signature = signature
     89
     90 -    def covers(self):
     91          return self.type_covered
     92
     93 -    def to_text(self, origin=None, relativize=True, **kw):
     94          return '%s %d %d %d %s %s %d %s %s' % (
     95              dns.rdatatype.to_text(self.type_covered),
     96              self.algorithm,
     97              self.labels,
     98              self.original_ttl,
     99              posixtime_to_sigtime(self.expiration),
    100              posixtime_to_sigtime(self.inception),
    101              self.key_tag,
    102              self.signer.choose_relativity(origin, relativize),
    103              dns.rdata._base64ify(self.signature)
    104          )
    105
    106      @classmethod
    107 -    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
    108          type_covered = dns.rdatatype.from_text(tok.get_string())
    109          algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
    110          labels = tok.get_int()
    111          original_ttl = tok.get_ttl()
    112          expiration = sigtime_to_posixtime(tok.get_string())
    113          inception = sigtime_to_posixtime(tok.get_string())
    114          key_tag = tok.get_int()
    115          signer = tok.get_name()
    116          signer = signer.choose_relativity(origin, relativize)
    117          chunks = []
    118          while 1:
    119              t = tok.get().unescape()
    120              if t.is_eol_or_eof():
    121                  break
    122              if not t.is_identifier():
    123                  raise dns.exception.SyntaxError
    124              chunks.append(t.value.encode())
    125          b64 = b''.join(chunks)
    126          signature = base64.b64decode(b64)
    127          return cls(rdclass, rdtype, type_covered, algorithm, labels,
    128                     original_ttl, expiration, inception, key_tag, signer,
    129                     signature)
    130
    131 -    def to_wire(self, file, compress=None, origin=None):
    132          header = struct.pack('!HBBIIIH', self.type_covered,
    133                               self.algorithm, self.labels,
    134                               self.original_ttl, self.expiration,
    135                               self.inception, self.key_tag)
    136          file.write(header)
    137          self.signer.to_wire(file, None, origin)
    138          file.write(self.signature)
    139
    140      @classmethod
    141 -    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
    142          header = struct.unpack('!HBBIIIH', wire[current: current + 18])
    143          current += 18
    144          rdlen -= 18
    145          (signer, cused) = dns.name.from_wire(wire[: current + rdlen], current)
    146          current += cused
    147          rdlen -= cused
    148          if origin is not None:
    149              signer = signer.relativize(origin)
    150          signature = wire[current: current + rdlen].unwrap()
    151          return cls(rdclass, rdtype, header[0], header[1], header[2],
    152                     header[3], header[4], header[5], header[6], signer,
    153                     signature)
    154
    155 -    def choose_relativity(self, origin=None, relativize=True):
    156          self.signer = self.signer.choose_relativity(origin, relativize)
    157