rotp 1.4.5 → 1.4.6

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: 53b1578ba5f12cd83cf8e616619b34d9f0135677
4
- data.tar.gz: 2102035657efa48f1b85c621db30d68563a77b87
3
+ metadata.gz: e9938a2125556d7dcd7b8eae64d58d28e90a6d0f
4
+ data.tar.gz: 053694aa169605804930a516e41294e3b78b0fe4
5
5
  SHA512:
6
- metadata.gz: 05a24b43f5622b2464cc174ba23cea19efe112ad838a8c9c9bdd05d31c6ac3e8e235b6ef550e38dd239569a25622e278887617eb39ecb83ebaa803848cf41108
7
- data.tar.gz: c26363a86a528d49d672aed06ebc9c8852eb27aa53d93c5c4dc50c75a5a8e823b93c373ddc34845972734a86a4bad594ef342da6b354f56cdd1cafa572dca48a
6
+ metadata.gz: 62890466fe02ab700ce21c7f882a6f25fddeb9e35b0bd51ef5bd9567ae4a1decea947dc729c74852d8e0f471474686ac4fdad08f6c51600e83b1abb8608f8464
7
+ data.tar.gz: fedda9e325a1e7513907ee8a1b2314a97b0fb55e1c6f848fc122f73031473dfad630220a943ba27af700f7eeb2418d0d0951d42f488cee2839ccebf8ab6fa609
@@ -1,8 +1,8 @@
1
+ require 'rotp/base32'
1
2
  require 'rotp/otp'
2
3
  require 'rotp/hotp'
3
4
  require 'rotp/totp'
4
5
  require 'uri'
5
- require 'base32'
6
6
  require 'openssl'
7
7
 
8
8
  module ROTP
@@ -0,0 +1,48 @@
1
+ module ROTP
2
+ class Base32
3
+ CHARS = "abcdefghijklmnopqrstuvwxyz234567".each_char.to_a
4
+
5
+ class << self
6
+ def decode(str)
7
+ output = []
8
+ str.scan(/.{1,8}/).each do |block|
9
+ char_array = decode_block(block).map{|c| c.chr}
10
+ output << char_array
11
+ end
12
+ output.join
13
+ end
14
+
15
+ def random_base32(length=16)
16
+ b32 = ''
17
+ OpenSSL::Random.random_bytes(length).each_byte do |b|
18
+ b32 << CHARS[b % 32]
19
+ end
20
+ b32
21
+ end
22
+
23
+ private
24
+
25
+ def decode_block(block)
26
+ length = block.scan(/[^=]/).length
27
+ quints = block.each_char.map {|c| decode_quint(c)}
28
+ bytes = []
29
+ bytes[0] = (quints[0] << 3) + (quints[1] ? quints[1] >> 2 : 0)
30
+ return bytes if length < 3
31
+ bytes[1] = ((quints[1] & 3) << 6) + (quints[2] << 1) + (quints[3] ? quints[3] >> 4 : 0)
32
+ return bytes if length < 4
33
+ bytes[2] = ((quints[3] & 15) << 4) + (quints[4] ? quints[4] >> 1 : 0)
34
+ return bytes if length < 6
35
+ bytes[3] = ((quints[4] & 1) << 7) + (quints[5] << 2) + (quints[6] ? quints[6] >> 3 : 0)
36
+ return bytes if length < 7
37
+ bytes[4] = ((quints[6] & 7) << 5) + (quints[7] || 0)
38
+ bytes
39
+ end
40
+
41
+ def decode_quint(q)
42
+ CHARS.index(q.downcase)
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
@@ -46,7 +46,7 @@ module ROTP
46
46
  end
47
47
 
48
48
  def byte_secret
49
- Base32.decode(@secret.upcase)
49
+ Base32.decode(@secret)
50
50
  end
51
51
 
52
52
  # Turns an integer to the OATH specified
@@ -1,3 +1,3 @@
1
1
  module ROTP
2
- VERSION = "1.4.5"
2
+ VERSION = "1.4.6"
3
3
  end
@@ -20,7 +20,6 @@ Gem::Specification.new do |s|
20
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
21
  s.require_paths = ["lib"]
22
22
 
23
- s.add_dependency('base32', '~> 0.2.0')
24
23
  s.add_development_dependency('rake')
25
24
  s.add_development_dependency('rspec')
26
25
  if RUBY_VERSION < "1.9"
@@ -1,5 +1,26 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
+ describe "the Base32 implementation" do
4
+ it "should be 16 characters by default" do
5
+ ROTP::Base32.random_base32.length.should == 16
6
+ ROTP::Base32.random_base32.should match /\A[a-z2-7]+\z/
7
+ end
8
+ it "should be allow a specific length" do
9
+ ROTP::Base32.random_base32(32).length.should == 32
10
+ end
11
+ it "should correctly decode a string" do
12
+ ROTP::Base32.decode("F").unpack('H*').first.should == "28"
13
+ ROTP::Base32.decode("23").unpack('H*').first.should == "d6"
14
+ ROTP::Base32.decode("234").unpack('H*').first.should == "d6f8"
15
+ ROTP::Base32.decode("234A").unpack('H*').first.should == "d6f800"
16
+ ROTP::Base32.decode("234B").unpack('H*').first.should == "d6f810"
17
+ ROTP::Base32.decode("234BCD").unpack('H*').first.should == "d6f8110c"
18
+ ROTP::Base32.decode("234BCDE").unpack('H*').first.should == "d6f8110c80"
19
+ ROTP::Base32.decode("234BCDEFG").unpack('H*').first.should == "d6f8110c8530"
20
+ ROTP::Base32.decode("234BCDEFG234BCDEFG").unpack('H*').first.should == "d6f8110c8536b7c0886429"
21
+ end
22
+ end
23
+
3
24
  describe "HOTP example values from the rfc" do
4
25
  it "should match the RFC" do
5
26
  # 12345678901234567890 in Bas32
@@ -57,6 +78,7 @@ describe "TOTP example values from the rfc" do
57
78
  end
58
79
  end
59
80
 
81
+
60
82
  it "should output its provisioning URI" do
61
83
  totp = ROTP::TOTP.new("wrn3pqx5uqxqvnqr")
62
84
  totp.provisioning_uri('mark@percival').should == "otpauth://totp/mark@percival?secret=wrn3pqx5uqxqvnqr"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rotp
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.5
4
+ version: 1.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Percival
@@ -10,20 +10,6 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2013-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: base32
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ~>
18
- - !ruby/object:Gem::Version
19
- version: 0.2.0
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ~>
25
- - !ruby/object:Gem::Version
26
- version: 0.2.0
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rake
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -99,6 +85,7 @@ files:
99
85
  - doc/method_list.html
100
86
  - doc/top-level-namespace.html
101
87
  - lib/rotp.rb
88
+ - lib/rotp/base32.rb
102
89
  - lib/rotp/hotp.rb
103
90
  - lib/rotp/otp.rb
104
91
  - lib/rotp/totp.rb