@@ -47,11 +47,7 @@ private static class Holder {
47
47
private volatile java .util .Random plainRandom ;
48
48
private volatile java .security .SecureRandom secureRandom ;
49
49
50
- //RandomHolder(java.util.Random plainRandom, java.security.SecureRandom secureRandom) {
51
- // this.plainRandom = plainRandom; this.secureRandom = secureRandom;
52
- //}
53
-
54
- final java .util .Random getPlainRandom () {
50
+ java .util .Random getPlainRandom () {
55
51
if (plainRandom == null ) {
56
52
synchronized (this ) {
57
53
if (plainRandom == null ) {
@@ -62,7 +58,7 @@ final java.util.Random getPlainRandom() {
62
58
return plainRandom ;
63
59
}
64
60
65
- final java .security .SecureRandom getSecureRandom () {
61
+ java .security .SecureRandom getSecureRandom () {
66
62
if (secureRandom == null ) {
67
63
synchronized (this ) {
68
64
if (secureRandom == null ) {
@@ -120,51 +116,54 @@ private static int toInt(final Ruby runtime, final IRubyObject arg) {
120
116
121
117
private static RubyString generate (final Ruby runtime ,
122
118
final IRubyObject self , final int len , final boolean secure ) {
123
- final Holder holder = unwrapStruct ( self );
119
+ final Holder holder = retrieveHolder (( RubyModule ) self );
124
120
final byte [] bytes = new byte [len ];
125
121
( secure ? holder .getSecureRandom () : holder .getPlainRandom () ).nextBytes (bytes );
126
122
return RubyString .newString (runtime , new ByteList (bytes , false ));
127
123
}
128
124
129
- private static Holder unwrapStruct (final IRubyObject Random ) {
130
- return (Holder ) (( RubyModule ) Random ) .dataGetStruct ();
125
+ private static Holder retrieveHolder (final RubyModule Random ) {
126
+ return (Holder ) Random .dataGetStruct ();
131
127
}
132
128
133
129
@ JRubyMethod (meta = true ) // seed(str) -> str
134
130
public static IRubyObject seed (final ThreadContext context ,
135
131
final IRubyObject self , IRubyObject str ) {
132
+ seedImpl ((RubyModule ) self , str );
133
+ return str ;
134
+ }
135
+
136
+ private static void seedImpl (final RubyModule Random , final IRubyObject str ) {
136
137
final byte [] seed = str .asString ().getBytes ();
137
- final Holder holder = unwrapStruct ( self );
138
+ final Holder holder = retrieveHolder ( Random );
138
139
139
- holder .getSecureRandom ().setSeed (seed ); // seed supplements existing
140
+ holder .getSecureRandom ().setSeed (seed ); // seed supplements existing (secure) seeding mechanism
140
141
141
142
long s ; int l = seed .length ;
142
143
if ( l >= 4 ) {
143
144
s = (seed [0 ] << 24 ) | (seed [1 ] << 16 ) | (seed [2 ] << 8 ) | seed [3 ];
145
+ if ( l >= 8 ) {
146
+ s = s ^ (seed [l -4 ] << 24 ) | (seed [l -3 ] << 16 ) | (seed [l -2 ] << 8 ) | seed [l -1 ];
147
+ }
144
148
holder .getPlainRandom ().setSeed (s );
145
149
}
146
- return str ;
147
150
}
148
151
149
152
// true if the PRNG has been seeded with enough data, false otherwise
150
153
@ JRubyMethod (meta = true , name = "status?" ) // status? => true | false
151
- public static IRubyObject status_p (final ThreadContext context ,
152
- final IRubyObject self ) {
153
- //final Holder holder = unwrapStruct(self);
154
- //if ( holder.secureRandom == null ) {
155
- // return context.runtime.newBoolean(false); // just a HINT
156
- //}
154
+ public static IRubyObject status_p (final ThreadContext context , final IRubyObject self ) {
157
155
return context .runtime .newBoolean (true );
158
156
}
159
157
160
- // C-Ruby OpenSSL::Random API stubs :
161
-
162
- @ JRubyMethod (meta = true ) // random_add(str, entropy) -> self
158
+ @ JRubyMethod (meta = true , name = { "random_add" , "add" }) // random_add(str, entropy) -> self
163
159
public static IRubyObject random_add (final ThreadContext context ,
164
160
final IRubyObject self , IRubyObject str , IRubyObject entropy ) {
161
+ seedImpl ((RubyModule ) self , str ); // simply ignoring _entropy_ hint
165
162
return self ;
166
163
}
167
164
165
+ // C-Ruby OpenSSL::Random API stubs :
166
+
168
167
@ JRubyMethod (meta = true ) // load_random_file(filename)
169
168
public static IRubyObject load_random_file (final ThreadContext context ,
170
169
final IRubyObject self , IRubyObject fname ) {
@@ -180,13 +179,15 @@ public static IRubyObject write_random_file(final ThreadContext context,
180
179
@ JRubyMethod (meta = true ) // egd(filename) -> true
181
180
public static IRubyObject egd (final ThreadContext context ,
182
181
final IRubyObject self , IRubyObject fname ) {
183
- return context .runtime .getNil ();
182
+ // no-op let the JVM security infrastructure to its internal seeding
183
+ return context .runtime .getTrue ();
184
184
}
185
185
186
186
@ JRubyMethod (meta = true ) // egd_bytes(filename, length) -> true
187
187
public static IRubyObject egd_bytes (final ThreadContext context ,
188
188
final IRubyObject self , IRubyObject fname , IRubyObject len ) {
189
- return context .runtime .getNil ();
189
+ // no-op let the JVM security infrastructure to its internal seeding
190
+ return context .runtime .getTrue ();
190
191
}
191
192
192
193
}
0 commit comments