yubioath 1.1.0 → 1.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45db1b97a74e59b31a8b0070d1722b18d548bb20
4
- data.tar.gz: 81ea24c84fac5bf8d48d79a9c2a01939f234d305
3
+ metadata.gz: f65371dc5c676a809ec0481fee24ed3b044acb12
4
+ data.tar.gz: b44a22b1b0e222ddd183d8dc76fbf9acaad74438
5
5
  SHA512:
6
- metadata.gz: 37e6029de7cf3bde37755f1a7ab9d52a343ff3bddddb0160e3dccd4b2e6cf3d51d8b5cfacb61b0232c1ba7393ec61570033c989e234b7ef368c125f6f3551f92
7
- data.tar.gz: 50f79cc8c96e6a53c199351b8c941f713dfc4afa52794aad6fd01cde1428cc4d8bde2c7bca58ee5a01e025e23922aa8e92e0320426239926fb0b27d9e0c1cf99
6
+ metadata.gz: ad49ada87e761639a55ae16752b476f68e636dd928409b751fdc9fe7dbe764d7f98493d56d2c149ae6e01bb0f4cb0ffe2b6d3e78210be69a678a22e78f54c580
7
+ data.tar.gz: 31d59e657ca027f7c315a3ea54202378e04479759a709f049228b4b4da5e00cad62ce42293aeb4d9e6bbe971d500f642c4e1bd5bc09cc3f7bd164004c367bfa3
data/Gemfile CHANGED
@@ -3,15 +3,9 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in yubioath.gemspec
4
4
  gemspec
5
5
 
6
- group :development do
7
- gem 'bundler'
8
- gem 'rake'
9
- gem 'rubocop'
10
- end
11
-
12
- group :test do
13
- gem 'rspec', '~> 3.3'
14
- gem 'rspec-its', '~> 1.2'
15
- gem 'rspec-the', '~> 1.0'
16
- gem 'smartcard', '~> 0.5.6'
17
- end
6
+ gem 'bundler', '~> 1.12'
7
+ gem 'rake', '~> 10.5'
8
+ gem 'rspec', '~> 3.3'
9
+ gem 'rspec-its', '~> 1.2'
10
+ gem 'rspec-the', '~> 1.0'
11
+ gem 'smartcard', '~> 0.5.6'
data/LICENSE.markdown CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015, James Ottaway
3
+ Copyright (c) 2016, James Ottaway
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -4,58 +4,49 @@ A mostly-complete Ruby implementation of the [YubiOATH applet protocol](https://
4
4
 
5
5
  ## Usage
6
6
 
7
- The `YubiOATH` class accepts a `card`, which must respond to `#transmit(apdu)`.
8
-
9
- You probably want to use [costan/smartcard](https://github.com/costan/smartcard).
10
-
11
- ```ruby
12
- yubioath = YubiOATH.new(card)
13
- ```
14
-
15
- ### Calculate
16
-
17
- Do calculate for one named code.
7
+ The `YubiOATH` class accepts a `card`, which must respond to `#transmit(apdu)`. See [costan/smartcard](https://github.com/costan/smartcard) for more info.
18
8
 
19
9
  ``` ruby
20
- yubioath.calculate(name: 'foo', timestamp: Time.now) # => '237893'
21
- ```
22
-
23
- ### Calculate All
24
-
25
- Do calculation for all available codes.
26
-
27
- ``` ruby
28
- yubioath.calculate_all(timestamp: Time.now) # => { 'foo' => '576238', 'bar' => '123895' }
29
- ```
30
-
31
- ### Delete
32
-
33
- Deletes an existing code.
34
-
35
- ``` ruby
36
- yubioath.delete(name: 'foo') # => true
37
- ```
38
-
39
- ### List
10
+ yubioath = YubiOATH.new(card)
40
11
 
41
- List configured codes.
12
+ yubioath.put(name: 'foo', secret: '123456') # => true
13
+ yubioath.calculate(name: 'foo', timestamp: Time.now) # => '237846'
42
14
 
43
- ``` ruby
44
- yubioath.list # => { 'foo' => { type: :totp, algorithm: :sha256 } }
45
- ```
15
+ yubioath.put(name: 'bar', secret: '345678') # => true
16
+ yubioath.put(name: 'qux', secret: '567890') # => true
17
+ yubioath.list.keys # => ['foo', 'bar', 'qux']
18
+ yubioath.calculate_all(timestamp: Time.now) # => {'foo' => '234526', 'bar' => '293857', 'qux' => '934856'}
46
19
 
47
- ### Put
20
+ yubioath.delete('qux') # => true
21
+ yubioath.list.keys # => ['foo', 'bar']
48
22
 
49
- Adds a new (or overwrites) OATH code.
50
-
51
- ``` ruby
52
- yubioath.put(name: 'foo', secret: 'bar', …) # => true
23
+ yubioath.reset # => true
24
+ yubioath.list.empty? # => true
53
25
  ```
54
26
 
55
- ### Reset
27
+ ### Instructions
56
28
 
57
- Reset the applet to just-installed state.
29
+ You can also trigger the instructions by instantiating the relevant class with a `card` and invoking its `#call` method.
58
30
 
59
31
  ``` ruby
60
- yubioath.reset # => true
32
+ calculate = YubiOATH::Calculate.new(card)
33
+ calculate_all = YubiOATH::CalculateAll.new(card)
34
+ delete = YubiOATH::Delete.new(card)
35
+ list = YubiOATH::List.new(card)
36
+ put = YubiOATH::Put.new(card)
37
+ reset = YubiOATH::Reset.new(card)
38
+
39
+ put.call(name: 'foo', secret: '123456') # => true
40
+ calculate.call(name: 'foo', timestamp: Time.now) # => '237846'
41
+
42
+ put.call(name: 'bar', secret: '345678') # => true
43
+ put.call(name: 'qux', secret: '567890') # => true
44
+ list.call.keys # => ['foo', 'bar', 'qux']
45
+ calculate_all.call(timestamp: Time.now) # => {'foo' => '234526', 'bar' => '293857', 'qux' => '934856'}
46
+
47
+ delete.call('qux') # => true
48
+ list.call.keys # => ['foo', 'bar']
49
+
50
+ reset.call # => true
51
+ list.call.empty? # => true
61
52
  ```
data/lib/yubioath.rb CHANGED
@@ -1,77 +1,40 @@
1
- require 'bindata'
2
- require 'yubioath/instructions'
3
- require 'yubioath/response'
1
+ require 'yubioath/calculate'
2
+ require 'yubioath/calculate_all'
3
+ require 'yubioath/delete'
4
+ require 'yubioath/list'
5
+ require 'yubioath/put'
6
+ require 'yubioath/reset'
7
+ require 'yubioath/select'
4
8
 
5
9
  class YubiOATH
6
10
  AID = [0xA0, 0x00, 0x00, 0x05, 0x27, 0x21, 0x01, 0x01]
7
- ALGORITHMS = { SHA1: 0x1, SHA256: 0x2 }
8
- TYPES = { HOTP: 0x1, TOTP: 0x2 }
9
-
10
- RequestFailed = Class.new(StandardError)
11
11
 
12
12
  def initialize(card)
13
13
  @card = card
14
- select(AID)
14
+ Select.new(@card).call(aid: AID)
15
15
  end
16
16
 
17
- def calculate(name:, timestamp: Time.now)
18
- data = Calculate::Request::Data.new(name: name, timestamp: timestamp.to_i / 30)
19
- request = Calculate::Request.new(data: data.to_binary_s)
20
- response = Response.read(@card.transmit(request.to_binary_s))
21
- raise RequestFailed, response unless response.success?
22
- Calculate::Response.read(response.data).code.to_s
17
+ def calculate(name:, timestamp:)
18
+ Calculate.new(@card).call(name: name, timestamp: timestamp)
23
19
  end
24
20
 
25
- def calculate_all(timestamp: Time.now)
26
- data = CalculateAll::Request::Data.new(timestamp: timestamp.to_i / 30)
27
- request = CalculateAll::Request.new(data: data.to_binary_s)
28
- response = Response.read(@card.transmit(request.to_binary_s))
29
- raise RequestFailed, response unless response.success?
30
- CalculateAll::Response.read(response.data)[:codes].map do |code|
31
- [code.name, code.code.to_s]
32
- end.to_h
21
+ def calculate_all(timestamp:)
22
+ CalculateAll.new(@card).call(timestamp: timestamp)
33
23
  end
34
24
 
35
25
  def delete(name:)
36
- data = Delete::Request::Data.new(name: name)
37
- request = Delete::Request.new(data: data.to_binary_s)
38
- Response.read(@card.transmit(request.to_binary_s))
26
+ Delete.new(@card).call(name: name)
39
27
  end
40
28
 
41
29
  def list
42
- request = List::Request.new.to_binary_s
43
- response = Response.read(@card.transmit(request))
44
- raise RequestFailed, response unless response.success?
45
- List::Response.read(response.data)[:codes].map do |code|
46
- [code.name, {
47
- type: TYPES.key(code.type),
48
- algorithm: ALGORITHMS.key(code.algorithm),
49
- }]
50
- end.to_h
30
+ List.new(@card).call
51
31
  end
52
32
 
53
33
  def put(name:, secret:, algorithm: :SHA256, type: :TOTP, digits: 6)
54
- data = Put::Request::Data.new(
55
- name: name,
56
- type: TYPES.fetch(type),
57
- algorithm: ALGORITHMS.fetch(algorithm),
58
- digits: digits,
59
- secret: secret,
60
- )
61
- request = Put::Request.new(data: data.to_binary_s)
62
- Response.read(@card.transmit(request.to_binary_s))
63
- end
64
-
65
- def reset(confirm: false)
66
- Response.read(@card.transmit(Reset::Request.new.to_binary_s)) if confirm
34
+ Put.new(@card).call(name: name, secret: secret, algorithm: algorithm, type: type, digits: digits)
67
35
  end
68
36
 
69
- private
70
-
71
- def select(aid)
72
- request = Select::Request.new(aid: aid).to_binary_s
73
- response = Response.read(@card.transmit(request))
74
- raise RequestFailed, response unless response.success?
75
- Select::Response.read(response.data)
37
+ def reset
38
+ Reset.new(@card).call
76
39
  end
77
40
  end
@@ -0,0 +1,3 @@
1
+ class YubiOATH
2
+ ALGORITHMS = {SHA1: 0x1, SHA256: 0x2}
3
+ end
@@ -2,6 +2,18 @@ require 'bindata'
2
2
 
3
3
  class YubiOATH
4
4
  class Calculate
5
+ def initialize(card)
6
+ @card = card
7
+ end
8
+
9
+ def call(name:, timestamp:)
10
+ data = Request::Data.new(name: name, timestamp: timestamp.to_i / 30)
11
+ request = Request.new(data: data.to_binary_s)
12
+ bytes = @card.transmit(request.to_binary_s)
13
+ response = Response.read(bytes)
14
+ response.code.to_s
15
+ end
16
+
5
17
  class Request < BinData::Record
6
18
  uint8 :cla, value: 0x00
7
19
  uint8 :ins, value: 0xA2
@@ -2,6 +2,21 @@ require 'bindata'
2
2
 
3
3
  class YubiOATH
4
4
  class CalculateAll
5
+ def initialize(card)
6
+ @card = card
7
+ end
8
+
9
+ def call(timestamp:)
10
+ data = Request::Data.new(timestamp: timestamp.to_i / 30)
11
+ request = Request.new(data: data.to_binary_s)
12
+ bytes = @card.transmit(request.to_binary_s)
13
+ response = Response.read(bytes)
14
+
15
+ response[:codes].map do |code|
16
+ [code.name, code.code.to_s]
17
+ end.to_h
18
+ end
19
+
5
20
  class Request < BinData::Record
6
21
  uint8 :cla, value: 0x00
7
22
  uint8 :ins, value: 0xA4
@@ -1,7 +1,19 @@
1
1
  require 'bindata'
2
+ require 'yubioath/response'
2
3
 
3
4
  class YubiOATH
4
5
  class Delete
6
+ def initialize(card)
7
+ @card = card
8
+ end
9
+
10
+ def call(name:)
11
+ data = Request::Data.new(name: name)
12
+ request = Request.new(data: data.to_binary_s)
13
+ bytes = @card.transmit(request.to_binary_s)
14
+ Response.read(bytes).success?
15
+ end
16
+
5
17
  class Request < BinData::Record
6
18
  uint8 :cla, value: 0x00
7
19
  uint8 :ins, value: 0x02
data/lib/yubioath/list.rb CHANGED
@@ -1,7 +1,26 @@
1
1
  require 'bindata'
2
+ require 'yubioath/algorithms'
3
+ require 'yubioath/types'
2
4
 
3
5
  class YubiOATH
4
6
  class List
7
+ def initialize(card)
8
+ @card = card
9
+ end
10
+
11
+ def call
12
+ request = Request.new
13
+ bytes = @card.transmit(request.to_binary_s)
14
+ response = Response.read(bytes)
15
+
16
+ response[:codes].map do |code|
17
+ [code.name, {
18
+ type: TYPES.key(code.type),
19
+ algorithm: ALGORITHMS.key(code.algorithm),
20
+ }]
21
+ end.to_h
22
+ end
23
+
5
24
  class Request < BinData::Record
6
25
  uint8 :cla, value: 0x00
7
26
  uint8 :ins, value: 0xA1
data/lib/yubioath/put.rb CHANGED
@@ -1,7 +1,27 @@
1
1
  require 'bindata'
2
+ require 'yubioath/algorithms'
3
+ require 'yubioath/response'
4
+ require 'yubioath/types'
2
5
 
3
6
  class YubiOATH
4
7
  class Put
8
+ def initialize(card)
9
+ @card = card
10
+ end
11
+
12
+ def call(name:, secret:, algorithm:, type:, digits:)
13
+ data = Request::Data.new(
14
+ name: name,
15
+ type: TYPES.fetch(type),
16
+ algorithm: ALGORITHMS.fetch(algorithm),
17
+ digits: digits,
18
+ secret: secret,
19
+ )
20
+ request = Request.new(data: data.to_binary_s)
21
+ bytes = @card.transmit(request.to_binary_s)
22
+ Response.read(bytes).success?
23
+ end
24
+
5
25
  class Request < BinData::Record
6
26
  uint8 :cla, value: 0x00
7
27
  uint8 :ins, value: 0x01
@@ -1,7 +1,18 @@
1
1
  require 'bindata'
2
+ require 'yubioath/response'
2
3
 
3
4
  class YubiOATH
4
5
  class Reset
6
+ def initialize(card)
7
+ @card = card
8
+ end
9
+
10
+ def call
11
+ request = Reset::Request.new
12
+ bytes = @card.transmit(request.to_binary_s)
13
+ Response.read(bytes).success?
14
+ end
15
+
5
16
  class Request < BinData::Record
6
17
  uint8 :cla, value: 0x00
7
18
  uint8 :ins, value: 0x04
@@ -2,6 +2,16 @@ require 'bindata'
2
2
 
3
3
  class YubiOATH
4
4
  class Select
5
+ def initialize(card)
6
+ @card = card
7
+ end
8
+
9
+ def call(aid:)
10
+ request = Request.new(aid: aid)
11
+ bytes = @card.transmit(request.to_binary_s)
12
+ Response.read(bytes)
13
+ end
14
+
5
15
  class Request < BinData::Record
6
16
  uint8 :cla, value: 0x00
7
17
  uint8 :ins, value: 0xA4
@@ -0,0 +1,3 @@
1
+ class YubiOATH
2
+ TYPES = {HOTP: 0x1, TOTP: 0x2}
3
+ end
data/yubioath.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'yubioath'
7
- spec.version = '1.1.0'
7
+ spec.version = '1.2.0'
8
8
  spec.authors = ['James Ottaway']
9
9
  spec.email = ['yubioath@james.ottaway.io']
10
10
  spec.summary = 'A mostly-complete Ruby implementation of the YubiOATH applet protocol'
@@ -15,5 +15,5 @@ Gem::Specification.new do |spec|
15
15
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
16
16
  spec.require_paths = ['lib']
17
17
 
18
- spec.add_dependency 'bindata', '~> 2.1'
18
+ spec.add_dependency 'bindata', '~> 2.0'
19
19
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yubioath
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Ottaway
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-26 00:00:00.000000000 Z
11
+ date: 2016-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bindata
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.1'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2.1'
26
+ version: '2.0'
27
27
  description:
28
28
  email:
29
29
  - yubioath@james.ottaway.io
@@ -32,25 +32,22 @@ extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
34
  - ".gitignore"
35
- - ".rspec"
36
- - ".rubocop.yml"
37
- - ".rubocop_todo.yml"
38
35
  - ".ruby-version"
39
36
  - Gemfile
40
37
  - LICENSE.markdown
41
- - LICENSE.txt
42
38
  - README.md
43
39
  - Rakefile
44
40
  - lib/yubioath.rb
41
+ - lib/yubioath/algorithms.rb
45
42
  - lib/yubioath/calculate.rb
46
43
  - lib/yubioath/calculate_all.rb
47
44
  - lib/yubioath/delete.rb
48
- - lib/yubioath/instructions.rb
49
45
  - lib/yubioath/list.rb
50
46
  - lib/yubioath/put.rb
51
47
  - lib/yubioath/reset.rb
52
48
  - lib/yubioath/response.rb
53
49
  - lib/yubioath/select.rb
50
+ - lib/yubioath/types.rb
54
51
  - yubioath.gemspec
55
52
  homepage: https://github.com/jamesottaway/yubioath
56
53
  licenses:
@@ -72,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
69
  version: '0'
73
70
  requirements: []
74
71
  rubyforge_project:
75
- rubygems_version: 2.4.5
72
+ rubygems_version: 2.5.1
76
73
  signing_key:
77
74
  specification_version: 4
78
75
  summary: A mostly-complete Ruby implementation of the YubiOATH applet protocol
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,26 +0,0 @@
1
- inherit_from: .rubocop_todo.yml
2
-
3
- AllCops:
4
- Exclude:
5
- - 'yubioath.gemspec'
6
-
7
- Metrics/LineLength:
8
- Enabled: false
9
-
10
- Style/Documentation:
11
- Enabled: false
12
-
13
- Style/SpaceAroundOperators:
14
- Enabled: false
15
-
16
- Style/SpaceInsideHashLiteralBraces:
17
- Enabled: false
18
-
19
- Style/TrailingComma:
20
- EnforcedStyleForMultiline: comma
21
-
22
- Style/BracesAroundHashParameters:
23
- Enabled: false
24
-
25
- Style/IndentHash:
26
- Enabled: false
data/.rubocop_todo.yml DELETED
@@ -1,16 +0,0 @@
1
- # This configuration was generated by `rubocop --auto-gen-config`
2
- # on 2015-07-04 16:09:47 +1000 using RuboCop version 0.29.1.
3
- # The point is for the user to remove these configuration records
4
- # one by one as the offenses are removed from the code base.
5
- # Note that changes in the inspected code, or installation of new
6
- # versions of RuboCop, may require this file to be generated again.
7
-
8
- # Offense count: 2
9
- Metrics/AbcSize:
10
- Max: 19
11
-
12
- # Offense count: 6
13
- # Cop supports --auto-correct.
14
- # Configuration parameters: EnforcedStyle, SupportedStyles.
15
- Style/SignalException:
16
- Enabled: false
data/LICENSE.txt DELETED
@@ -1,22 +0,0 @@
1
- Copyright (c) 2015 James Ottaway
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,7 +0,0 @@
1
- require 'yubioath/calculate'
2
- require 'yubioath/calculate_all'
3
- require 'yubioath/delete'
4
- require 'yubioath/list'
5
- require 'yubioath/put'
6
- require 'yubioath/reset'
7
- require 'yubioath/select'