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