fast_secure_compare 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1b49fc77195a730ff81966f32d327f2e4eafda4b
4
+ data.tar.gz: cc68be175b411a1d1f6867d8e9a7f0443269be40
5
+ SHA512:
6
+ metadata.gz: d1bd92fc4dcc15967c9e2dc614bf492c6722c10e898fc3e5a8cf2121739ec8da1dd12b7093e5daddcfaed20f08c2083ec4a984b8ba7620ae25b16186d193ad92
7
+ data.tar.gz: f473788cc8c4c789f02d9262593290f5e8e0eb4a12024d73f0099592ce622642215d367bb0ae17b4679e74bb48ac9da5c08e7377bd4245dfe8b4950a34f2592e
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2014 Daniel Axtens
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ This gem provides a simple, fast way to do string comparisons that resist timing attacks.
2
+
3
+ # What is a timing attack? #
4
+ A timing attack is an attack on a system that determines secret information based on how long an operation takes.
5
+
6
+ Timing attacks are particularly prevalent (and dangerous) in cryptographic operations, but they can also sneak into other types of operation.
7
+
8
+ In particular, any time you are **comparing user specified input with a secret**, you should consider whether or not you are exposing yourself to a timing attack.
9
+
10
+ The attack is probably best described by [Nate Lawson](http://rdist.root.org/2010/07/19/exploiting-remote-timing-attacks/):
11
+
12
+ > The attack is very simple. You repeatedly send guesses about a secret value to the server, which rejects them as incorrect. However, if your first byte of the guess is correct, it takes a very slightly longer time to return the error. With many measurements and some filtering, you can distinguish this difference.
13
+
14
+ Therefore, it's important that the amount of time these operations take depends *only* on the length of the user's input, and *not* on any characteristic of the secret data.
15
+
16
+ # How does this gem help? Why should I use it rather than rolling my own? #
17
+
18
+ This gem provides a secure comparison function that is:
19
+
20
+ - very simple: 1 class, 1 method
21
+ - fast: it uses a C back-end rather than a pure Ruby implementation.
22
+ - portable: the C code is platform independent
23
+
24
+ Furthermore, unlike some other secure comparison fuctions, the code does not require that the strings are the same length, and should not leak the length of the string if the string lengths do not match.
25
+
26
+ If you're interested in seeing how much faster you can make your code by using this gem, check out the demo folder.
27
+
28
+ # How do I use this gem in my code? #
29
+
30
+ ```ruby
31
+
32
+ import 'fast_secure_compare'
33
+
34
+ FastSecureCompare.compare(my_secret, user_input)
35
+ ```
36
+
37
+ # Is there anything else I should know? #
38
+
39
+ The gem is not foolproof. In particular, it can't protect you against anything designed to exploit cache misses or any other more elaborate form of timing attack. However, none of the existing pure Ruby secure_compare functions do either.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ # shamelessly ripped off https://github.com/cotag/http-parser/blob/master/Rakefile
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'rspec/core/rake_task'
6
+
7
+ task :default => [:compile, :test]
8
+
9
+ task :compile do
10
+ protect = ['secure_compare.c']
11
+ Dir["ext/fast_secure_compare/**/*"].each do |file|
12
+ begin
13
+ next if protect.include? File.basename(file)
14
+ FileUtils.rm file
15
+ rescue
16
+ end
17
+ end
18
+ system 'cd ext && rake'
19
+ end
20
+
21
+ RSpec::Core::RakeTask.new(:test)
data/ext/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require 'ffi-compiler/compile_task'
2
+
3
+ FFI::Compiler::CompileTask.new('fast_secure_compare')
@@ -0,0 +1,15 @@
1
+ int secure_compare_bytes(const unsigned char * secret, unsigned int secret_len,
2
+ const unsigned char * input, unsigned int input_len) {
3
+
4
+ int input_pos;
5
+ int secret_pos = 0;
6
+ int result = secret_len - input_len;
7
+ // make sure our time isn't dependent on secret_len, and only dependent
8
+ // on input_len
9
+ for (input_pos = 0; input_pos < input_len; input_pos++) {
10
+ result |= input[input_pos] ^ secret[secret_pos];
11
+ secret_pos = (secret_pos + 1) % secret_len;
12
+ }
13
+
14
+ return result;
15
+ }
@@ -0,0 +1,27 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'fast_secure_compare'
3
+ s.version = '0.0.2'
4
+ s.date = '2014-08-17'
5
+ s.summary = "A fast, simple way to do constant time string comparisons."
6
+ s.description = "A secure_comparison function implemented in C for blazing speed."
7
+ s.authors = ["Daniel Axtens"]
8
+ s.email = 'daniel@axtens.net'
9
+ s.homepage =
10
+ 'https://github.com/daxtens/fast_secure_compare'
11
+ s.license = 'MIT'
12
+
13
+
14
+ s.add_dependency 'ffi-compiler', '>= 0.0.2'
15
+ s.add_dependency 'rake'
16
+
17
+ s.add_development_dependency 'rspec'
18
+
19
+ s.files = Dir["{lib}/**/*"] + %w(Rakefile fast_secure_compare.gemspec README.md LICENSE)
20
+ s.files += ["ext/fast_secure_compare/secure_compare.c"]
21
+ s.test_files = Dir["spec/**/*"]
22
+ s.extra_rdoc_files = ["README.md"]
23
+
24
+ s.extensions << "ext/Rakefile"
25
+ s.require_paths = ["lib"]
26
+ end
27
+
@@ -0,0 +1,17 @@
1
+ require 'ffi'
2
+ require 'ffi-compiler/loader'
3
+
4
+ module FastSecureCompare
5
+ extend FFI::Library
6
+ ffi_lib FFI::Compiler::Loader.find('fast_secure_compare')
7
+
8
+ attach_function :secure_compare_bytes, [:pointer, :uint, :pointer, :uint], :int
9
+
10
+ def self.compare(secret, input)
11
+ sBuf = FFI::MemoryPointer.new(:char, secret.size)
12
+ sBuf.put_bytes(0, secret)
13
+ iBuf = FFI::MemoryPointer.new(:char, input.size)
14
+ iBuf.put_bytes(0, input)
15
+ secure_compare_bytes(secret, secret.size, input, input.size) == 0
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'fast_secure_compare'
2
+
3
+ describe FastSecureCompare, "#compare" do
4
+ it "returns true on equal strings" do
5
+ expect(FastSecureCompare.compare("aaa","aaa")).to eq(true)
6
+ end
7
+ it "returns false on an empty string" do
8
+ expect(FastSecureCompare.compare("aaa","")).to eq(false)
9
+ end
10
+ it "returns false on different strings of different length" do
11
+ expect(FastSecureCompare.compare("aaa","a")).to eq(false)
12
+ expect(FastSecureCompare.compare("aaa","aaaaaa")).to eq(false)
13
+ end
14
+ it "returns false on different strings of equal length" do
15
+ expect(FastSecureCompare.compare("aaa","bbb")).to eq(false)
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fast_secure_compare
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Axtens
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi-compiler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: A secure_comparison function implemented in C for blazing speed.
56
+ email: daniel@axtens.net
57
+ executables: []
58
+ extensions:
59
+ - ext/Rakefile
60
+ extra_rdoc_files:
61
+ - README.md
62
+ files:
63
+ - lib/fast_secure_compare.rb
64
+ - Rakefile
65
+ - fast_secure_compare.gemspec
66
+ - README.md
67
+ - LICENSE
68
+ - ext/fast_secure_compare/secure_compare.c
69
+ - spec/fast_secure_compare_spec.rb
70
+ - ext/Rakefile
71
+ homepage: https://github.com/daxtens/fast_secure_compare
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.0.6
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: A fast, simple way to do constant time string comparisons.
95
+ test_files:
96
+ - spec/fast_secure_compare_spec.rb
97
+ has_rdoc: