Module: HmacAuthentication

Defined in:
lib/hmac_authentication/version.rb,
lib/hmac_authentication/signature.rb

Constant Summary collapse

VERSION =
'0.0.0'
NO_SIGNATURE =
1
INVALID_FORMAT =
2
UNSUPPORTED_ALGORITHM =
3
MATCH =
4
MISMATCH =
5

Class Method Summary collapse

Class Method Details

.parse_digest(name) ⇒ Object



27
28
29
30
31
# File 'lib/hmac_authentication/signature.rb', line 27

def self.parse_digest(name)
  OpenSSL::Digest.new name
rescue
  nil
end

.request_signature(request, digest, headers, secret_key) ⇒ Object



21
22
23
24
25
# File 'lib/hmac_authentication/signature.rb', line 21

def self.request_signature(request, digest, headers, secret_key)
  hmac = OpenSSL::HMAC.new secret_key, digest
  hmac << string_to_sign(request, headers) << (request.body || '')
  digest.name.downcase + ' ' + Base64.strict_encode64(hmac.digest)
end

.signed_headers(request, headers) ⇒ Object



11
12
13
# File 'lib/hmac_authentication/signature.rb', line 11

def self.signed_headers(request, headers)
  headers.map { |name| request[name] || '' }
end

.string_to_sign(req, headers) ⇒ Object



15
16
17
18
19
# File 'lib/hmac_authentication/signature.rb', line 15

def self.string_to_sign(req, headers)
  # TODO(mbland): Test for paths of the form 'http://foo.com/bar?baz'
  [req.method, signed_headers(req, headers).join("\n"), req.uri.path]
    .join("\n")
end

.validate_request(request, headers, secret_key) ⇒ Object



33
34
35
36
37
38
39
40
41
42
# File 'lib/hmac_authentication/signature.rb', line 33

def self.validate_request(request, headers, secret_key)
  header = request['Gap-Signature']
  return NO_SIGNATURE unless header
  components = header.split ' '
  return INVALID_FORMAT, header unless components.size == 2
  digest = parse_digest components.first
  return UNSUPPORTED_ALGORITHM, header unless digest
  computed = request_signature(request, digest, headers, secret_key)
  [(header == computed) ? MATCH : MISMATCH, header, computed]
end