@@ -47,11 +47,7 @@ private static class Holder {
4747 private volatile java .util .Random plainRandom ;
4848 private volatile java .security .SecureRandom secureRandom ;
4949
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 () {
5551 if (plainRandom == null ) {
5652 synchronized (this ) {
5753 if (plainRandom == null ) {
@@ -62,7 +58,7 @@ final java.util.Random getPlainRandom() {
6258 return plainRandom ;
6359 }
6460
65- final java .security .SecureRandom getSecureRandom () {
61+ java .security .SecureRandom getSecureRandom () {
6662 if (secureRandom == null ) {
6763 synchronized (this ) {
6864 if (secureRandom == null ) {
@@ -120,51 +116,54 @@ private static int toInt(final Ruby runtime, final IRubyObject arg) {
120116
121117 private static RubyString generate (final Ruby runtime ,
122118 final IRubyObject self , final int len , final boolean secure ) {
123- final Holder holder = unwrapStruct ( self );
119+ final Holder holder = retrieveHolder (( RubyModule ) self );
124120 final byte [] bytes = new byte [len ];
125121 ( secure ? holder .getSecureRandom () : holder .getPlainRandom () ).nextBytes (bytes );
126122 return RubyString .newString (runtime , new ByteList (bytes , false ));
127123 }
128124
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 ();
131127 }
132128
133129 @ JRubyMethod (meta = true ) // seed(str) -> str
134130 public static IRubyObject seed (final ThreadContext context ,
135131 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 ) {
136137 final byte [] seed = str .asString ().getBytes ();
137- final Holder holder = unwrapStruct ( self );
138+ final Holder holder = retrieveHolder ( Random );
138139
139- holder .getSecureRandom ().setSeed (seed ); // seed supplements existing
140+ holder .getSecureRandom ().setSeed (seed ); // seed supplements existing (secure) seeding mechanism
140141
141142 long s ; int l = seed .length ;
142143 if ( l >= 4 ) {
143144 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+ }
144148 holder .getPlainRandom ().setSeed (s );
145149 }
146- return str ;
147150 }
148151
149152 // true if the PRNG has been seeded with enough data, false otherwise
150153 @ 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 ) {
157155 return context .runtime .newBoolean (true );
158156 }
159157
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
163159 public static IRubyObject random_add (final ThreadContext context ,
164160 final IRubyObject self , IRubyObject str , IRubyObject entropy ) {
161+ seedImpl ((RubyModule ) self , str ); // simply ignoring _entropy_ hint
165162 return self ;
166163 }
167164
165+ // C-Ruby OpenSSL::Random API stubs :
166+
168167 @ JRubyMethod (meta = true ) // load_random_file(filename)
169168 public static IRubyObject load_random_file (final ThreadContext context ,
170169 final IRubyObject self , IRubyObject fname ) {
@@ -180,13 +179,15 @@ public static IRubyObject write_random_file(final ThreadContext context,
180179 @ JRubyMethod (meta = true ) // egd(filename) -> true
181180 public static IRubyObject egd (final ThreadContext context ,
182181 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 ();
184184 }
185185
186186 @ JRubyMethod (meta = true ) // egd_bytes(filename, length) -> true
187187 public static IRubyObject egd_bytes (final ThreadContext context ,
188188 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 ();
190191 }
191192
192193}
0 commit comments