rotp 1.4.5 → 1.4.6

Sign up to get free protection for your applications and to get access to all the features.
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