Parent

Class Index [+]

Quicksearch

Dnsruby::Dnssec

RFC4033, section 7

  "There is one more step that a security-aware stub resolver can take
  if, for whatever reason, it is not able to establish a useful trust
  relationship with the recursive name servers that it uses: it can
  perform its own signature validation by setting the Checking Disabled
  (CD) bit in its query messages.  A validating stub resolver is thus
  able to treat the DNSSEC signatures as trust relationships between
  the zone administrators and the stub resolver itself. "

Dnsruby is configured to validate responses by default. However, it is not configured with any trusted keys by default. Applications may use the verify() method to perform verification with of RRSets of Messages with given keys. Alternatively, trusted keys may be added to this class (either directly, or by loading the IANA TAR or the DLV ISC ZSK). Validation will then be performed from these keys (or the DLV registry, if configured). Negative and positive responses are validation.

Messages are tagged with the current security_level (Message::SecurityLevel). UNCHECKED means Dnsruby has not attempted to validate the response. BOGUS means the response has been checked, and is bogus. INSECURE means the response has been validated to be insecure (e.g. in an unsigned zone) SECURE means that the response has been verfied to be correct.

Several validators are provided, with each maintaining its own cache of trusted keys. If validators are added or removed, the caches of the other validators are not affected.

Public Class Methods

add_dlv_key(dlv_key) click to toggle source

Add a trusted Key Signing Key for the ISC DLV registry.

    # File lib/Dnsruby/dnssec.rb, line 92
92:     def Dnssec.add_dlv_key(dlv_key)
93:       @@dlv_verifier.add_dlv_key(dlv_key)
94:     end
add_trust_anchor(t) click to toggle source

Add a new trust anchor

    # File lib/Dnsruby/dnssec.rb, line 96
96:     def Dnssec.add_trust_anchor(t)
97:       # @TODO@ Create a new verifier?
98:       @@anchor_verifier.add_trust_anchor(t)
99:     end
add_trust_anchor_with_expiration(k, expiration) click to toggle source

Add the trusted key with the given expiration time

     # File lib/Dnsruby/dnssec.rb, line 101
101:     def self.add_trust_anchor_with_expiration(k, expiration)
102:       # Create a new verifier?
103:       @@anchor_verifier.add_trust_anchor_with_expiration(k, expiration)
104:     end
anchor_verifier() click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 289
289:     def self.anchor_verifier
290:       return @@anchor_verifier
291:     end
clear_trust_anchors() click to toggle source

Wipes the cache of trusted keys

     # File lib/Dnsruby/dnssec.rb, line 110
110:     def self.clear_trust_anchors
111:       @@anchor_verifier.clear_trust_anchors
112:     end
clear_trusted_keys() click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 118
118:     def self.clear_trusted_keys
119:       [@@anchor_verifier, @@root_verifier, @@dlv_verifier].each {|v|
120:         v.clear_trusted_keys
121:       }
122:     end
default_resolver() click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 167
167:     def self.default_resolver
168:       return @@default_resolver
169:     end
default_resolver=(res) click to toggle source

This method overrides the system default resolver configuration for validation If default_resolver is set, then it will be used to follow the chain of trust. If it is not, then the default system resolver will be used (unless do_validation_with_recursor is set.

     # File lib/Dnsruby/dnssec.rb, line 164
164:     def self.default_resolver=(res)
165:       @@default_resolver = res
166:     end
dlv_verifier() click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 292
292:     def self.dlv_verifier
293:       return @@dlv_verifier
294:     end
do_validation_with_recursor(on) click to toggle source

This method defines the choice of Resolver or Recursor, when the validator is checking responses. If set to true, then a Recursor will be used to query for the DNSSEC records. Otherwise, the default system resolver will be used.

     # File lib/Dnsruby/dnssec.rb, line 154
154:     def self.do_validation_with_recursor(on)
155:       @@do_validation_with_recursor = on
156:     end
do_validation_with_recursor?() click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 157
157:     def self.do_validation_with_recursor?
158:       return @@do_validation_with_recursor
159:     end
no_keys?() click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 137
137:     def self.no_keys?
138:       no_keys = true
139:       [@@anchor_verifier, @@root_verifier, @@dlv_verifier].each {|v|
140:         if (v.trusted_keys.length() > 0 ||
141:               v.trust_anchors.length() > 0)
142:           no_keys = false
143:         end
144:       }
145:       return no_keys
146:     end
remove_trust_anchor(t) click to toggle source

Remove the trusted key

     # File lib/Dnsruby/dnssec.rb, line 106
106:     def Dnssec.remove_trust_anchor(t)
107:       @@anchor_verifier.remove_trust_anchor(t)
108:     end
reset() click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 124
124:     def self.reset
125:       @@validation_policy = ValidationPolicy::LOCAL_ANCHORS_THEN_ROOT
126:       @@root_verifier = SingleVerifier.new(SingleVerifier::VerifierType::ROOT)
127:       @@root_verifier.add_root_ds(@@root_key)
128: 
129:       @@dlv_verifier = SingleVerifier.new(SingleVerifier::VerifierType::DLV)
130: 
131:       # @TODO@ Could add a new one of these for each anchor.
132:       @@anchor_verifier = SingleVerifier.new(SingleVerifier::VerifierType::ANCHOR)
133:       @@do_validation_with_recursor = true # Many nameservers don't handle DNSSEC correctly yet
134:       @@default_resolver = Resolver.new
135:     end
root_verifier() click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 295
295:     def self.root_verifier
296:       return @@root_verifier
297:     end
trust_anchors() click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 114
114:     def self.trust_anchors
115:       return @@anchor_verifier.trust_anchors
116:     end
validate(msg) click to toggle source

Returns true for secure/insecure, false otherwise This method will set the security_level on msg to the appropriate value. Could be : secure, insecure, bogus or indeterminate If an error is encountered during verification, then the thrown exception will define the error.

     # File lib/Dnsruby/dnssec.rb, line 176
176:     def self.validate(msg)
177:       query = Message.new()
178:       query.header.cd=true
179:       return self.validate_with_query(query, msg)
180:     end
validate_with_anchors(msg, query) click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 265
265:     def self.validate_with_anchors(msg, query)
266:       return @@anchor_verifier.validate(msg, query)
267:     end
validate_with_dlv(msg, query) click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 273
273:     def self.validate_with_dlv(msg, query)
274:       return @@dlv_verifier.validate(msg, query)
275:     end
validate_with_query(query, msg) click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 182
182:     def self.validate_with_query(query, msg)
183:       if (!msg)
184:         return false
185:       end
186:       # First, just check there is something to validate!
187:       found_sigs = false
188:       msg.each_resource {|rr|
189:         if (rr.type == Types::RRSIG)
190:           found_sigs = true
191:         end
192:       }
193:       if (found_sigs)
194:         begin
195:           if (verify(msg))
196:             msg.security_level = Message::SecurityLevel.SECURE
197:             return true
198:           end
199:         rescue VerifyError => e
200:           msg.security_error = e
201:         end
202:       end
203: 
204:       # SHOULD ALWAYS VERIFY DNSSEC-SIGNED RESPONSES?
205:       # Yes - if a trust anchor is configured. Otherwise, act on CD bit (in query)
206:       TheLog.debug("Checking whether to validate, query.cd = #{query.header.cd}")
207:       if (((@@validation_policy > ValidationPolicy::ALWAYS_ROOT_ONLY) && (self.trust_anchors().length > 0)) ||
208:             # Check query here, and validate if CD is true
209:           (query.header.cd == true))
210:         TheLog.debug("Starting validation")
211: 
212:         # Validate!
213:         # Need to think about trapping/storing exceptions and security_levels here
214:         last_error = ""
215:         last_level = Message::SecurityLevel.BOGUS
216:         last_error_level = Message::SecurityLevel.BOGUS
217:         if (@@validation_policy == ValidationPolicy::ALWAYS_LOCAL_ANCHORS_ONLY)
218:           last_level, last_error, last_error_level = try_validation(last_level, last_error, last_error_level,
219:             Proc.new{|m, q| validate_with_anchors(m, q)}, msg, query)
220:         elsif (@@validation_policy == ValidationPolicy::ALWAYS_ROOT_ONLY)
221:           last_level, last_error, last_error_level = try_validation(last_level, last_error, last_error_level,
222:             Proc.new{|m, q| validate_with_root(m, q)}, msg, query)
223:         elsif (@@validation_policy == ValidationPolicy::LOCAL_ANCHORS_THEN_ROOT)
224:           last_level, last_error, last_error_level = try_validation(last_level, last_error, last_error_level, 
225:             Proc.new{|m, q| validate_with_anchors(m, q)}, msg, query)
226:           if (last_level != Message::SecurityLevel.SECURE)
227:             last_level, last_error, last_error_level = try_validation(last_level, last_error, last_error_level,
228:               Proc.new{|m, q| validate_with_root(m, q)}, msg, query)
229:           end
230:         elsif (@@validation_policy == ValidationPolicy::ROOT_THEN_LOCAL_ANCHORS)
231:           last_level, last_error, last_error_level = try_validation(last_level, last_error, last_error_level,
232:             Proc.new{|m, q| validate_with_root(m, q)}, msg, query)
233:           if (last_level != Message::SecurityLevel.SECURE)
234:             last_level, last_error, last_error_level = try_validation(last_level, last_error, last_error_level,
235:               Proc.new{|m, q| validate_with_anchors(m, q)}, msg, query)
236:           end
237:         end
238:         if (last_level != Message::SecurityLevel.SECURE)
239:           last_level, last_error, last_error_level = try_validation(last_level, last_error, last_error_level, 
240:             Proc.new{|m, q| validate_with_dlv(m, q)}, msg, query)
241:         end
242:         # Set the message security level!
243:         msg.security_level = last_level
244:         msg.security_error = last_error
245:         raise VerifyError.new(last_error) if (last_level < 0)
246:         return (msg.security_level.code > Message::SecurityLevel::UNCHECKED)
247:       end
248:       msg.security_level = Message::SecurityLevel.UNCHECKED
249:       return true
250:     end
validate_with_root(msg, query) click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 269
269:     def self.validate_with_root(msg, query)
270:       return @@root_verifier.validate(msg, query)
271:     end
validation_policy() click to toggle source
    # File lib/Dnsruby/dnssec.rb, line 74
74:     def Dnssec.validation_policy
75:       @@validation_policy
76:     end
validation_policy=(p) click to toggle source
    # File lib/Dnsruby/dnssec.rb, line 68
68:     def Dnssec.validation_policy=(p)
69:       if ((p >= ALWAYS_ROOT_ONY) && (p <= ALWAYS_LOCAL_ANCHORS))
70:         @@validation_policy = p
71:         # @TODO@ Should we be clearing the trusted keys now?
72:       end
73:     end
verify(msg, keys=nil) click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 277
277:     def self.verify(msg, keys=nil)
278:       begin
279:         return true if @@anchor_verifier.verify(msg, keys=nil)
280:       rescue VerifyError
281:         begin
282:           return true if @@root_verifier.verify(msg, keys=nil)
283:         rescue VerifyError
284:           return true if @@dlv_verifier.verify(msg, keys=nil) # Will carry error to client
285:         end
286:       end
287:     end
verify_rrset(rrset, keys = nil) click to toggle source
     # File lib/Dnsruby/dnssec.rb, line 302
302:     def self.verify_rrset(rrset, keys = nil)
303:       return ((@@anchor_verifier.verify_rrset(rrset, keys) ||
304:             @@root_verifier.verify_rrset(rrset, keys) ||
305:             @@dlv_verifier.verify_rrset(rrset, keys)))
306:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.