securer_randomer 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -19,3 +19,4 @@ before_install:
19
19
  env:
20
20
  - WITH_MONKEYPATCH=false
21
21
  - WITH_MONKEYPATCH=true
22
+ - WITH_MONKEYPATCH=kinda
data/README.md CHANGED
@@ -7,67 +7,93 @@ Ruby's SecureRandom prefers OpenSSL over other mechanisms (such as
7
7
  `/dev/urandom` and `getrandom(2)`). This has recently garnered [some][1]
8
8
  [criticism][2].
9
9
 
10
- [RbNaCl][3] provides Ruby bindings to a portable crypto library
11
- ([libsodium][4]) that includes an alternative, OpenSSL-free pseudo-random
12
- number generator (PRNG) implementation.
10
+ [RbNaCl][3] provides Ruby bindings to [libsodium][4], a portable crypto
11
+ library—which is a fork of [NaCl][6] by Daniel J. Bernstein—that
12
+ includes hooks to alternative, OpenSSL-free pseudo-random number generators
13
+ (PRNGs) such as `getrandom(2)` on modern Linux kernels and `RtlGenRandom()` on
14
+ Windows.
13
15
 
14
16
  This gem monkeypatches RbNaCl into SecureRandom and aims to be "bug-for-bug"
15
17
  compatible with the "stock" implementation of SecureRandom across Ruby
16
- versions. It also provides a nice "do what I mean" random number method that
18
+ versions. It also provides a bonus "do what I mean" random number method that
17
19
  can be used instead of Kernel`.rand` and SecureRandom`.random_number`.
18
20
 
19
21
  ## History
20
22
 
21
23
  This gem started out as a very simple monkeypatch to
22
- SecureRandom`.random_bytes` and grew as I dug deeper. In newer Rubies, you need
23
- to patch `.gen_random` instead of `.random_bytes`, and it has no default byte
24
- size.
24
+ SecureRandom`.random_bytes` and grew as I dug deeper. In newer rubies, for
25
+ example, you need to patch `.gen_random` instead of `.random_bytes`, and it has
26
+ a different calling signature.
25
27
 
26
- Generating random numbers proved to be rather tricky due to inconsistencies
27
- between the implementations and functionality of Kernel`.rand` and
28
- SecureRandom`.random_number` between Ruby versions. For example:
28
+ Generating random numbers proved to be rather tricky due to inconsistencies of
29
+ of Kernel`.rand` and SecureRandom`.random_number` between Ruby implementations
30
+ and versions. For example:
29
31
 
30
32
  * `Kernel.rand(nil)` and `SecureRandom.random_number(nil)` both return a float
31
- such that `{ 0.0 <= n < 1.0 }` in Ruby 2.3; but
33
+ `n` such that `0.0 <= n < 1.0` in Ruby 2.3; but
32
34
  `SecureRandom.random_number(nil)` throws an ArgumentError in Ruby 2.2
33
35
  * Kernel`.rand` with an inverted range (e.g. `0..-10`) returns `nil` in Ruby
34
36
  2.2+, but SecureRandom`.random_number` throws an ArgumentError in Ruby 2.2
35
- and returns a float such that `{ 0.0 <= n < 1.0 }` in Ruby 2.3
37
+ and returns a float `n` such that `0.0 <= n < 1.0` in Ruby 2.3
36
38
 
37
- Tests started to accumulate so I decided it was probably a good idea to gemify
38
- this!
39
+ Branching logic and tests started to accumulate so I decided it was probably a
40
+ good idea to gemify this!
41
+
42
+ ### Why a monkeypatch?
43
+
44
+ The concept of monkeypatching in Ruby is a sensitive subject. It has the
45
+ potential to break things in unexpected ways and make Ruby code more difficult
46
+ to troubleshoot, and it's these kinds of practices that give Ruby (and
47
+ Rubyists) a bad name. It was actually way more labor-intensive to write this as
48
+ a monkeypatch rather than landing it as a completely separate module. So why?
49
+
50
+ Simply put, I do not anticipate this gem being a long-term solution! At some
51
+ point in the hopefully-near future I would like to see the Ruby core team
52
+ acquiesce to community pressure and modify `securerandom.rb` and `random.c` to
53
+ not utilize OpenSSL and prefer `getrandom(2)` over `urandom`. And so my goal
54
+ was not to write some super-maintainable, standalone piece of software, but
55
+ rather a temporary fix that can be easily dropped into an existing project and
56
+ easily pulled out at a later date. A monkeypatch is the best way to achieve
57
+ this.
39
58
 
40
59
  ## Features
41
60
 
42
61
  * SecureRandom`.gen_random` (or `.random_bytes`)
43
62
 
44
- Monkeypatches SecureRandom such that its various formatter methods (`.uuid`,
45
- `.hex`, `.base64`, `.urlsafe_base64`, and `.random_bytes`) use RbNaCl for random
46
- byte generation instead of OpenSSL.
63
+ Monkeypatches SecureRandom such that its various formatter methods (`.uuid`,
64
+ `.hex`, `.base64`, `.urlsafe_base64`, and `.random_bytes`) use RbNaCl for random
65
+ byte generation instead of OpenSSL.
47
66
 
48
67
  * SecureRandom`.random_number`
49
68
 
50
- Monkeypatches SecureRandom such that it uses SecurerRandomer`.kernel_rand`
51
- instead of OpenSSL (or Kernel`.rand`) to generate random numbers from numeric
52
- types and ranges. It is bug-for-bug compatible with "stock" SecureRandom,
53
- meaning it "chokes" on the same inputs and throws the same exception types.
69
+ Monkeypatches SecureRandom such that it uses SecurerRandomer`.kernel_rand`
70
+ instead of OpenSSL to generate random numbers from numeric types and ranges. It
71
+ is bug-for-bug compatible with "stock" SecureRandom, meaning it "chokes" on the
72
+ same inputs and throws the same exception types.
73
+
74
+ If you prefer to use Kernel`.rand` instead of SecurerRandomer`.kernel_rand`,
75
+ add this statement to your bootup process after requiring SecurerRandomer:
76
+
77
+ ```ruby
78
+ SecurerRandomer::KERNEL_RAND = Kernel.method(:rand)
79
+ ```
54
80
 
55
81
  * SecurerRandomer`.kernel_rand`
56
82
 
57
- A bug-for-bug reimplementation of Kernel`.rand`&mdash;meaning it "chokes" on
58
- the same inputs and throws the same exception types&mdash;that uses RbNaCl as
59
- its source of entropy.
83
+ A bug-for-bug reimplementation of Kernel`.rand`&mdash;meaning it "chokes" on
84
+ the same inputs and throws the same exception types&mdash;that uses RbNaCl as
85
+ its source of entropy.
60
86
 
61
87
  * SecurerRandomer`.rand`
62
88
 
63
- An idealistic, "do what I mean" random number method that accepts a variety of
64
- inputs and returns what you might expect. Whereas `Kernel.rand(-5.6)` returns
65
- an integer such that `{ 0 <= n < 5 }` and `SecureRandom.random_number(-5.6)`
66
- returns a float such that `{ 0.0 <= n < 1.0 }`, **`SecurerRandomer.rand(-5.6)`
67
- returns a float such that `{ 0 >= n > -5.6 }`**. Whereas `Kernel.rand(10..0)`
68
- returns `nil` and `SecureRandom.random_number(10..0)` returns a float such that
69
- `{ 0.0 <= n < 1.0 }` (in Ruby 2.3), **`SecurerRandomer.rand(10..0)` returns an
70
- integer such that `{ 10 >= n >= 0 }`**.
89
+ An idealistic, "do what I mean" random number method that accepts a variety of
90
+ inputs and returns what you might expect. Whereas `Kernel.rand(-5.6)` returns
91
+ an integer `n` such that `0 <= n < 5` and `SecureRandom.random_number(-5.6)`
92
+ returns a float `n` such that `0.0 <= n < 1.0`, **`SecurerRandomer.rand(-5.6)`
93
+ returns a float `n` such that `0 >= n > -5.6`**. Whereas `Kernel.rand(10..0)`
94
+ returns `nil` and `SecureRandom.random_number(10..0)` returns a float `n` such
95
+ that `0.0 <= n < 1.0` (in Ruby 2.3), **`SecurerRandomer.rand(10..0)` returns an
96
+ integer `n` such that `10 >= n >= 0`**.
71
97
 
72
98
  ## Installation
73
99
 
@@ -100,9 +126,8 @@ and 2.3, and JRuby 1.7 and 9.0 (both under Oracle Java 8).
100
126
 
101
127
  I am neither a cryptologist nor a cryptographer. Although I'm fairly confident
102
128
  in the test suite, serious bugs affecting compatibility, randomness, and
103
- performance may be present. If you're cautious, I would recommend using the
104
- monkeypatched SecureRandom formatter methods for random data and Kernel`.rand`
105
- for random numbers. Bug reports are welcome.
129
+ performance may be present. If you're cautious, I would recommend setting
130
+ `SecurerRandomer::KERNEL_RAND = Kernel.method(:rand)` as described above.
106
131
 
107
132
  ## Development
108
133
 
@@ -123,3 +148,4 @@ The gem is available as open source under the terms of the [MIT License](http://
123
148
  [3]: https://github.com/cryptosphere/rbnacl
124
149
  [4]: https://github.com/jedisct1/libsodium
125
150
  [5]: https://github.com/cryptosphere/rbnacl-libsodium
151
+ [6]: http://nacl.cr.yp.to
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SecureRandom
4
+ KERNEL_RAND = SecurerRandomer.method(:kernel_rand)
5
+
4
6
  if respond_to?(:gen_random)
5
7
  def self.gen_random(n)
6
8
  RbNaCl::Random.random_bytes(n)
@@ -31,7 +33,7 @@ module SecureRandom
31
33
 
32
34
  raise TypeError unless arg
33
35
 
34
- SecurerRandomer.rand(arg, true)
36
+ KERNEL_RAND.call(arg)
35
37
  rescue TypeError
36
38
  raise ArgumentError, "invalid argument - #{n}"
37
39
  end
@@ -42,7 +44,7 @@ module SecureRandom
42
44
  raise ArgumentError, "comparison of Fixnum with #{n} failed" unless n.is_a?(Numeric)
43
45
  raise FLOAT_ERROR if n.is_a?(Float) and n > 0
44
46
 
45
- SecurerRandomer.rand(n > 0 ? n : 0, true)
47
+ KERNEL_RAND.call(n > 0 ? n : 0)
46
48
  end
47
49
  end
48
50
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SecurerRandomer
4
- VERSION = '0.1.5' # rubocop:disable Style/MutableConstant
4
+ VERSION = '0.1.6' # rubocop:disable Style/MutableConstant
5
5
  end
@@ -26,5 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency 'rspec-given', '~> 3.8.0'
27
27
  spec.add_development_dependency 'rubocop', '~> 0.39.0'
28
28
 
29
- spec.add_runtime_dependency 'rbnacl', '~> 3.3.0'
29
+ spec.add_runtime_dependency 'rbnacl', '~> 3.3'
30
30
  end
metadata CHANGED
@@ -1,110 +1,123 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: securer_randomer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Mike Pastore
8
- autorequire:
9
+ autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2016-05-11 00:00:00.000000000 Z
12
+ date: 2016-05-12 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
15
+ name: bundler
14
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
15
18
  requirements:
16
- - - "~>"
19
+ - - ~>
17
20
  - !ruby/object:Gem::Version
18
21
  version: '1.11'
19
- name: bundler
20
- prerelease: false
21
22
  type: :development
23
+ prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - "~>"
27
+ - - ~>
25
28
  - !ruby/object:Gem::Version
26
29
  version: '1.11'
27
30
  - !ruby/object:Gem::Dependency
31
+ name: rake
28
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
29
34
  requirements:
30
- - - "~>"
35
+ - - ~>
31
36
  - !ruby/object:Gem::Version
32
37
  version: 11.1.1
33
- name: rake
34
- prerelease: false
35
38
  type: :development
39
+ prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - "~>"
43
+ - - ~>
39
44
  - !ruby/object:Gem::Version
40
45
  version: 11.1.1
41
46
  - !ruby/object:Gem::Dependency
47
+ name: rspec
42
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
43
50
  requirements:
44
- - - "~>"
51
+ - - ~>
45
52
  - !ruby/object:Gem::Version
46
53
  version: '3.0'
47
- name: rspec
48
- prerelease: false
49
54
  type: :development
55
+ prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - "~>"
59
+ - - ~>
53
60
  - !ruby/object:Gem::Version
54
61
  version: '3.0'
55
62
  - !ruby/object:Gem::Dependency
63
+ name: rspec-given
56
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
57
66
  requirements:
58
- - - "~>"
67
+ - - ~>
59
68
  - !ruby/object:Gem::Version
60
69
  version: 3.8.0
61
- name: rspec-given
62
- prerelease: false
63
70
  type: :development
71
+ prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
- - - "~>"
75
+ - - ~>
67
76
  - !ruby/object:Gem::Version
68
77
  version: 3.8.0
69
78
  - !ruby/object:Gem::Dependency
79
+ name: rubocop
70
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
71
82
  requirements:
72
- - - "~>"
83
+ - - ~>
73
84
  - !ruby/object:Gem::Version
74
85
  version: 0.39.0
75
- name: rubocop
76
- prerelease: false
77
86
  type: :development
87
+ prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
- - - "~>"
91
+ - - ~>
81
92
  - !ruby/object:Gem::Version
82
93
  version: 0.39.0
83
94
  - !ruby/object:Gem::Dependency
95
+ name: rbnacl
84
96
  requirement: !ruby/object:Gem::Requirement
97
+ none: false
85
98
  requirements:
86
- - - "~>"
99
+ - - ~>
87
100
  - !ruby/object:Gem::Version
88
- version: 3.3.0
89
- name: rbnacl
90
- prerelease: false
101
+ version: '3.3'
91
102
  type: :runtime
103
+ prerelease: false
92
104
  version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
93
106
  requirements:
94
- - - "~>"
107
+ - - ~>
95
108
  - !ruby/object:Gem::Version
96
- version: 3.3.0
97
- description:
109
+ version: '3.3'
110
+ description:
98
111
  email:
99
112
  - mike@oobak.org
100
113
  executables: []
101
114
  extensions: []
102
115
  extra_rdoc_files: []
103
116
  files:
104
- - ".gitignore"
105
- - ".rspec"
106
- - ".rubocop.yml"
107
- - ".travis.yml"
117
+ - .gitignore
118
+ - .rspec
119
+ - .rubocop.yml
120
+ - .travis.yml
108
121
  - Gemfile
109
122
  - LICENSE.txt
110
123
  - README.md
@@ -119,25 +132,29 @@ files:
119
132
  homepage: https://github.com/mwpastore/securer_randomer
120
133
  licenses:
121
134
  - MIT
122
- metadata: {}
123
- post_install_message:
135
+ post_install_message:
124
136
  rdoc_options: []
125
137
  require_paths:
126
138
  - lib
127
139
  required_ruby_version: !ruby/object:Gem::Requirement
140
+ none: false
128
141
  requirements:
129
- - - ">="
142
+ - - ! '>='
130
143
  - !ruby/object:Gem::Version
131
144
  version: 1.9.3
132
145
  required_rubygems_version: !ruby/object:Gem::Requirement
146
+ none: false
133
147
  requirements:
134
- - - ">="
148
+ - - ! '>='
135
149
  - !ruby/object:Gem::Version
136
150
  version: '0'
151
+ segments:
152
+ - 0
153
+ hash: 1367148123343509472
137
154
  requirements: []
138
- rubyforge_project:
139
- rubygems_version: 2.4.8
140
- signing_key:
141
- specification_version: 4
155
+ rubyforge_project:
156
+ rubygems_version: 1.8.23.2
157
+ signing_key:
158
+ specification_version: 3
142
159
  summary: Monkeypatch SecureRandom with RbNaCl
143
160
  test_files: []
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 7cba7c11c88f376cd4e607ce3257ead37f85627a
4
- data.tar.gz: 9b8f50ff4c3ded6e183525eec67e92f3384ed856
5
- SHA512:
6
- metadata.gz: eb8dc02d517df6ccc33c3ef75faec746f6ed659d8185115bb147cef400d575212637ebc44df23a68fa430f5472a2020086b023cdcb4f186530935d140caf4602
7
- data.tar.gz: f0c6807fad93b80a32318642b16a8ebbb4b43ef090743dbd737283bce4610ddf99a4d5f298ce03a9be682d7e590d1369144fb0f06527200172c293262bcc4e23