yubikey 1.1.1 → 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.
@@ -45,6 +45,7 @@ A library to verify, decode, decrypt and parse Yubikey[http://www.yubico.com/hom
45
45
  The MIT License. See LICENSE.
46
46
 
47
47
  === Contributors
48
+ Carl Byström
48
49
  Erik Ruwalder
49
50
 
50
51
  === AES and CRC code
@@ -2,9 +2,11 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  require 'net/http'
5
+ require 'crypt/rijndael'
5
6
  require 'openssl'
6
7
 
7
- require 'yubikey_ext'
8
+ module Yubikey; end;
9
+
8
10
  require 'yubikey/hex'
9
11
  require 'yubikey/modhex'
10
12
  require 'yubikey/otp'
@@ -4,36 +4,26 @@ module Yubikey::ModHex
4
4
 
5
5
  # Decode a ModHex string into binary data
6
6
  def self.decode(modhex_string)
7
- out = ''
8
- flag = true # to switch between first and last nibble
9
- byte = 0
10
-
11
7
  raise ArgumentError, "ModHex string length is not even" unless modhex_string.length % 2 == 0
12
8
 
13
- modhex_string.each_byte do |b|
14
- x = TRANS.index(b.chr) # lookup occurrence in table
15
- if flag
16
- byte = x
17
- else
18
- byte = (byte << 4) | x
19
- out <<= byte.chr
20
- end
21
- flag = !flag
9
+ chars = 'cbdefghijklnrtuv'
10
+ result = ""
11
+ modhex_string.scan(/../).each do |c|
12
+ result += (chars.index(c[0]) * 16 + chars.index(c[1])).chr
22
13
  end
23
-
24
- out
14
+ result
25
15
  end
26
16
 
27
17
  # Encode a binary string into ModHex
28
18
  def self.encode(string)
29
- out = ''
19
+ result = ''
30
20
 
31
21
  string.each_byte do |b|
32
- out <<= TRANS[(b >> 4) & 0xF]
33
- out <<= TRANS[b & 0xF]
22
+ result <<= TRANS[(b >> 4) & 0xF]
23
+ result <<= TRANS[b & 0xF]
34
24
  end
35
25
 
36
- out
26
+ result
37
27
  end
38
28
 
39
29
  end # Yubikey::ModHex
@@ -22,7 +22,7 @@ class Yubikey::OTP
22
22
  # [+otp+] ModHex encoded Yubikey OTP (at least 32 characters)
23
23
  # [+key+] 32-character hex AES key
24
24
  def initialize(otp, key)
25
- raise InvalidOTPError, 'OTP must be at least 32 characters of modhex' unless otp.modhex? && otp.length >= 32
25
+ raise InvalidOTPError, 'OTP must be at least 32 characters of modhex' unless otp.modhex? && otp.length >= 32
26
26
  raise InvalidKeyError, 'Key must be 32 hex characters' unless key.hex? && key.length == 32
27
27
 
28
28
  @public_id = otp[0,otp.length-32] if otp.length > 32
@@ -30,24 +30,27 @@ class Yubikey::OTP
30
30
  @token = Yubikey::ModHex.decode(otp[-32,32])
31
31
  @aes_key = key.to_bin
32
32
 
33
- decrypt
34
- parse
33
+ @token = Crypt::Rijndael.new(@aes_key, 128).decrypt_block(@token)
34
+
35
+ raise BadCRCError unless crc_valid?
36
+
37
+ @secret_id, @insert_counter, @timestamp, @timestamp_lo, @session_counter, @random_number, @crc = @token.unpack('H12vvCCvv')
38
+ @timestamp += @timestamp_lo * 65536
35
39
  end
36
40
 
37
41
  private
38
42
 
39
- def decrypt
40
- @token = Yubikey::AES.decrypt(@token, @aes_key)
41
- end
42
-
43
- def parse
44
- raise BadCRCError unless Yubikey::CRC.valid?(@token)
45
-
46
- @secret_id = @token[0,6].to_hex
47
- @insert_counter = @token[7] * 256 + @token[6]
48
- @timestamp = @token[10] * 65536 + @token[9] * 256 + @token[8]
49
- @session_counter = @token[11]
50
- @random_number = @token[13] * 256 + @token[12]
43
+ def crc_valid?
44
+ crc = 0xffff
45
+ @token.each_byte do |b|
46
+ crc ^= b & 0xff
47
+ 8.times do
48
+ test = (crc & 1) == 1
49
+ crc >>= 1
50
+ crc ^= 0x8408 if test
51
+ end
52
+ end
53
+ crc == 0xf0b8
51
54
  end
52
55
 
53
56
  # :stopdoc:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yubikey
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Rudenberg
@@ -9,27 +9,30 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-04 00:00:00 -04:00
12
+ date: 2009-08-08 00:00:00 -04:00
13
13
  default_executable:
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: crypt
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
16
25
  description: A library to verify, decode, decrypt and parse Yubikey one-time passwords.
17
26
  email: jon335@gmail.com
18
27
  executables: []
19
28
 
20
- extensions:
21
- - ext/yubikey_ext/extconf.rb
29
+ extensions: []
30
+
22
31
  extra_rdoc_files:
23
32
  - LICENSE
24
33
  - README.rdoc
25
- - ext/yubikey_ext/yubikey_ext.c
26
34
  files:
27
35
  - examples/otp.rb
28
- - ext/yubikey_ext/extconf.rb
29
- - ext/yubikey_ext/ykaes.c
30
- - ext/yubikey_ext/ykcrc.c
31
- - ext/yubikey_ext/yubikey.h
32
- - ext/yubikey_ext/yubikey_ext.c
33
36
  - lib/yubikey.rb
34
37
  - lib/yubikey/hex.rb
35
38
  - lib/yubikey/modhex.rb
@@ -38,7 +41,6 @@ files:
38
41
  - spec/hex_spec.rb
39
42
  - spec/spec.opts
40
43
  - spec/spec_helper.rb
41
- - spec/yubikey_ext_spec.rb
42
44
  - spec/yubikey_modhex_spec.rb
43
45
  - spec/yubikey_otp_spec.rb
44
46
  - spec/yubikey_otp_verify_spec.rb
@@ -72,14 +74,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
74
  requirements: []
73
75
 
74
76
  rubyforge_project: yubikey
75
- rubygems_version: 1.3.4
77
+ rubygems_version: 1.3.5
76
78
  signing_key:
77
79
  specification_version: 3
78
80
  summary: A library to verify, decode, decrypt and parse Yubikey one-time passwords.
79
81
  test_files:
80
82
  - spec/hex_spec.rb
81
83
  - spec/spec_helper.rb
82
- - spec/yubikey_ext_spec.rb
83
84
  - spec/yubikey_modhex_spec.rb
84
85
  - spec/yubikey_otp_spec.rb
85
86
  - spec/yubikey_otp_verify_spec.rb
@@ -1,7 +0,0 @@
1
- require 'mkmf'
2
-
3
- dir_config('yubikey_ext')
4
-
5
- have_header('yubikey.h')
6
-
7
- create_makefile('yubikey_ext')
@@ -1,214 +0,0 @@
1
- /* ykaes.c --- Implementation of AES-128.
2
- *
3
- * Copyright (c) 2006, 2007, 2008, 2009 Yubico AB
4
- * All rights reserved.
5
- *
6
- * Redistribution and use in source and binary forms, with or without
7
- * modification, are permitted provided that the following conditions are
8
- * met:
9
- *
10
- * * Redistributions of source code must retain the above copyright
11
- * notice, this list of conditions and the following disclaimer.
12
- *
13
- * * Redistributions in binary form must reproduce the above
14
- * copyright notice, this list of conditions and the following
15
- * disclaimer in the documentation and/or other materials provided
16
- * with the distribution.
17
- *
18
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
- *
30
- */
31
-
32
- #include "yubikey.h"
33
-
34
- #define NUMBER_OF_ROUNDS 10
35
-
36
- static const uint8_t RC[] =
37
- { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 };
38
-
39
- static const uint8_t rijndael_sbox[] = {
40
- 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
41
- 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
42
- 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
43
- 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
44
- 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
45
- 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
46
- 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
47
- 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
48
- 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
49
- 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
50
- 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
51
- 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
52
- 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
53
- 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
54
- 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
55
- 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
56
- 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
57
- 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
58
- 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
59
- 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
60
- 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
61
- 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
62
- 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
63
- 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
64
- 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
65
- 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
66
- 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
67
- 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
68
- 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
69
- 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
70
- 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
71
- 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
72
- };
73
-
74
- static const uint8_t rijndael_inv_sbox[] = {
75
- 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
76
- 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
77
- 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
78
- 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
79
- 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
80
- 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
81
- 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
82
- 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
83
- 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
84
- 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
85
- 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
86
- 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
87
- 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
88
- 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
89
- 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
90
- 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
91
- 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
92
- 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
93
- 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
94
- 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
95
- 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
96
- 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
97
- 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
98
- 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
99
- 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
100
- 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
101
- 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
102
- 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
103
- 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
104
- 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
105
- 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
106
- 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
107
- };
108
-
109
- static inline uint8_t
110
- xtime (uint8_t b)
111
- {
112
- return (b & 0x80) ? ((b << 1) ^ 0x1b) : (b << 1);
113
- }
114
-
115
- void
116
- yubikey_aes_decrypt (uint8_t * state, const uint8_t * key)
117
- {
118
- uint8_t i, j, round_key[0x10];
119
- uint8_t a02x, a13x;
120
- uint8_t a02xx, a13xx;
121
- uint8_t k1, k2;
122
-
123
- memcpy (round_key, key, sizeof (round_key));
124
- for (i = 0; i < NUMBER_OF_ROUNDS; i++)
125
- {
126
- round_key[0] ^= RC[i];
127
-
128
- round_key[0] ^= rijndael_sbox[round_key[13]];
129
- round_key[1] ^= rijndael_sbox[round_key[14]];
130
- round_key[2] ^= rijndael_sbox[round_key[15]];
131
- round_key[3] ^= rijndael_sbox[round_key[12]];
132
-
133
- for (j = 4; j < 16; j++)
134
- round_key[j] ^= round_key[j - 4];
135
- }
136
- for (i = 0; i < 0x10; i++)
137
- state[i] ^= round_key[i];
138
-
139
- for (i = 1; i <= NUMBER_OF_ROUNDS; i++)
140
- {
141
- // inv_byte_sub_shift_row();
142
-
143
- /* First row: 0 shift, 0 4 8 12 */
144
- state[0] = rijndael_inv_sbox[state[0]];
145
- state[4] = rijndael_inv_sbox[state[4]];
146
- state[8] = rijndael_inv_sbox[state[8]];
147
- state[12] = rijndael_inv_sbox[state[12]];
148
-
149
- /* Second row: -1 shift, 1 5 9 13 */
150
- j = state[13];
151
- state[13] = rijndael_inv_sbox[state[9]];
152
- state[9] = rijndael_inv_sbox[state[5]];
153
- state[5] = rijndael_inv_sbox[state[1]];
154
- state[1] = rijndael_inv_sbox[j];
155
-
156
- /* Third row: -2 shift, 2 6 10 14 */
157
- j = state[2];
158
- state[2] = rijndael_inv_sbox[state[10]];
159
- state[10] = rijndael_inv_sbox[j];
160
- j = state[6];
161
- state[6] = rijndael_inv_sbox[state[14]];
162
- state[14] = rijndael_inv_sbox[j];
163
-
164
- /* Fourth row: -3 shift, 3 7 11 15 */
165
- j = state[3];
166
- state[3] = rijndael_inv_sbox[state[7]];
167
- state[7] = rijndael_inv_sbox[state[11]];
168
- state[11] = rijndael_inv_sbox[state[15]];
169
- state[15] = rijndael_inv_sbox[j];
170
-
171
- // get_inv_round_key(i);
172
-
173
- for (j = 15; j > 3; j--)
174
- round_key[j] ^= round_key[j - 4];
175
-
176
- round_key[0] ^=
177
- (RC[NUMBER_OF_ROUNDS - i] ^ rijndael_sbox[round_key[13]]);
178
-
179
- round_key[1] ^= rijndael_sbox[round_key[14]];
180
- round_key[2] ^= rijndael_sbox[round_key[15]];
181
- round_key[3] ^= rijndael_sbox[round_key[12]];
182
-
183
- for (j = 0; j < 16; j++)
184
- state[j] ^= round_key[j];
185
- if (i != NUMBER_OF_ROUNDS)
186
- {
187
-
188
- //inv_mix_column();
189
-
190
- for (j = 0; j < 16; j += 4)
191
- {
192
- k1 = state[j] ^ state[j + 2];
193
- a02x = xtime (k1);
194
- k2 = state[j + 1] ^ state[j + 3];
195
- a13x = xtime (k2);
196
-
197
- k1 ^= (k2 ^ xtime (state[j + 1] ^ state[j + 2]));
198
- k2 = k1;
199
-
200
- a02xx = xtime (a02x);
201
- a13xx = xtime (a13x);
202
-
203
- k1 ^= (xtime (a02xx ^ a13xx) ^ a02xx);
204
- k2 ^= (xtime (a02xx ^ a13xx) ^ a13xx);
205
-
206
- state[j] ^= (k1 ^ a02x);
207
- state[j + 1] ^= k2;
208
- state[j + 2] ^= (k1 ^ a13x);
209
- state[j + 3] ^= (k2 ^ a02x ^ a13x);
210
- }
211
- }
212
-
213
- }
214
- }
@@ -1,54 +0,0 @@
1
- /* ykcrc.c --- Implementation of Yubikey CRC-16 function.
2
- *
3
- * Written by Simon Josefsson <simon@josefsson.org>.
4
- * Copyright (c) 2006, 2007, 2008, 2009 Yubico AB
5
- * All rights reserved.
6
- *
7
- * Redistribution and use in source and binary forms, with or without
8
- * modification, are permitted provided that the following conditions are
9
- * met:
10
- *
11
- * * Redistributions of source code must retain the above copyright
12
- * notice, this list of conditions and the following disclaimer.
13
- *
14
- * * Redistributions in binary form must reproduce the above
15
- * copyright notice, this list of conditions and the following
16
- * disclaimer in the documentation and/or other materials provided
17
- * with the distribution.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
- *
31
- */
32
-
33
- #include "yubikey.h"
34
-
35
- uint16_t
36
- yubikey_crc16 (const uint8_t *buf, size_t buf_size)
37
- {
38
- uint16_t m_crc = 0xffff;
39
-
40
- while (buf_size--)
41
- {
42
- int i, j;
43
- m_crc ^= (uint8_t) * buf++ & 0xFF;
44
- for (i = 0; i < 8; i++)
45
- {
46
- j = m_crc & 1;
47
- m_crc >>= 1;
48
- if (j)
49
- m_crc ^= 0x8408;
50
- }
51
- }
52
-
53
- return m_crc;
54
- }
@@ -1,58 +0,0 @@
1
- /* yubikey.h --- Prototypes for low-level Yubikey OTP functions.
2
- *
3
- * Written by Simon Josefsson <simon@josefsson.org>.
4
- * Copyright (c) 2006, 2007, 2008, 2009 Yubico AB
5
- * All rights reserved.
6
- *
7
- * Redistribution and use in source and binary forms, with or without
8
- * modification, are permitted provided that the following conditions are
9
- * met:
10
- *
11
- * * Redistributions of source code must retain the above copyright
12
- * notice, this list of conditions and the following disclaimer.
13
- *
14
- * * Redistributions in binary form must reproduce the above
15
- * copyright notice, this list of conditions and the following
16
- * disclaimer in the documentation and/or other materials provided
17
- * with the distribution.
18
- *
19
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
- *
31
- */
32
-
33
- #ifndef YUBIKEY_H
34
- #define YUBIKEY_H
35
-
36
- #include <stdint.h>
37
- #include <string.h>
38
-
39
- #define YUBIKEY_BLOCK_SIZE 16
40
- #define YUBIKEY_KEY_SIZE 16
41
- #define YUBIKEY_UID_SIZE 6
42
-
43
- #define YUBIKEY_CRC_OK_RESIDUE 0xf0b8
44
-
45
- #define yubikey_crc_ok_p(tok) (yubikey_crc16 ((tok), YUBIKEY_BLOCK_SIZE) == YUBIKEY_CRC_OK_RESIDUE)
46
-
47
- /* Low-level functions; AES. */
48
-
49
- /* AES-decrypt one 16-byte block STATE using the 128-bit KEY, leaving
50
- the decrypted output in the STATE buffer. */
51
- void yubikey_aes_decrypt(uint8_t *state, const uint8_t *key);
52
-
53
- /*
54
- * Low-level functions; CRC.
55
- */
56
- uint16_t yubikey_crc16 (const uint8_t *buf, size_t buf_size);
57
-
58
- #endif
@@ -1,53 +0,0 @@
1
- #include "ruby.h"
2
- #include "yubikey.h"
3
-
4
- /*
5
- * call-seq:
6
- * decrypt(state, key) -> plaintext
7
- *
8
- * Decrypt 16 bytes of binary AES ciphertext to binary plaintext with the Yubico implementation of AES-128 ECB
9
- *
10
- * [+state+] 16 bytes of binary ciphertext
11
- * [+key+] 16-byte binary key
12
- *
13
- */
14
- static VALUE
15
- aes_decrypt(VALUE self, VALUE state, VALUE key) {
16
- char* state_ptr = StringValuePtr(state);
17
- char* key_ptr = StringValuePtr(key);
18
-
19
- if (RSTRING(state)->len != YUBIKEY_BLOCK_SIZE || RSTRING(key)->len != YUBIKEY_KEY_SIZE)
20
- rb_raise(rb_eArgError, "key and state must be 16 bytes");
21
-
22
- yubikey_aes_decrypt((uint8_t*)state_ptr, (uint8_t*)key_ptr);
23
-
24
- return rb_str_new(state_ptr, YUBIKEY_BLOCK_SIZE);
25
- }
26
-
27
- /*
28
- * call-seq:
29
- * valid?(token)
30
- *
31
- * Check the CRC of a decrypted Yubikey OTP
32
- *
33
- * [+token+] 16-byte binary token
34
- */
35
- static VALUE
36
- crc_check(VALUE self, VALUE token) {
37
- char* token_ptr = StringValuePtr(token);
38
-
39
- if (RSTRING(token)->len != YUBIKEY_BLOCK_SIZE)
40
- rb_raise(rb_eArgError, "token must be 16 bytes");
41
-
42
- return yubikey_crc_ok_p((uint8_t*)token_ptr) ? Qtrue : Qfalse;
43
- }
44
-
45
- void
46
- Init_yubikey_ext() {
47
- VALUE rb_mYubikey = rb_define_module("Yubikey");
48
- VALUE rb_mYubikeyAES = rb_define_module_under(rb_mYubikey, "AES");
49
- VALUE rb_mYubikeyCRC = rb_define_module_under(rb_mYubikey, "CRC");
50
-
51
- rb_define_module_function(rb_mYubikeyAES, "decrypt", aes_decrypt, 2);
52
- rb_define_module_function(rb_mYubikeyCRC, "valid?", crc_check, 1);
53
- }
@@ -1,32 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- $:.unshift File.dirname(__FILE__) + '/../ext/yubikey_ext'
4
- require 'yubikey_ext.so'
5
-
6
- describe 'yubikey_ext' do
7
- it 'should decrypt aes' do
8
- key = '72992427a3b8ccd20697493b5532561f'.to_bin
9
- state = 'ddf43aec57366784e061a12f767e728a'.to_bin
10
- plain = '619dd70df3b30300de1bdb00ffbf6f26'.to_bin
11
-
12
- Yubikey::AES.decrypt(state, key).should == plain
13
- end
14
-
15
- it 'should raise if aes key or state length is not 16' do
16
- lambda { Yubikey::AES.decrypt("i\266H\034\213\253\242\266\016\217\"\027\233X\315V", 'test') }.
17
- should raise_error(ArgumentError)
18
-
19
- lambda { Yubikey::AES.decrypt('test', "\354\336\030\333\347o\275\f33\017\0345Hq\333") }.
20
- should raise_error(ArgumentError)
21
- end
22
-
23
- it 'should check a crc' do
24
- Yubikey::CRC.valid?('619dd70df3b30300de1bdb00ffbf6f26'.to_bin).should == true
25
- Yubikey::CRC.valid?('ddf43aec57366784e061a12f767e728a'.to_bin).should == false
26
- end
27
-
28
- it 'should raise if crc token length not 16' do
29
- lambda { Yubikey::CRC.valid?('619dd70df3b30300de1bdb00ffbf6f'.to_bin) }.
30
- should raise_error(ArgumentError)
31
- end
32
- end