Class: RightSupport::Crypto::SignedHash

Inherits:
Object
  • Object
show all
Defined in:
lib/right_support/crypto/signed_hash.rb

Constant Summary collapse

DefaultEncoding =
nil
DEFAULT_OPTIONS =
{
  :digest   => Digest::SHA1,
  :encoding => DefaultEncoding
}

Instance Method Summary collapse

Constructor Details

#initialize(hash = {}, options = {}) ⇒ SignedHash

Returns a new instance of SignedHash.



21
22
23
24
25
26
27
28
29
# File 'lib/right_support/crypto/signed_hash.rb', line 21

def initialize(hash={}, options={})
  options = DEFAULT_OPTIONS.merge(options)
  @hash        = hash
  @digest      = options[:digest]
  @encoding    = options[:encoding]
  @public_key  = options[:public_key]
  @private_key = options[:private_key]
  duck_type_check
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args) ⇒ Object



56
57
58
# File 'lib/right_support/crypto/signed_hash.rb', line 56

def method_missing(meth, *args)
  @hash.__send__(meth, *args)
end

Instance Method Details

#sign(expires_at) ⇒ Object

Raises:

  • (ArgumentError)


31
32
33
34
35
36
37
# File 'lib/right_support/crypto/signed_hash.rb', line 31

def sign(expires_at)
  raise ArgumentError, "Cannot sign; missing private_key" unless @private_key
  raise ArgumentError, "expires_at must be a Time in the future" unless time_check(expires_at)

   = {:expires_at => expires_at}
  @private_key.private_encrypt( digest( encode( canonicalize( frame(@hash, ) ) ) ) )
end

#verify(signature, expires_at) ⇒ Object



49
50
51
52
53
54
# File 'lib/right_support/crypto/signed_hash.rb', line 49

def verify(signature, expires_at)
  verify!(signature, expires_at)
  true
rescue Exception => e
  false
end

#verify!(signature, expires_at) ⇒ Object

Raises:

  • (ArgumentError)


39
40
41
42
43
44
45
46
47
# File 'lib/right_support/crypto/signed_hash.rb', line 39

def verify!(signature, expires_at)
  raise ArgumentError, "Cannot verify; missing public_key" unless @public_key

   = {:expires_at => expires_at}
  expected = digest( encode( canonicalize( frame(@hash, ) ) ) )
  actual = @public_key.public_decrypt(signature)
  raise SecurityError, "Signature mismatch: expected #{expected}, got #{actual}" unless actual == expected
  raise SecurityError, "The signature has expired (or expires_at is not a Time)" unless time_check(expires_at)
end