sysrandom 1.0.0-java

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e24cd46b6417b143899bcec5491ded930fdff1b9
4
+ data.tar.gz: b4c37eded4ec30f2860538b3db047f3b12b5db78
5
+ SHA512:
6
+ metadata.gz: d91f8eb67cfa6c2a070fd06e7e15de5379e172d33d248eecce50e592fc8b1ebf1ab9d0bc22cfaef5380c34da9b8a8f979ee466406ece07270c158bead8976ee9
7
+ data.tar.gz: 708ede372c5493228dcdc63237c398a814df9b4ce47baac08dce981397346f945580cf29931c1dcd6cac2ff9afdb0c07b3d3ae208ae6e519499e3fe630ca40f6
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.so
11
+ *.bundle
12
+ *.dll
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,34 @@
1
+ AllCops:
2
+ DisplayCopNames: true
3
+
4
+ #
5
+ # Style
6
+ #
7
+
8
+ LineLength:
9
+ Max: 128
10
+
11
+ Style/StringLiterals:
12
+ EnforcedStyle: double_quotes
13
+
14
+ Style/SpaceBeforeFirstArg:
15
+ Enabled: false
16
+
17
+ Style/ConditionalAssignment:
18
+ Enabled: false
19
+
20
+ #
21
+ # Metrics
22
+ #
23
+
24
+ Metrics/MethodLength:
25
+ Max: 22
26
+
27
+ Metrics/AbcSize:
28
+ Max: 20
29
+
30
+ AllCops:
31
+ Include:
32
+ - '**/Rakefile'
33
+ Exclude:
34
+ - 'spec/**/*'
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.0
5
+ - 2.1
6
+ - 2.2
7
+ - 2.3.1
8
+ - jruby-9.1.1.0
9
+ before_install: gem install bundler -v 1.12.3
data/CHANGES.md ADDED
@@ -0,0 +1,3 @@
1
+ ## 1.0.0 (2016-05-28)
2
+
3
+ * Initial release.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem "rake"
7
+ gem "rake-compiler"
8
+ gem "rspec"
9
+ gem "rubocop", "= 0.40.0"
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,15 @@
1
+ Copyright (c) 2013-2016
2
+ Frank Denis <j at pureftpd dot org>
3
+ Tony Arcieri <bascule at gmail dot com>
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # Sysrandom
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/sysrandom.svg)](https://rubygems.org/gems/sysrandom)
4
+ [![Build Status](https://secure.travis-ci.org/cryptosphere/sysrandom.svg?branch=master)](https://travis-ci.org/cryptosphere/sysrandom)
5
+ [![ISC licensed](https://img.shields.io/badge/license-ISC-blue.svg)](https://github.com/cryptosphere/sysrandom/blob/master/LICENSE.txt)
6
+
7
+ Secure random number generation for Ruby using system RNG facilities e.g. `/dev/urandom`, `getrandom(2)`
8
+
9
+ ## Description
10
+
11
+ [Concerns have been raised][concerns] about the current implementation of Ruby's built-in
12
+ `SecureRandom` functionality, as it presently leverages the poorly reputed OpenSSL RNG.
13
+
14
+ In cryptography circles, [the prevailing advice is to use OS RNG functionality][/dev/urandom],
15
+ namely `/dev/urandom` or equivalent calls which use an OS-level CSPRNG to
16
+ produce random numbers.
17
+
18
+ This gem provides an easy-to-install repackaging of the `randombytes`
19
+ functionality from [libsodium] for the purpose of generating secure random
20
+ numbers trustworthy for use in cryptographic contexts, such as generating
21
+ cryptographic keys, initialization vectors, or nonces.
22
+
23
+ The following random number generators are utilized:
24
+
25
+ | OS | RNG |
26
+ |---------|-------------------------------------------------------------------|
27
+ | Linux | [getrandom(2)] if available, otherwise [/dev/urandom] |
28
+ | Windows | [RtlGenRandom] |
29
+ | OpenBSD | [arc4random(3)] with ChaCha20 CSPRNG (not RC4) |
30
+ | JRuby | [SecureRandom.getInstanceStrong] if available, otherwise SHA1PRNG |
31
+ | Others | [/dev/urandom] |
32
+
33
+ [concerns]: https://bugs.ruby-lang.org/issues/9569
34
+ [libsodium]: https://github.com/jedisct1/libsodium
35
+ [getrandom(2)]: http://man7.org/linux/man-pages/man2/getrandom.2.html
36
+ [/dev/urandom]: http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
37
+ [RtlGenRandom]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa387694(v=vs.85).aspx
38
+ [arc4random(3)]: http://man.openbsd.org/arc4random.3
39
+ [SecureRandom.getInstanceStrong]: https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html#getInstanceStrong--
40
+
41
+ ## Supported Platforms
42
+
43
+ Sysrandom is tested on the following Ruby implementations:
44
+
45
+ * Ruby (MRI) 2.0, 2.1, 2.2, 2.3
46
+ * JRuby 9.1.1.0
47
+
48
+ ## Installation
49
+
50
+ Add this line to your application's Gemfile:
51
+
52
+ ```ruby
53
+ gem 'sysrandom'
54
+ ```
55
+
56
+ And then execute:
57
+
58
+ $ bundle
59
+
60
+ Or install it yourself as:
61
+
62
+ $ gem install sysrandom
63
+
64
+ ## Usage
65
+
66
+ `Sysrandom` aims to be API-compatible with Ruby's built-in `SecureRandom` class,
67
+ but always prefers OS-level RNG wherever it's available:
68
+
69
+ ```ruby
70
+ >> Sysrandom.random_number(42)
71
+ => 15
72
+ >> Sysrandom.random_bytes(32)
73
+ => "\xD6J\xB3\xD2\x8B\x7F*9D\xB7\xF9\xEA\xE2\\\xAAH\tV#\xEC\x84\xE3E\r\x97\xB9\b\xFCH\x17\xA0\v"
74
+ >> Sysrandom.base64(32)
75
+ => "WXPkxfAuLRpnI6Z4zFb4E+MIenx6w6vKhe01+rMPuIQ="
76
+ >> Sysrandom.urlsafe_base64(32)
77
+ => "37rsMfR4X8g7Bb-uDJEekRHnB3r_7nO03cv52ilaWqE="
78
+ >> Sysrandom.hex(32)
79
+ => "c950496ce200abf7d18eb1414e9206c6335f971a37d0394114f56439b59831ba"
80
+ >> Sysrandom.uuid
81
+ => "391c6f52-8017-4838-9790-131a9b979c63"
82
+ ```
83
+
84
+ * [SecureRandom API docs](http://ruby-doc.org/stdlib-2.0.0/libdoc/securerandom/rdoc/SecureRandom.html)
85
+
86
+ ## Patching SecureRandom with Sysrandom
87
+
88
+ Since Sysrandom is SecureRandom-compatible, it can be patched in-place of
89
+ SecureRandom if you prefer its RNG behavior.
90
+
91
+ To do this, require `sysrandom/securerandom`:
92
+
93
+ ```ruby
94
+ >> SecureRandom
95
+ => SecureRandom
96
+ >> require "sysrandom/securerandom"
97
+ => true
98
+ >> SecureRandom
99
+ => Sysrandom
100
+ >> SecureRandom.hex(32)
101
+ => "d1bbe8c1ab78fc2fe514c5623d913a27ffd2dcdc9e002f3b358bb01a996962f1"
102
+ ```
103
+
104
+ ## Contributing
105
+
106
+ * Fork this repository on Github
107
+ * Make your changes and send a pull request
108
+ * If your changes look good, we'll merge them
109
+
110
+ ## Copyright
111
+
112
+ Copyright (c) 2013-2016 Frank Denis, Tony Arcieri. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "rubocop/rake_task"
4
+ require "rake/clean"
5
+
6
+ unless defined? JRUBY_VERSION
7
+ require "rake/extensiontask"
8
+ Rake::ExtensionTask.new("sysrandom_ext") do |ext|
9
+ ext.ext_dir = "ext/sysrandom"
10
+ end
11
+ end
12
+
13
+ RSpec::Core::RakeTask.new(:spec)
14
+ RuboCop::RakeTask.new
15
+
16
+ default_tasks = %w(spec rubocop)
17
+ default_tasks.unshift("compile") unless defined?(JRUBY_VERSION)
18
+
19
+ task default: default_tasks
20
+
21
+ CLEAN.include "**/*.o", "**/*.so", "**/*.bundle", "pkg", "tmp"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "sysrandom"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,4 @@
1
+ require "mkmf"
2
+
3
+ dir_config "sysrandom_ext"
4
+ create_makefile "sysrandom_ext"
@@ -0,0 +1,275 @@
1
+ /*
2
+ * __randombytes_sysrandom.c: adapted from libsodium
3
+ * Copyright (c) 2013-2016 Frank Denis <j at pureftpd dot org>
4
+ * https://github.com/jedisct1/libsodium
5
+ */
6
+
7
+ #include <stdlib.h>
8
+ #include <sys/types.h>
9
+ #ifndef _WIN32
10
+ # include <sys/stat.h>
11
+ # include <sys/time.h>
12
+ #endif
13
+ #ifdef __linux__
14
+ # include <sys/syscall.h>
15
+ #endif
16
+
17
+ #include <assert.h>
18
+ #include <errno.h>
19
+ #include <fcntl.h>
20
+ #include <limits.h>
21
+ #include <stdint.h>
22
+ #include <string.h>
23
+ #ifndef _WIN32
24
+ # include <unistd.h>
25
+ #endif
26
+
27
+ #ifdef _WIN32
28
+ # include <windows.h>
29
+ # define RtlGenRandom SystemFunction036
30
+ # if defined(__cplusplus)
31
+ extern "C"
32
+ # endif
33
+ BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
34
+ # pragma comment(lib, "advapi32.lib")
35
+ #endif
36
+
37
+ #if defined(__OpenBSD__) || defined(__CloudABI__)
38
+ # define HAVE_SAFE_ARC4RANDOM 1
39
+ #endif
40
+
41
+ #ifndef SSIZE_MAX
42
+ # define SSIZE_MAX (SIZE_MAX / 2 - 1)
43
+ #endif
44
+
45
+ #ifdef HAVE_SAFE_ARC4RANDOM
46
+
47
+ uint32_t
48
+ __randombytes_sysrandom(void)
49
+ {
50
+ return arc4random();
51
+ }
52
+
53
+ static void
54
+ __randombytes_sysrandom_stir(void)
55
+ {
56
+ }
57
+
58
+ void
59
+ __randombytes_sysrandom_buf(void * const buf, const size_t size)
60
+ {
61
+ return arc4random_buf(buf, size);
62
+ }
63
+
64
+ #else /* __OpenBSD__ */
65
+
66
+ typedef struct SysRandom_ {
67
+ int random_data_source_fd;
68
+ int initialized;
69
+ int getrandom_available;
70
+ } SysRandom;
71
+
72
+ static SysRandom stream = {
73
+ .random_data_source_fd = -1,
74
+ .initialized = 0,
75
+ .getrandom_available = 0
76
+ };
77
+
78
+ #ifndef _WIN32
79
+ static ssize_t
80
+ safe_read(const int fd, void * const buf_, size_t size)
81
+ {
82
+ unsigned char *buf = (unsigned char *) buf_;
83
+ ssize_t readnb;
84
+
85
+ assert(size > (size_t) 0U);
86
+ assert(size <= SSIZE_MAX);
87
+ do {
88
+ while ((readnb = read(fd, buf, size)) < (ssize_t) 0 &&
89
+ (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */
90
+ if (readnb < (ssize_t) 0) {
91
+ return readnb; /* LCOV_EXCL_LINE */
92
+ }
93
+ if (readnb == (ssize_t) 0) {
94
+ break; /* LCOV_EXCL_LINE */
95
+ }
96
+ size -= (size_t) readnb;
97
+ buf += readnb;
98
+ } while (size > (ssize_t) 0);
99
+
100
+ return (ssize_t) (buf - (unsigned char *) buf_);
101
+ }
102
+ #endif
103
+
104
+ #ifndef _WIN32
105
+ static int
106
+ __randombytes_sysrandom_random_dev_open(void)
107
+ {
108
+ /* LCOV_EXCL_START */
109
+ struct stat st;
110
+ static const char *devices[] = {
111
+ # ifndef USE_BLOCKING_RANDOM
112
+ "/dev/urandom",
113
+ # endif
114
+ "/dev/random", NULL
115
+ };
116
+ const char ** device = devices;
117
+ int fd;
118
+
119
+ do {
120
+ fd = open(*device, O_RDONLY);
121
+ if (fd != -1) {
122
+ if (fstat(fd, &st) == 0 &&
123
+ # ifdef __COMPCERT__
124
+ 1
125
+ # elif defined(S_ISNAM)
126
+ (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))
127
+ # else
128
+ S_ISCHR(st.st_mode)
129
+ # endif
130
+ ) {
131
+ # if defined(F_SETFD) && defined(FD_CLOEXEC)
132
+ (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
133
+ # endif
134
+ return fd;
135
+ }
136
+ (void) close(fd);
137
+ } else if (errno == EINTR) {
138
+ continue;
139
+ }
140
+ device++;
141
+ } while (*device != NULL);
142
+
143
+ errno = EIO;
144
+ return -1;
145
+ /* LCOV_EXCL_STOP */
146
+ }
147
+
148
+ # ifdef SYS_getrandom
149
+ static int
150
+ _randombytes_linux_getrandom(void * const buf, const size_t size)
151
+ {
152
+ int readnb;
153
+
154
+ assert(size <= 256U);
155
+ do {
156
+ readnb = syscall(SYS_getrandom, buf, (int) size, 0);
157
+ } while (readnb < 0 && (errno == EINTR || errno == EAGAIN));
158
+
159
+ return (readnb == (int) size) - 1;
160
+ }
161
+
162
+ static int
163
+ randombytes_linux_getrandom(void * const buf_, size_t size)
164
+ {
165
+ unsigned char *buf = (unsigned char *) buf_;
166
+ size_t chunk_size = 256U;
167
+
168
+ do {
169
+ if (size < chunk_size) {
170
+ chunk_size = size;
171
+ assert(chunk_size > (size_t) 0U);
172
+ }
173
+ if (_randombytes_linux_getrandom(buf, chunk_size) != 0) {
174
+ return -1;
175
+ }
176
+ size -= chunk_size;
177
+ buf += chunk_size;
178
+ } while (size > (size_t) 0U);
179
+
180
+ return 0;
181
+ }
182
+ # endif
183
+
184
+ static void
185
+ __randombytes_sysrandom_init(void)
186
+ {
187
+ const int errno_save = errno;
188
+
189
+ # ifdef SYS_getrandom
190
+ {
191
+ unsigned char fodder[16];
192
+
193
+ if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) {
194
+ stream.getrandom_available = 1;
195
+ errno = errno_save;
196
+ return;
197
+ }
198
+ stream.getrandom_available = 0;
199
+ }
200
+ # endif
201
+
202
+ if ((stream.random_data_source_fd =
203
+ __randombytes_sysrandom_random_dev_open()) == -1) {
204
+ abort(); /* LCOV_EXCL_LINE */
205
+ }
206
+ errno = errno_save;
207
+ }
208
+
209
+ #else /* _WIN32 */
210
+
211
+ static void
212
+ __randombytes_sysrandom_init(void)
213
+ {
214
+ }
215
+ #endif
216
+
217
+ static void
218
+ __randombytes_sysrandom_stir(void)
219
+ {
220
+ if (stream.initialized == 0) {
221
+ __randombytes_sysrandom_init();
222
+ stream.initialized = 1;
223
+ }
224
+ }
225
+
226
+ static void
227
+ __randombytes_sysrandom_stir_if_needed(void)
228
+ {
229
+ if (stream.initialized == 0) {
230
+ __randombytes_sysrandom_stir();
231
+ }
232
+ }
233
+
234
+ void
235
+ __randombytes_sysrandom_buf(void * const buf, const size_t size)
236
+ {
237
+ __randombytes_sysrandom_stir_if_needed();
238
+ #ifdef ULONG_LONG_MAX
239
+ /* coverity[result_independent_of_operands] */
240
+ assert(size <= ULONG_LONG_MAX);
241
+ #endif
242
+ #ifndef _WIN32
243
+ # ifdef SYS_getrandom
244
+ if (stream.getrandom_available != 0) {
245
+ if (randombytes_linux_getrandom(buf, size) != 0) {
246
+ abort();
247
+ }
248
+ return;
249
+ }
250
+ # endif
251
+ if (stream.random_data_source_fd == -1 ||
252
+ safe_read(stream.random_data_source_fd, buf, size) != (ssize_t) size) {
253
+ abort(); /* LCOV_EXCL_LINE */
254
+ }
255
+ #else
256
+ if (size > (size_t) 0xffffffff) {
257
+ abort(); /* LCOV_EXCL_LINE */
258
+ }
259
+ if (! RtlGenRandom((PVOID) buf, (ULONG) size)) {
260
+ abort(); /* LCOV_EXCL_LINE */
261
+ }
262
+ #endif
263
+ }
264
+
265
+ uint32_t
266
+ __randombytes_sysrandom(void)
267
+ {
268
+ uint32_t r;
269
+
270
+ __randombytes_sysrandom_buf(&r, sizeof r);
271
+
272
+ return r;
273
+ }
274
+
275
+ #endif /* __OpenBSD__ */
@@ -0,0 +1,77 @@
1
+ #include "ruby.h"
2
+
3
+ /* How many bytes to generate by default, matching SecureRandom
4
+ * Why SecureRandom has a default size argument is beyond me */
5
+ #define DEFAULT_N_BYTES 16
6
+
7
+ static VALUE mSysrandom = Qnil;
8
+
9
+ static VALUE Sysrandom_random_uint32(VALUE self);
10
+ static VALUE Sysrandom_random_bytes(int argc, VALUE *argv, VALUE self);
11
+
12
+ /* From randombytes_sysrandom.c */
13
+ uint32_t __randombytes_sysrandom(void);
14
+ void __randombytes_sysrandom_buf(void * const buf, const size_t size);
15
+
16
+ void Init_sysrandom_ext()
17
+ {
18
+ mSysrandom = rb_define_module("Sysrandom");
19
+
20
+ rb_define_singleton_method(mSysrandom, "__random_uint32", Sysrandom_random_uint32, 0);
21
+ rb_define_method(mSysrandom, "__random_uint32", Sysrandom_random_uint32, 0);
22
+
23
+ rb_define_singleton_method(mSysrandom, "random_bytes", Sysrandom_random_bytes, -1);
24
+ rb_define_method(mSysrandom, "random_bytes", Sysrandom_random_bytes, -1);
25
+ }
26
+
27
+ /**
28
+ * call-seq:
29
+ * Sysrandom#__random_uint32 -> Fixnum
30
+ *
31
+ * Generates a random unsigned 32-bit integer using the OS CSPRNG
32
+ *
33
+ */
34
+ static VALUE
35
+ Sysrandom_random_uint32(VALUE self)
36
+ {
37
+ return UINT2NUM(__randombytes_sysrandom());
38
+ }
39
+
40
+ /**
41
+ * call-seq:
42
+ * Sysrandom#random_bytes(n=nil) -> String
43
+ *
44
+ * ::random_bytes generates a random binary string via the OS CSPRNG.
45
+ *
46
+ * The argument n specifies how long the resulting string should be.
47
+ *
48
+ * For compatibility with SecureRandom, if n is not specified, 16 is assumed.
49
+ *
50
+ * The resulting string may contain any byte (i.e. "x00" - "xff")
51
+ *
52
+ */
53
+ static VALUE
54
+ Sysrandom_random_bytes(int argc, VALUE * argv, VALUE self)
55
+ {
56
+ VALUE n_obj, str;
57
+ int n;
58
+
59
+ if (rb_scan_args(argc, argv, "01", &n_obj) == 1) {
60
+ n = NUM2INT(n_obj);
61
+
62
+ if(n < 0) {
63
+ rb_raise(rb_eArgError, "negative string size");
64
+ }
65
+ } else {
66
+ n = DEFAULT_N_BYTES;
67
+ }
68
+
69
+ if(n > 0) {
70
+ str = rb_str_new(0, n);
71
+ __randombytes_sysrandom_buf(RSTRING_PTR(str), n);
72
+ } else {
73
+ str = rb_str_new2("");
74
+ }
75
+
76
+ return str;
77
+ }
@@ -0,0 +1,7 @@
1
+ require "sysrandom"
2
+
3
+ # Make sure SecureRandom has been loaded before we patch it
4
+ require "securerandom"
5
+
6
+ Object.send(:remove_const, :SecureRandom)
7
+ SecureRandom = Sysrandom
@@ -0,0 +1,3 @@
1
+ module Sysrandom
2
+ VERSION = "1.0.0".freeze
3
+ end
data/lib/sysrandom.rb ADDED
@@ -0,0 +1,64 @@
1
+ require "sysrandom/version"
2
+
3
+ require "base64"
4
+
5
+ # Secure random number generation using system RNG facilities
6
+ module Sysrandom
7
+ module_function
8
+
9
+ # For some reason SecureRandom defaults to 16 bytes
10
+ DEFAULT_LENGTH = 16
11
+
12
+ if defined?(JRUBY_VERSION)
13
+ require "java"
14
+
15
+ if java.security.SecureRandom.respond_to?(:getInstanceStrong)
16
+ @_java_secure_random = java.security.SecureRandom.getInstanceStrong
17
+ else
18
+ @_java_secure_random = java.security.SecureRandom.getInstance("SHA1PRNG")
19
+ end
20
+
21
+ # Random uint32, used by random_number. The C extension provides an equivalent method
22
+ def __random_uint32
23
+ @_java_secure_random.nextLong & 0xFFFFFFFF
24
+ end
25
+
26
+ def random_bytes(n = DEFAULT_LENGTH)
27
+ raise ArgumentError, "negative string size" if n < 0
28
+
29
+ bytes = Java::byte[n].new
30
+ @_java_secure_random.nextBytes(bytes)
31
+ String.from_java_bytes(bytes)
32
+ end
33
+ else
34
+ require "sysrandom_ext"
35
+ end
36
+
37
+ def random_number(n = 0)
38
+ result = __random_uint32 / (2**32).to_f
39
+
40
+ if n <= 0
41
+ result
42
+ else
43
+ result *= n
44
+ n.is_a?(Fixnum) ? result.floor : result
45
+ end
46
+ end
47
+
48
+ def base64(n = DEFAULT_LENGTH)
49
+ Base64.encode64(random_bytes(n)).chomp
50
+ end
51
+
52
+ def urlsafe_base64(n = DEFAULT_LENGTH)
53
+ Base64.urlsafe_encode64(random_bytes(n)).chomp
54
+ end
55
+
56
+ def hex(n = DEFAULT_LENGTH)
57
+ random_bytes(n).unpack("h*").first
58
+ end
59
+
60
+ def uuid
61
+ values = SecureRandom.hex(16).match(/\A(.{8})(.{4})(.)(.{3})(.)(.{3})(.{12})\z/)
62
+ "#{values[1]}-#{values[2]}-4#{values[4]}-#{'89ab'[values[5].ord % 4]}#{values[6]}-#{values[7]}"
63
+ end
64
+ end
data/sysrandom.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "sysrandom/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "sysrandom"
7
+ spec.version = Sysrandom::VERSION
8
+ spec.authors = ["Tony Arcieri"]
9
+ spec.email = ["bascule@gmail.com"]
10
+
11
+ spec.summary = "Secure random number generation using system RNG facilities"
12
+ spec.description = "Sysrandom generates secure random numbers using /dev/urandom, getrandom(), etc"
13
+ spec.homepage = "https://github.com/cryptosphere/sysrandom"
14
+ spec.licenses = ["ISC"]
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ if defined? JRUBY_VERSION
22
+ spec.platform = "java"
23
+ else
24
+ spec.extensions = ["ext/sysrandom/extconf.rb"]
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sysrandom
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: java
6
+ authors:
7
+ - Tony Arcieri
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-05-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Sysrandom generates secure random numbers using /dev/urandom, getrandom(), etc
14
+ email:
15
+ - bascule@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - ".rspec"
22
+ - ".rubocop.yml"
23
+ - ".travis.yml"
24
+ - CHANGES.md
25
+ - Gemfile
26
+ - LICENSE.txt
27
+ - README.md
28
+ - Rakefile
29
+ - bin/console
30
+ - bin/setup
31
+ - ext/sysrandom/extconf.rb
32
+ - ext/sysrandom/randombytes_sysrandom.c
33
+ - ext/sysrandom/sysrandom_ext.c
34
+ - lib/sysrandom.rb
35
+ - lib/sysrandom/securerandom.rb
36
+ - lib/sysrandom/version.rb
37
+ - sysrandom.gemspec
38
+ homepage: https://github.com/cryptosphere/sysrandom
39
+ licenses:
40
+ - ISC
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 2.4.8
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: Secure random number generation using system RNG facilities
62
+ test_files: []