YubiRuby 1.0.0 → 1.1.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 +7 -0
- data/.hgignore +30 -0
- data/.hgtags +4 -0
- data/.rspec +2 -0
- data/CHANGELOG +3 -1
- data/Gemfile +4 -0
- data/LICENSE +1 -1
- data/README.developer.txt +17 -0
- data/README.md +43 -0
- data/Rakefile +64 -50
- data/YubiRuby.gemspec +31 -45
- data/bin/modhex +1 -1
- data/bin/yubikey +1 -1
- data/ext/libyubikey/libyubikey.c +14 -14
- data/ext/libyubikey/ykaes.c +101 -1
- data/ext/libyubikey/ykcrc.c +3 -3
- data/ext/libyubikey/ykhex.c +3 -5
- data/ext/libyubikey/ykmodhex.c +3 -5
- data/ext/libyubikey/ykparse.c +115 -9
- data/ext/libyubikey/yktoken.c +52 -0
- data/ext/libyubikey/yubikey.h +23 -8
- data/lib/fake_yubikey.rb +51 -55
- data/lib/hex.rb +10 -29
- data/lib/version.rb +3 -0
- data/lib/yubiruby.rb +2 -2
- data/test/fake_yubikey_spec.rb +1 -1
- data/test/hex_spec.rb +1 -1
- data/test/modhex_spec.rb +2 -2
- data/test/yubiruby_spec.rb +7 -0
- metadata +144 -143
- data/Manifest +0 -29
- data/README +0 -44
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1e0f6d6e3bb774f4aa5b792afe36563e6dd55172
|
4
|
+
data.tar.gz: 594c95692490f2e64adbd6f9f97707b9e2844ba4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c3f2e3e12a5a75fab5434f2d3039695536dd6151f42fb39ee8b6235f83b3268cf8dcdc7e6c497f662cdf07e3094267e4505f8e5927531a654fc22afb4a589485
|
7
|
+
data.tar.gz: 27e4a5a517036bc3236c74aa8f163a40265fc86b03fede41061aa377f50a8703240bb4e98953131af1e077acf9d04add3d913684e292bc38b42f3d145cf12993
|
data/.hgignore
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
syntax: glob
|
2
|
+
*.orig
|
3
|
+
*.rej
|
4
|
+
*~
|
5
|
+
*.o
|
6
|
+
tests/*.err
|
7
|
+
.DS_Store
|
8
|
+
build
|
9
|
+
.svn
|
10
|
+
(*)
|
11
|
+
*.perspectivev3
|
12
|
+
*.mode1v3
|
13
|
+
*.mode2v3
|
14
|
+
*.mpkg
|
15
|
+
*.framework
|
16
|
+
*.pbxuser
|
17
|
+
*.gem
|
18
|
+
*.bundle
|
19
|
+
Makefile
|
20
|
+
Gemfile.lock
|
21
|
+
lib/*.so
|
22
|
+
|
23
|
+
syntax: regexp
|
24
|
+
.*\#.*\#$
|
25
|
+
^tmp/*$
|
26
|
+
^script/*$
|
27
|
+
^doc/*$
|
28
|
+
^pkg/*$
|
29
|
+
^meta/*$
|
30
|
+
^\.yardoc/*$
|
data/.hgtags
ADDED
data/.rspec
ADDED
data/CHANGELOG
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
v1.1.0. updates to build under Ruby 2.0
|
2
|
+
|
1
3
|
v1.0.0. broken api compatibility. TestCase. fixed some bugs in (mod)hex decoding. Exceptions. FakeYubikey generator. yubikey app for personal key management.
|
2
4
|
|
3
5
|
v0.1.2. backported fixes from 1.0.0
|
@@ -6,4 +8,4 @@ v0.1.1. fixed some bugs in hex decoding.
|
|
6
8
|
|
7
9
|
v0.1.0. modhex installed as binary.
|
8
10
|
|
9
|
-
v0.0.1. First release
|
11
|
+
v0.0.1. First release
|
data/Gemfile
ADDED
data/LICENSE
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
CONTRIBUTING
|
2
|
+
|
3
|
+
Firstoff, any model to be used by people should consist of simple, consistent
|
4
|
+
rules. Programming is complex enough without having to worry about elaborate
|
5
|
+
branching directives. Therefore this model boils down to 3 simple rules:
|
6
|
+
|
7
|
+
(1) you do all the work on default - except for hotfixes.
|
8
|
+
|
9
|
+
(2) on stable you only do hotfixes, merges for release and tagging for
|
10
|
+
release. Only maintainers touch stable.
|
11
|
+
|
12
|
+
(3) you can use arbitrary feature-branches, as long as you don't call them
|
13
|
+
default or stable. They always start at default (since you do all the
|
14
|
+
work on default).
|
15
|
+
|
16
|
+
A more detailed explaination can be found online at
|
17
|
+
http://draketo.de/light/english/mercurial/complete-branching-strategy
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# YubiRuby
|
2
|
+
|
3
|
+
Yubico Server wrapper in Ruby
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
`$ gem install YubiRuby`
|
8
|
+
|
9
|
+
## Some examples
|
10
|
+
|
11
|
+
### Checking an OTP
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'YubiRuby'
|
15
|
+
|
16
|
+
key = "6df89690b5f51bd9ac912c5004781e86" #use your AES key
|
17
|
+
y = YubiRuby::Yubikey.new(key);
|
18
|
+
puts y.key
|
19
|
+
otp = gets().strip
|
20
|
+
puts y.parse(otp)
|
21
|
+
puts "Ouput: #{y}"
|
22
|
+
puts "uid: #{y.uid}"
|
23
|
+
puts "session counter: #{y.session_counter}"
|
24
|
+
puts "capslock: #{y.triggered_by_capslock?}"
|
25
|
+
puts "timestamp low/high: #{y.timestamp_low}/#{y.timestamp_high}"
|
26
|
+
puts "session use: #{y.session_use}"
|
27
|
+
puts "random: #{y.random}"
|
28
|
+
puts "crc: #{y.crc}"
|
29
|
+
puts "crc residue: #{y.crc_residue}"
|
30
|
+
puts "crc residue ok?: #{y.crc?} (#{y.crc_residue} == #{YubiRuby::Yubikey::CRC_OK_RESIDUE})"
|
31
|
+
|
32
|
+
### Generating a valid yubikey
|
33
|
+
|
34
|
+
key = YubiRuby::FakeYubikey.new
|
35
|
+
key.set_random_key
|
36
|
+
key.set_random_uid
|
37
|
+
key.public_id = "vvefeeccebek"
|
38
|
+
puts "Yubikey generated"
|
39
|
+
puts "public id:\t#{key.public_id}"
|
40
|
+
puts "key:\t\t#{key.key}"
|
41
|
+
puts "uid:\t\t#{key.uid}"
|
42
|
+
puts "And now 3 otp"
|
43
|
+
3.times { puts key.otp }
|
data/Rakefile
CHANGED
@@ -1,54 +1,68 @@
|
|
1
|
-
|
2
|
-
require
|
3
|
-
require 'rake'
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
Redistribution and use in source and binary forms, with or without
|
18
|
-
modification, are permitted provided that the following conditions are
|
19
|
-
met:
|
20
|
-
|
21
|
-
* Redistributions of source code must retain the above copyright
|
22
|
-
notice, this list of conditions and the following disclaimer.
|
23
|
-
|
24
|
-
* Redistributions in binary form must reproduce the above
|
25
|
-
copyright notice, this list of conditions and the following
|
26
|
-
disclaimer in the documentation and/or other materials provided
|
27
|
-
with the distribution.
|
28
|
-
|
29
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
30
|
-
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
31
|
-
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
32
|
-
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
33
|
-
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
34
|
-
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
35
|
-
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
36
|
-
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
37
|
-
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
38
|
-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
39
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
40
|
-
EOF
|
41
|
-
p.url = "http://bitbucket.org/nolith/yubiruby"
|
42
|
-
p.author = "Alessio Caiazza"
|
43
|
-
p.email = "nolith@abisso.org"
|
44
|
-
p.platform = Gem::Platform::RUBY
|
45
|
-
p.ignore_pattern = ["tmp/**/*", "script/*", "meta/**/*"]
|
46
|
-
p.development_dependencies = ['yard', 'rspec']
|
47
|
-
p.runtime_dependencies << ['ruby-aes-normal', '~> 1.0']
|
48
|
-
p.runtime_dependencies << ['bit-struct'] #, '~> 0.13.6']
|
49
|
-
p.spec_pattern = ['test/**/*_spec.rb']
|
50
|
-
p.has_rdoc = true
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require 'rake/clean'
|
4
|
+
CLEAN << 'lib/libyubikey.so'
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
7
|
+
task.pattern = './test{,/*/**}/*_spec.rb'
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => :spec
|
11
|
+
|
12
|
+
require "rake/extensiontask"
|
13
|
+
|
14
|
+
Rake::ExtensionTask.new("libyubikey") do |ext|
|
15
|
+
ext.lib_dir = "lib"
|
51
16
|
end
|
52
17
|
|
53
18
|
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
54
19
|
|
20
|
+
task :build => :compile
|
21
|
+
task :spec => :compile
|
22
|
+
|
23
|
+
#fast hack for mercurial
|
24
|
+
module Bundler
|
25
|
+
class GemHelper
|
26
|
+
|
27
|
+
def git_push
|
28
|
+
perform_git_push ' -r tip'
|
29
|
+
Bundler.ui.confirm "Pushed hg commits and tags."
|
30
|
+
end
|
31
|
+
|
32
|
+
def perform_git_push(options = '')
|
33
|
+
cmd = "hg push #{options}"
|
34
|
+
out, code = sh_with_code(cmd)
|
35
|
+
raise "Couldn't hg push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
def already_tagged?
|
39
|
+
if sh('hg tags -q').split(/\n/).include?(version_tag)
|
40
|
+
Bundler.ui.confirm "Tag #{version_tag} has already been created."
|
41
|
+
true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def guard_clean
|
46
|
+
clean? && committed? or raise("There are files that need to be committed first.")
|
47
|
+
end
|
48
|
+
|
49
|
+
def clean?
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
def committed?
|
54
|
+
sh_with_code("hg sum -q | grep \"^commit:\"")[1] != 0
|
55
|
+
end
|
56
|
+
|
57
|
+
def tag_version
|
58
|
+
sh "hg tag -m \"Version #{version}\" #{version_tag}"
|
59
|
+
Bundler.ui.confirm "Tagged #{version_tag}."
|
60
|
+
yield if block_given?
|
61
|
+
rescue
|
62
|
+
Bundler.ui.error "Untagging #{version_tag} due to error."
|
63
|
+
sh_with_code "hg tag --remove #{version_tag}"
|
64
|
+
raise
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
data/YubiRuby.gemspec
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "YubiRuby"
|
8
|
+
spec.version = YubiRuby::VERSION
|
9
|
+
spec.authors = ["Alessio Caiazza"]
|
10
|
+
spec.email = ["nolith@abisso.org"]
|
11
|
+
spec.extensions = ["ext/libyubikey/extconf.rb"]
|
12
|
+
spec.summary = %q{Yubico Server wrapper in Ruby}
|
13
|
+
spec.description = <<-EOF
|
14
|
+
Yubikey integration -
|
11
15
|
|
12
16
|
Includes Prototypes for low-level Yubikey OTP functions
|
13
17
|
witten by Simon Josefsson <simon@josefsson.org>.
|
@@ -37,39 +41,21 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
37
41
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
38
42
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
39
43
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
59
|
-
s.add_runtime_dependency(%q<ruby-aes-normal>, ["~> 1.0"])
|
60
|
-
s.add_runtime_dependency(%q<bit-struct>, [">= 0"])
|
61
|
-
s.add_development_dependency(%q<yard>, [">= 0"])
|
62
|
-
s.add_development_dependency(%q<rspec>, [">= 0"])
|
63
|
-
else
|
64
|
-
s.add_dependency(%q<ruby-aes-normal>, ["~> 1.0"])
|
65
|
-
s.add_dependency(%q<bit-struct>, [">= 0"])
|
66
|
-
s.add_dependency(%q<yard>, [">= 0"])
|
67
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
68
|
-
end
|
69
|
-
else
|
70
|
-
s.add_dependency(%q<ruby-aes-normal>, ["~> 1.0"])
|
71
|
-
s.add_dependency(%q<bit-struct>, [">= 0"])
|
72
|
-
s.add_dependency(%q<yard>, [">= 0"])
|
73
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
74
|
-
end
|
44
|
+
EOF
|
45
|
+
spec.homepage = "http://bitbucket.org/nolith/yubiruby"
|
46
|
+
spec.license = "AS IS"
|
47
|
+
|
48
|
+
spec.platform = Gem::Platform::RUBY
|
49
|
+
spec.files = `hg locate -0`.split("\x0")
|
50
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
51
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
52
|
+
spec.require_paths = ["lib"]
|
53
|
+
|
54
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
55
|
+
spec.add_development_dependency "rake"
|
56
|
+
spec.add_development_dependency "rake-compiler"
|
57
|
+
spec.add_development_dependency "rspec", "~> 2"
|
58
|
+
spec.add_development_dependency "yard", "~> 0.8"
|
59
|
+
|
60
|
+
spec.add_dependency "bit-struct", "~> 0.15"
|
75
61
|
end
|
data/bin/modhex
CHANGED
data/bin/yubikey
CHANGED
data/ext/libyubikey/libyubikey.c
CHANGED
@@ -58,13 +58,13 @@ static VALUE mCRC16;
|
|
58
58
|
static VALUE modhex_sing_encode(VALUE self, VALUE obj)
|
59
59
|
{
|
60
60
|
VALUE str = StringValue(obj);
|
61
|
-
int src_size =
|
61
|
+
int src_size = RSTRING_LEN(str);
|
62
62
|
char *dst = (char*) malloc((2*src_size+1)*sizeof(char));
|
63
63
|
/* ModHex encode input string SRC of length SRCSIZE and put the zero
|
64
64
|
terminated output string in DST. The size of the output string DST
|
65
65
|
must be at least 2*SRCSIZE+1. The output string is always
|
66
66
|
2*SRCSIZE large plus the terminating zero. */
|
67
|
-
yubikey_modhex_encode(dst,
|
67
|
+
yubikey_modhex_encode(dst, RSTRING_PTR(str), src_size);
|
68
68
|
|
69
69
|
return rb_str_new2(dst);
|
70
70
|
}
|
@@ -94,14 +94,14 @@ static VALUE modhex_encode(VALUE self)
|
|
94
94
|
static VALUE modhex_sing_decode(VALUE self, VALUE obj)
|
95
95
|
{
|
96
96
|
VALUE str = StringValue(obj);
|
97
|
-
int src_size =
|
97
|
+
int src_size = RSTRING_LEN(str);
|
98
98
|
if (rb_funcall(str, rb_intern(MODHEX_VALID), 0) == Qfalse)
|
99
99
|
rb_raise(rb_eval_string("YubiRuby::NoModHexEncodedError"), "");
|
100
100
|
char *dst = (char*) malloc(((src_size/2)+1)*sizeof(char));
|
101
101
|
/* ModHex decode input string SRC of length DSTSIZE/2 into output
|
102
102
|
string DST. The output string DST is always DSTSIZE/2 large plus
|
103
103
|
the terminating zero. */
|
104
|
-
yubikey_modhex_decode(dst,
|
104
|
+
yubikey_modhex_decode(dst, RSTRING_PTR(str), src_size);
|
105
105
|
|
106
106
|
return rb_str_new(dst, src_size/2);
|
107
107
|
}
|
@@ -128,7 +128,7 @@ static VALUE modhex_decode(VALUE self)
|
|
128
128
|
static VALUE modhex_sing_is_modhex(VALUE self, VALUE obj)
|
129
129
|
{
|
130
130
|
VALUE str = StringValue(obj);
|
131
|
-
if (yubikey_modhex_p(
|
131
|
+
if (yubikey_modhex_p(RSTRING_PTR(str)) != 0)
|
132
132
|
return Qtrue;
|
133
133
|
else
|
134
134
|
return Qfalse;
|
@@ -190,12 +190,12 @@ static VALUE yubikey_set_key(VALUE self, VALUE key)
|
|
190
190
|
if (sKey == Qnil)
|
191
191
|
rb_raise(rb_eTypeError, "wrong parameter type.");
|
192
192
|
|
193
|
-
if (
|
193
|
+
if (RSTRING_LEN(sKey) == YUBIKEY_KEY_SIZE*2) {
|
194
194
|
/* Hex */
|
195
|
-
if (yubikey_hex_p(
|
195
|
+
if (yubikey_hex_p(RSTRING_PTR(sKey)) == 0)
|
196
196
|
rb_raise(rb_eTypeError, "not an HEX string."); //TODO:ArgumentError
|
197
197
|
char* buff = (char*) malloc(sizeof(char)*(YUBIKEY_KEY_SIZE +1));
|
198
|
-
yubikey_hex_decode( buff,
|
198
|
+
yubikey_hex_decode( buff, RSTRING_PTR(sKey), YUBIKEY_KEY_SIZE );
|
199
199
|
MEMCPY(&data->key, buff, uint8_t, YUBIKEY_KEY_SIZE);
|
200
200
|
}
|
201
201
|
|
@@ -228,7 +228,7 @@ static VALUE yubikey_get_key(VALUE self)
|
|
228
228
|
*
|
229
229
|
* Creates a yubikey parser whith +aes_key+ ad AES key.
|
230
230
|
*
|
231
|
-
* +aes_key+
|
231
|
+
* +aes_key+ must be encoded with YubiRuby::HEX.encode.
|
232
232
|
*/
|
233
233
|
static VALUE yubikey_initialize(VALUE self, VALUE key)
|
234
234
|
{
|
@@ -275,7 +275,7 @@ static VALUE yubikey_check(VALUE self, VALUE otp)
|
|
275
275
|
if (str == Qnil)
|
276
276
|
rb_raise(rb_eTypeError, "wrong argument type.");
|
277
277
|
|
278
|
-
int start =
|
278
|
+
int start = RSTRING_LEN(str)- 32;
|
279
279
|
|
280
280
|
if (start < 0)
|
281
281
|
rb_raise(rb_eTypeError, "OTP too short."); //Argument error
|
@@ -313,7 +313,7 @@ static VALUE yubikey_check(VALUE self, VALUE otp)
|
|
313
313
|
/* Decrypt TOKEN using KEY and store output in OUT structure. Note
|
314
314
|
that there is no error checking whether the output data is valid or
|
315
315
|
not, use yubikey_check_* for that. */
|
316
|
-
yubikey_parse ((uint8_t*)(
|
316
|
+
yubikey_parse ((uint8_t*)(RSTRING_PTR(str)+start), data->key, data->token);
|
317
317
|
|
318
318
|
#ifndef NDEBUG
|
319
319
|
printf ("Output:\n");
|
@@ -398,7 +398,7 @@ static VALUE yubikey_get_uid(VALUE self)
|
|
398
398
|
VALUE out = yubikey_to_str(self);
|
399
399
|
|
400
400
|
// *2 becaouse of hex
|
401
|
-
return rb_str_new(
|
401
|
+
return rb_str_new(RSTRING_PTR(out), YUBIKEY_UID_SIZE*2 );
|
402
402
|
}
|
403
403
|
|
404
404
|
/* call-seq:
|
@@ -493,7 +493,7 @@ static VALUE yubikey_check_crc(VALUE self)
|
|
493
493
|
static VALUE crc16_sing_calc(VALUE self, VALUE data)
|
494
494
|
{
|
495
495
|
VALUE str = StringValue(data);
|
496
|
-
return INT2NUM(yubikey_crc16(
|
496
|
+
return INT2NUM(yubikey_crc16( (uint8_t *)RSTRING_PTR(str), RSTRING_LEN(str)));
|
497
497
|
}
|
498
498
|
|
499
499
|
/* Implementation of Yubikey OTP functions.
|
@@ -551,4 +551,4 @@ void Init_libyubikey() {
|
|
551
551
|
|
552
552
|
mCRC16 = rb_define_module_under(mYubiRuby, "CRC16");
|
553
553
|
rb_define_singleton_method(mCRC16, "calculate", crc16_sing_calc, 1);
|
554
|
-
}
|
554
|
+
}
|