time_sensitive_hmac 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .rspec
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in time_sensitive_hmac.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2013 Rob Howard
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # TimeSensitiveHmac
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'time_sensitive_hmac'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install time_sensitive_hmac
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rspec/core/rake_task"
4
+ RSpec::Core::RakeTask.new('spec')
5
+ task :test => :spec
@@ -0,0 +1,6 @@
1
+ require "time_sensitive_hmac/version"
2
+ require "time_sensitive_hmac/signature"
3
+
4
+ module TimeSensitiveHmac
5
+
6
+ end
@@ -0,0 +1,55 @@
1
+ require 'base64'
2
+ require 'openssl'
3
+
4
+ module TimeSensitiveHmac
5
+ class Signature
6
+
7
+ attr_reader :secret, :digest
8
+
9
+ def initialize(secret, opts={})
10
+ @secret = secret
11
+ @digest = OpenSSL::Digest::Digest.new(
12
+ opts[:digest] || 'sha256'
13
+ )
14
+ end
15
+
16
+ def generate(time, data, context=nil)
17
+ raw = OpenSSL::HMAC.digest(
18
+ digest,
19
+ secret,
20
+ data_from_parts(time, context, data)
21
+ )
22
+ encode(raw)
23
+ end
24
+
25
+ def verify(sig, time, data, context=nil, grace_period_in_seconds=0)
26
+ # TODO: grace period
27
+ # Take inspiration from HOTP (RFC 4226) for time intervals:
28
+ # http://tools.ietf.org/html/rfc4226#page-35
29
+ check_sig = generate(time, data, context)
30
+ sig == check_sig
31
+ end
32
+
33
+ def verify_now(sig, data, context=nil, grace_period_in_seconds=0)
34
+ verify(sig, Time.now, context, grace_period_in_seconds)
35
+ end
36
+
37
+ protected
38
+
39
+ def encode(input)
40
+ # encode64 includes a trailing \n.
41
+ input && Base64.encode64(input).strip
42
+ end
43
+
44
+ def data_from_parts(time, context, data)
45
+ [time.utc.to_i, encode(context), encode(data)].compact.join(':')
46
+ end
47
+
48
+ def normalise_to_time_class(time)
49
+ unless time.is_a? Time
50
+ time = Time.at(time.to_i)
51
+ end
52
+ time
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module TimeSensitiveHmac
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'bundler/setup'
2
+ require 'time_sensitive_hmac'
3
+
4
+ RSpec.configure do |config|
5
+ # ...
6
+ end
7
+
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe TimeSensitiveHmac do
4
+ let(:secret) { 'abcd' * 8 }
5
+
6
+ context "instantiating" do
7
+ it "defaults to SHA256" do
8
+ sig = TimeSensitiveHmac::Signature.new(secret)
9
+ sig.digest.name.should == 'SHA256'
10
+ end
11
+
12
+ it "accepts any valid OpenSSL::Digest type" do
13
+ sig = TimeSensitiveHmac::Signature.new(secret, :digest => 'sha1')
14
+ sig.digest.name.should == 'SHA1'
15
+ end
16
+
17
+ it "assumes OpenSSL will reject default digest types" do
18
+ -> {
19
+ TimeSensitiveHmac::Signature.new(secret, :digest => 'sha666')
20
+ }.should raise_error(RuntimeError)
21
+ end
22
+ end
23
+
24
+ context "generating" do
25
+ let!(:now) { Time.utc(2013,1,1) }
26
+ let(:signature) { TimeSensitiveHmac::Signature.new(secret) }
27
+
28
+ it "generates with a time and data chunk" do
29
+ digest = signature.generate(now, '{"sample"=>"data"}')
30
+ digest.should == 'qDdAbSFV3/oDpmD10L0LySWZugYbzbCKxyZ7Z9Nd0RY='
31
+ end
32
+
33
+ it "generates with time, data, and a URL path context" do
34
+ digest = signature.generate(
35
+ now,
36
+ '{"sample"=>"data"}',
37
+ '/path/with?query=string'
38
+ )
39
+ digest.should == 'Wq+9pR/thhyUz0rTFHj4CxGQPGT271ZEJMdDSMPeucg='
40
+ end
41
+ end
42
+
43
+ context "verification at exact moments" do
44
+ pending "verifies signatures with valid data"
45
+ pending "verifies signatures with a valid data and context pair"
46
+ pending "fails invalid signatures"
47
+ end
48
+
49
+ context "verification with grace period" do
50
+ pending "verifies signatures with valid data"
51
+ pending "verifies signatures with a valid data and context pair"
52
+ pending "fails invalid signatures"
53
+ pending "fails valid signatures outside of the grace period"
54
+ end
55
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'time_sensitive_hmac/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "time_sensitive_hmac"
8
+ spec.version = TimeSensitiveHmac::VERSION
9
+ spec.authors = ["Rob Howard"]
10
+ spec.email = ["rob@robhoward.id.au"]
11
+ spec.description = %q{A tiny library for calculation and verification of HMAC signatures bound to a particular time.}
12
+ spec.summary = spec.description
13
+ spec.homepage = ""
14
+ spec.license = "Apache 2.0"
15
+
16
+ spec.required_ruby_version = '>= 1.9.2'
17
+
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
26
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: time_sensitive_hmac
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rob Howard
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: A tiny library for calculation and verification of HMAC signatures bound
63
+ to a particular time.
64
+ email:
65
+ - rob@robhoward.id.au
66
+ executables: []
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - Gemfile
72
+ - LICENSE.txt
73
+ - README.md
74
+ - Rakefile
75
+ - lib/time_sensitive_hmac.rb
76
+ - lib/time_sensitive_hmac/signature.rb
77
+ - lib/time_sensitive_hmac/version.rb
78
+ - spec/spec_helper.rb
79
+ - spec/time_sensitive_hmac_spec.rb
80
+ - time_sensitive_hmac.gemspec
81
+ homepage: ''
82
+ licenses:
83
+ - Apache 2.0
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.9.2
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ segments:
101
+ - 0
102
+ hash: 433686917233539613
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 1.8.23
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: A tiny library for calculation and verification of HMAC signatures bound
109
+ to a particular time.
110
+ test_files:
111
+ - spec/spec_helper.rb
112
+ - spec/time_sensitive_hmac_spec.rb