class Dnsruby::RR::RRSIG

(RFC4034, section 3)

DNSSEC uses public key cryptography to sign and authenticate DNS resource record sets (RRsets). Digital signatures are stored in RRSIG resource records and are used in the DNSSEC authentication process described in [RFC4035]. A validator can use these RRSIG RRs to authenticate RRsets from the zone. The RRSIG RR MUST only be used to carry verification material (digital signatures) used to secure DNS operations.

An RRSIG record contains the signature for an RRset with a particular name, class, and type. The RRSIG RR specifies a validity interval for the signature and uses the Algorithm, the Signer's Name, and the Key Tag to identify the DNSKEY RR containing the public key that a validator can use to verify the signature.

Attributes

algorithm[R]

The algorithm used for this RRSIG See Dnsruby::Algorithms for permitted values

expiration[RW]

The signature expiration

inception[RW]

The signature inception

key_tag[RW]

The key tag value of the DNSKEY RR that validates this signature

labels[RW]

The number of labels in the original RRSIG RR owner name Can be used to determine if name was synthesised from a wildcard.

original_ttl[RW]

The TTL of the covered RRSet as it appears in the authoritative zone

signature[RW]

contains the cryptographic signature that covers the RRSIG RDATA (excluding the Signature field) and the RRset specified by the RRSIG owner name, RRSIG class, and RRSIG Type Covered field

signers_name[R]

identifies the owner name of the DNSKEY RR that a validator is supposed to use to validate this signature

type_covered[R]

The type covered by this RRSIG

Public Class Methods

get_time(input) click to toggle source
# File lib/dnsruby/resource/RRSIG.rb, line 183
def RRSIG.get_time(input)
  if input.kind_of?(Integer)
    return input
  end
  #  RFC 4034, section 3.2
  # The Signature Expiration Time and Inception Time field values MUST be
  #    represented either as an unsigned decimal integer indicating seconds
  #    since 1 January 1970 00:00:00 UTC, or in the form YYYYMMDDHHmmSS in
  #    UTC, where:
  #
  #       YYYY is the year (0001-9999, but see Section 3.1.5);
  #       MM is the month number (01-12);
  #       DD is the day of the month (01-31);
  #       HH is the hour, in 24 hour notation (00-23);
  #       mm is the minute (00-59); and
  #       SS is the second (00-59).
  #
  #    Note that it is always possible to distinguish between these two
  #    formats because the YYYYMMDDHHmmSS format will always be exactly 14
  #    digits, while the decimal representation of a 32-bit unsigned integer
  #    can never be longer than 10 digits.
  if (input.length == 10)
    return input.to_i
  elsif (input.length == 14)
    year = input[0,4]
    mon=input[4,2]
    day=input[6,2]
    hour=input[8,2]
    min=input[10,2]
    sec=input[12,2]
    #  @TODO@ REPLACE THIS BY LOCAL CODE - Time.gm DOG SLOW!
    return Time.gm(year, mon, day, hour, min, sec).to_i
  else
    raise DecodeError.new("RRSIG : Illegal time value #{input} - see RFC 4034 section 3.2")
  end
end

Public Instance Methods

algorithm=(a) click to toggle source
# File lib/dnsruby/resource/RRSIG.rb, line 102
def algorithm=(a)
  if (a.instance_of?String)
    if (a.to_i > 0)
      a = a.to_i
    end
  end
  begin
    alg = Algorithms.new(a)
    @algorithm = alg
  rescue ArgumentError => e
    raise DecodeError.new(e)
  end
end
format_time(time) click to toggle source
# File lib/dnsruby/resource/RRSIG.rb, line 224
def format_time(time)
  return Time.at(time).gmtime.strftime("%Y%m%d%H%M%S")
end
from_string(input) click to toggle source
# File lib/dnsruby/resource/RRSIG.rb, line 145
def from_string(input)
  if (input.length > 0)
    data = input.split(" ")
    self.type_covered=(data[0])
    self.algorithm=(data[1])
    self.labels=data[2].to_i
    self.original_ttl=data[3].to_i
    self.expiration=get_time(data[4])
    #  Brackets may also be present
    index = 5
    end_index = data.length - 1
    if (data[index]=="(")
      index = 6
      end_index = data.length - 2
    end
    self.inception=get_time(data[index])
    self.key_tag=data[index+1].to_i
    self.signers_name=(data[index+2])
    #  signature can include whitespace - include all text
    #  until we come to " )" at the end, and then gsub
    #  the white space out
    buf=""
    (index+3..end_index).each {|i|
      if (comment_index = data[i].index(";"))
        buf += data[i].slice(0, comment_index)
        #  @TODO@ We lose the comments here - we should really keep them for when we write back to string format?
        break
      else
      buf += data[i]
      end
    }
    buf.gsub!(/\n/, "")
    buf.gsub!(/ /, "")
    # self.signature=Base64.decode64(buf)
    self.signature=buf.unpack("m*")[0]
  end
end
get_time(input) click to toggle source
# File lib/dnsruby/resource/RRSIG.rb, line 220
def get_time(input)
  return RRSIG.get_time(input)
end
init_defaults() click to toggle source
# File lib/dnsruby/resource/RRSIG.rb, line 90
def init_defaults
  @algorithm=Algorithms.RSASHA1
  @type_covered = Types::A
  @original_ttl = 3600
  @inception = Time.now.to_i
  @expiration = Time.now.to_i
  @key_tag = 0
  @labels = 0
  self.signers_name="."
  @signature = "\0"
end
sig_data() click to toggle source
# File lib/dnsruby/resource/RRSIG.rb, line 261
def sig_data
  # RRSIG_RDATA is the wire format of the RRSIG RDATA fields
  # with the Signer's Name field in canonical form and
  # the Signature field excluded;
  data = MessageEncoder.new { |msg|
    msg.put_pack('ncc', @type_covered.to_i, @algorithm.to_i, @labels)
    msg.put_pack("NNN", @original_ttl, @expiration, @inception)
    msg.put_pack("n", @key_tag)
    msg.put_name(@signers_name, true)
  }.to_s
  return data
end
signers_name=(s) click to toggle source
# File lib/dnsruby/resource/RRSIG.rb, line 125
def signers_name=(s)
  begin
    name = Name.create(s)
    @signers_name = name
  rescue ArgumentError => e
    raise DecodeError.new(e)
  end
end
type_covered=(t) click to toggle source
# File lib/dnsruby/resource/RRSIG.rb, line 116
def type_covered=(t)
  begin
    type = Types.new(t)
    @type_covered = type
  rescue ArgumentError => e
    raise DecodeError.new(e)
  end
end