Class: Dnsruby::RR::DNSKEY

Inherits:
Dnsruby::RR show all
Defined in:
lib/Dnsruby/resource/DNSKEY.rb

Overview

RFC4034, section 2 DNSSEC uses public key cryptography to sign and authenticate DNS resource record sets (RRsets). The public keys are stored in DNSKEY resource records and are used in the DNSSEC authentication process described in [RFC4035]: A zone signs its authoritative RRsets by using a private key and stores the corresponding public key in a DNSKEY RR. A resolver can then use the public key to validate signatures covering the RRsets in the zone, and thus to authenticate them.

Constant Summary collapse

ClassValue =

:nodoc: all

nil
TypeValue =

:nodoc: all

Types::DNSKEY
REVOKED_KEY =

Key is revoked

0x80
ZONE_KEY =

Key is a zone key

0x100
SEP_KEY =

Key is a secure entry point key

0x1

Constants inherited from Dnsruby::RR

ClassInsensitiveTypes

Instance Attribute Summary collapse

Attributes inherited from Dnsruby::RR

#klass, #name, #rdata, #ttl, #type

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Dnsruby::RR

#==, create, #eql?, #from_hash, get_class, get_num, #hash, implemented_rrs, new_from_data, new_from_hash, new_from_string, #rdlength, #sameRRset, #to_s

Instance Attribute Details

#algorithmObject

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



47
48
49
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 47

def algorithm
  @algorithm
end

#flagsObject

The flags for the DNSKEY RR



41
42
43
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 41

def flags
  @flags
end

#keyObject

The public key



49
50
51
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 49

def key
  @key
end

#protocolObject

The protocol for this DNSKEY RR. MUST be 3.



44
45
46
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 44

def protocol
  @protocol
end

Class Method Details

.decode_rdata(msg) ⇒ Object

:nodoc: all



181
182
183
184
185
186
187
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 181

def self.decode_rdata(msg) #:nodoc: all
  # 2 octets, then 2 sets of 1 octet
  flags, protocol, algorithm = msg.get_unpack('ncc')
  key = msg.get_bytes
  return self.new(
    [flags, protocol, algorithm, key])
end

Instance Method Details

#dsa_keyObject



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 279

def dsa_key
  t = @key[0]
  t = t.getbyte(0) if t.class == String
  pgy_len = t * 8 + 64
  pos = 1
  q = RR::get_num(@key[pos, 20])
  pos += 20
  p = RR::get_num(@key[pos, pgy_len])
  pos += pgy_len
  g = RR::get_num(@key[pos, pgy_len])
  pos += pgy_len
  y = RR::get_num(@key[pos, pgy_len])
  pos += pgy_len
  
  pkey = OpenSSL::PKey::DSA.new
  pkey.p = p
  pkey.q = q
  pkey.g = g
  pkey.pub_key = y
  
  pkey
end

#encode_rdata(msg, canonical = false) ⇒ Object

:nodoc: all



175
176
177
178
179
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 175

def encode_rdata(msg, canonical=false) #:nodoc: all
  # 2 octets, then 2 sets of 1 octet
  msg.put_pack('ncc', @flags, @protocol, @algorithm.code)
  msg.put_bytes(@key)
end

#from_data(data) ⇒ Object

def bad_flags?

  if ((@flags & ~ZONE_KEY & ~SEP_KEY) > 0)
    return true
  end
  return false
end


135
136
137
138
139
140
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 135

def from_data(data) #:nodoc: all
  flags, protocol, algorithm, @key = data
  self.flags=(flags)
  self.protocol=(protocol)
  self.algorithm=(algorithm)
end

#from_string(input) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 142

def from_string(input)
  if (input.length > 0)
    data = input.split(" ")
    self.flags=(data[0].to_i)
    self.protocol=(data[1].to_i)
    self.algorithm=(data[2])
    # key can include whitespace - include all text
    # until we come to " )" at the end, and then gsub
    # the white space out
    # Also, brackets may or may not be present
    buf = ""
    index = 3
    end_index = data.length - 1
    if (data[index]=="(")
      end_index = data.length - 2
      index = 4
    end
    (index..end_index).each {|i|
      buf += data[i]
    }
    self.key=(buf)
  end
end

#init_defaultsObject



51
52
53
54
55
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 51

def init_defaults
  self.protocol=3
  self.flags=ZONE_KEY
  @algorithm=Algorithms.RSASHA1
end

#key_tagObject



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 189

def key_tag
  tag=0
  rdata = MessageEncoder.new {|msg|
    encode_rdata(msg)
  }.to_s
  if (@algorithm == Algorithms.RSAMD5)
    #The key tag for algorithm 1 (RSA/MD5) is defined differently from the
    #key tag for all other algorithms, for historical reasons.
    d1 = rdata[rdata.length - 3] & 0xFF
    d2 = rdata[rdata.length - 2] & 0xFF
    tag = (d1 << 8) + d2
  else
    tag = 0
    last = 0
    0.step(rdata.length - 1, 2) {|i|
      last = i
      d1 = rdata[i]
      d2 = rdata[i + 1] || 0 # odd number of bytes possible

      d1 = d1.getbyte(0) if d1.class == String # Ruby 1.9
      d2 = d2.getbyte(0) if d2.class == String # Ruby 1.9
    
      d1 = d1  & 0xFF
      d2 = d2  & 0xFF

      tag += ((d1 << 8) + d2)
    }
    last+=2
    if (last < rdata.length)
      d1 = rdata[last] 
      
      if (d1.class == String) # Ruby 1.9
        d1 = d1.getbyte(0)
      end
      
      d1 = d1 & 0xFF
      tag += (d1 << 8)
    end
    tag += ((tag >> 16) & 0xFFFF)
  end
  tag=tag&0xFFFF
  return tag
end

#public_keyObject



240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 240

def public_key
  if (@public_key.nil?)
    if [Algorithms.RSASHA1,
        Algorithms.RSASHA1_NSEC3_SHA1].include?(@algorithm)
      @public_key = rsa_key
    elsif [Algorithms.DSA,
        Algorithms.DSA_NSEC3_SHA1].include?(@algorithm)
      @public_key = dsa_key
    end
  end
  # @TODO@ Support other key encodings!
  return @public_key
end

#rdata_to_stringObject

:nodoc: all



166
167
168
169
170
171
172
173
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 166

def rdata_to_string #:nodoc: all
  if (@flags!=nil)
    #          return "#{@flags} #{@protocol} #{@algorithm.string} ( #{Base64.encode64(@key.to_s)} )"
    return "#{@flags} #{@protocol} #{@algorithm.string} ( #{[@key.to_s].pack("m*").gsub("\n", "")} )"
  else
    return ""
  end
end

#revoked=(on) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 78

def revoked=(on)
  print "setting revoke"
  if (on)
    @flags |= REVOKED_KEY
  else
    @flags &= (~REVOKED_KEY)
  end
end

#revoked?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 87

def revoked?
  return ((@flags & REVOKED_KEY) > 0)
end

#rsa_keyObject



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 254

def rsa_key
  exponentLength = @key[0]
  if (exponentLength.class == String)
    exponentLength = exponentLength.getbyte(0) # Ruby 1.9
  end
  pos = 1
  if (exponentLength == 0)
    key1 = @key[1]
    if (key1.class == String) # Ruby 1.9
      key1 = key1.getbyte(0)
    end
    exponentLength = (key1<<8) + key1
    pos += 2
  end
  exponent = RR::get_num(@key[pos, exponentLength])
  pos += exponentLength

  modulus = RR::get_num(@key[pos, @key.length])

  pkey = OpenSSL::PKey::RSA.new
  pkey.e = exponent
  pkey.n = modulus
  return pkey 
end

#sep_key=(on) ⇒ Object



103
104
105
106
107
108
109
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 103

def sep_key=(on)
  if (on)
    @flags |= SEP_KEY
  else
    @flags &= (~SEP_KEY)
  end
end

#sep_key?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 111

def sep_key?
  return ((@flags & SEP_KEY) > 0)
end

#zone_key=(on) ⇒ Object



91
92
93
94
95
96
97
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 91

def zone_key=(on)
  if (on)
    @flags |= ZONE_KEY
  else
    @flags &= (~ZONE_KEY)
  end
end

#zone_key?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/Dnsruby/resource/DNSKEY.rb', line 99

def zone_key?
  return ((@flags & ZONE_KEY) > 0)
end