lib/fernet/verifier.rb in fernet-1.6 vs lib/fernet/verifier.rb in fernet-2.0.rc1

- old
+ new

@@ -1,102 +1,74 @@ +#encoding UTF-8 require 'base64' -require 'yajl' require 'openssl' require 'date' module Fernet class Verifier - attr_reader :token, :data + class UnknownTokenVersion < RuntimeError; end + + attr_reader :token attr_accessor :ttl, :enforce_ttl - def initialize(secret, decrypt) - @secret = Secret.new(secret, decrypt) - @decrypt = decrypt - @ttl = Configuration.ttl - @enforce_ttl = Configuration.enforce_ttl + def initialize(opts = {}) + enforce_ttl = opts.has_key?(:enforce_ttl) ? opts[:enforce_ttl] : Configuration.enforce_ttl + @token = Token.new(opts.fetch(:token), + enforce_ttl: enforce_ttl, + ttl: opts[:ttl], + now: opts[:now]) + @token.secret = opts.fetch(:secret) end - def verify_token(token) - @token = token - deconstruct + def valid? + @token.valid? + end - if block_given? - custom_verification = yield self - else - custom_verification = true - end - - @valid = signatures_match? && token_recent_enough? && custom_verification + def message + @token.message end - def valid? - @valid + def data + puts "[WARNING] data is deprected. Use message instead" + message end def inspect - "#<Fernet::Verifier @secret=[masked] @token=#{@token} @data=#{@data.inspect} @ttl=#{@ttl}>" + "#<Fernet::Verifier @secret=[masked] @token=#{@token} @message=#{@message.inspect} @ttl=#{@ttl} @enforce_ttl=#{@enforce_ttl}>" end alias to_s inspect private - attr_reader :secret - - def deconstruct - parts = @token.split('|') - if decrypt? - encrypted_data, iv, @received_signature = *parts - @data = Yajl::Parser.parse(decrypt!(encrypted_data, Base64.urlsafe_decode64(iv))) - signing_blob = "#{encrypted_data}|#{iv}" - else - encoded_data, @received_signature = *parts - signing_blob = encoded_data - @data = Yajl::Parser.parse(Base64.urlsafe_decode64(encoded_data)) - end - @regenerated_mac = OpenSSL::HMAC.hexdigest('sha256', signing_blob, signing_key) + def must_verify? + @must_verify || @valid.nil? end def token_recent_enough? if enforce_ttl? - good_till = DateTime.parse(data['issued_at']) + (ttl.to_f / 24 / 60 / 60) - good_till > now + good_till = @issued_at + (ttl.to_f / 24 / 60 / 60) + (good_till.to_i >= now.to_i) && acceptable_clock_skew? else true end end + def acceptable_clock_skew? + @issued_at < (now + MAX_CLOCK_SKEW) + end + def signatures_match? regenerated_bytes = @regenerated_mac.bytes.to_a received_bytes = @received_signature.bytes.to_a received_bytes.inject(0) do |accum, byte| accum |= byte ^ regenerated_bytes.shift end.zero? end - def decrypt!(encrypted_data, iv) - decipher = OpenSSL::Cipher.new('AES-128-CBC') - decipher.decrypt - decipher.iv = iv - decipher.key = encryption_key - decipher.update(Base64.urlsafe_decode64(encrypted_data)) + decipher.final - end - - def encryption_key - @secret.encryption_key - end - - def signing_key - @secret.signing_key - end - - def decrypt? - @decrypt - end - def enforce_ttl? @enforce_ttl end def now - DateTime.now + @now ||= Time.now end end end