def verify_envelope(response, response_bytes)
if (!@buf)
@num_envelopes = 0
@last_signed = 0
end
@num_envelopes += 1
if (!response.tsig)
if ((@num_envelopes > 1) && (@num_envelopes - @last_signed < 100))
TheLog.debug("Receiving intermediate envelope in TSIG TCP session")
response.tsigstate = :Intermediate
response.tsigerror = RCode.NOERROR
@buf = @buf + response_bytes
return
else
response.tsigstate = :Failed
TheLog.error("Expecting signed packet")
return false
end
end
@last_signed = @num_envelopes
tsig = response.tsig
if (@num_envelopes == 1)
TheLog.debug("First response in TSIG TCP session - verifying normally")
ok = verify(@query, response, response_bytes)
if (ok)
mac_bytes = MessageEncoder.new {|m|
m.put_pack('n', tsig.mac_size)
m.put_bytes(tsig.mac)
}.to_s
@buf = mac_bytes
else
end
return ok
end
TheLog.debug("Processing TSIG on TSIG TCP session")
if (!verify_common(response))
return false
end
response_bytes = Header.decrement_arcount_encoded(response_bytes)
@buf += response_bytes[0, response.tsigstart]
timers_data = MessageEncoder.new { |msg|
time_high = (tsig.time_signed >> 32)
time_low = (tsig.time_signed & 0xFFFFFFFF)
msg.put_pack('nN', time_high, time_low)
msg.put_pack('n', tsig.fudge)
}.to_s
@buf += timers_data
mac = nil
key = @key.gsub(" ", "")
key = Base64::decode64(key)
if (tsig.algorithm == HMAC_MD5)
mac = OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, @buf)
elsif (tsig.algorithm == HMAC_SHA1)
mac = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, key, @buf)
elsif (tsig.algorithm == HMAC_SHA256)
mac = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, key, @buf)
else
raise RuntimeError.new("Algorithm #{tsig.algorithm} unsupported by TSIG")
end
if (mac != tsig.mac)
TheLog.error("TSIG Verify error on TSIG TCP session")
response.tsigstate = :Failed
return false
end
mac_bytes = MessageEncoder.new {|m|
m.put_pack('n', mac.length)
m.put_bytes(mac)
}.to_s
@buf=mac_bytes
response.tsigstate = :Verified
response.tsigerror = RCode.NOERROR
return true
end