Skip to content

Commit 4d6a01c

Browse files
committed
also seen on Random#add; Random#egd shall return true on JVM
1 parent 0045ab7 commit 4d6a01c

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

src/main/java/org/jruby/ext/openssl/Random.java

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)