Skip to content

Commit 2e087c4

Browse files
committed
[fix] support getting password from block for PKeys
1 parent 24ba8fe commit 2e087c4

File tree

5 files changed

+54
-34
lines changed

5 files changed

+54
-34
lines changed

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.jruby.RubyString;
4949
import org.jruby.anno.JRubyMethod;
5050
import org.jruby.exceptions.RaiseException;
51+
import org.jruby.runtime.Block;
5152
import org.jruby.runtime.ObjectAllocator;
5253
import org.jruby.runtime.ThreadContext;
5354
import org.jruby.runtime.builtin.IRubyObject;
@@ -203,11 +204,16 @@ public IRubyObject initialize(ThreadContext context) {
203204

204205
public abstract RubyString to_der() ;
205206

206-
public abstract RubyString to_pem(final IRubyObject[] args) ;
207+
public abstract RubyString to_pem(ThreadContext context, final IRubyObject[] args) ;
208+
209+
@Deprecated
210+
public RubyString to_pem(final IRubyObject[] args) {
211+
return to_pem(getRuntime().getCurrentContext(), args);
212+
}
207213

208214
@Deprecated
209215
public RubyString export(final IRubyObject[] args) {
210-
return to_pem(args);
216+
return to_pem(getRuntime().getCurrentContext(), args);
211217
}
212218

213219
@JRubyMethod(name = "sign")
@@ -359,13 +365,24 @@ protected static CipherSpec cipherSpec(final IRubyObject cipher) {
359365
return null;
360366
}
361367

368+
@Deprecated
362369
protected static char[] password(final IRubyObject pass) {
363370
if ( pass != null && ! pass.isNil() ) {
364371
return pass.toString().toCharArray();
365372
}
366373
return null;
367374
}
368375

376+
protected static char[] password(final ThreadContext context, IRubyObject pass, final Block block) {
377+
if (pass != null && !pass.isNil()) { // argument takes precedence (instead of block)
378+
return pass.toString().toCharArray();
379+
}
380+
if (block != null && block.isGiven()) {
381+
return password(context, block.call(context), null);
382+
}
383+
return null;
384+
}
385+
369386
protected static char[] passwordPrompt(final ThreadContext context) {
370387
return passwordPrompt(context, "Enter PEM pass phrase:");
371388
}
@@ -376,7 +393,7 @@ protected static char[] passwordPrompt(final ThreadContext context, final String
376393
Kernel.callMethod("print", context.runtime.newString(prompt));
377394
final RubyString gets = Kernel.callMethod(context, "gets").convertToString();
378395
gets.chomp_bang(context);
379-
return gets.toString().toCharArray();
396+
return gets.decodeString().toCharArray();
380397
}
381398

382399
protected static boolean ttySTDIN(final ThreadContext context) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ public RubyBoolean private_p() {
288288

289289
@Override
290290
@JRubyMethod(name = { "to_pem", "to_s" }, alias = "export", rest = true)
291-
public RubyString to_pem(final IRubyObject[] args) {
291+
public RubyString to_pem(ThreadContext context, final IRubyObject[] args) {
292292
//Arity.checkArgumentCount(getRuntime(), args, 0, 2);
293293

294294
//CipherSpec spec = null; char[] passwd = null;

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import org.jruby.ext.openssl.impl.CipherSpec;
5353
import org.jruby.ext.openssl.x509store.PEMInputOutput;
5454
import org.jruby.runtime.Arity;
55+
import org.jruby.runtime.Block;
5556
import org.jruby.runtime.ObjectAllocator;
5657
import org.jruby.runtime.builtin.IRubyObject;
5758
import org.jruby.runtime.ThreadContext;
@@ -172,22 +173,22 @@ static PKeyDSA newInstance(final Ruby runtime, final PublicKey publicKey) {
172173
}
173174

174175
@JRubyMethod(rest = true, visibility = Visibility.PRIVATE)
175-
public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) {
176+
public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args, final Block block) {
176177
final Ruby runtime = context.runtime;
177178

178179
if ( Arity.checkArgumentCount(runtime, args, 0, 2) == 0 ) {
179180
this.privateKey = null; this.publicKey = null; return this;
180181
}
181182

182-
IRubyObject arg = args[0]; IRubyObject pass = null;
183-
if ( args.length > 1 ) pass = args[1];
183+
IRubyObject arg = args[0];
184+
IRubyObject arg1 = args.length > 1 ? args[1] : null; // password (String)
184185

185186
if ( arg instanceof RubyFixnum ) {
186187
int keySize = RubyNumeric.fix2int((RubyFixnum) arg);
187188
return dsaGenerate(context.runtime, this, keySize);
188189
}
189190

190-
final char[] passwd = password(pass);
191+
final char[] passwd = password(context, arg1, block);
191192
final RubyString str = readInitArg(context, arg);
192193
final String strJava = str.toString();
193194

@@ -343,13 +344,13 @@ public PKeyDSA public_key() {
343344

344345
@Override
345346
@JRubyMethod(name = { "to_pem", "to_s" }, alias = "export", rest = true)
346-
public RubyString to_pem(final IRubyObject[] args) {
347-
Arity.checkArgumentCount(getRuntime(), args, 0, 2);
347+
public RubyString to_pem(final ThreadContext context, final IRubyObject[] args) {
348+
Arity.checkArgumentCount(context.runtime, args, 0, 2);
348349

349350
CipherSpec spec = null; char[] passwd = null;
350351
if ( args.length > 0 ) {
351352
spec = cipherSpec( args[0] );
352-
if ( args.length > 1 ) passwd = password(args[1]);
353+
if ( args.length > 1 ) passwd = password(context, args[1], null);
353354
}
354355

355356
try {
@@ -360,13 +361,13 @@ public RubyString to_pem(final IRubyObject[] args) {
360361
else {
361362
PEMInputOutput.writeDSAPublicKey(writer, publicKey);
362363
}
363-
return RubyString.newString(getRuntime(), writer.getBuffer());
364+
return RubyString.newString(context.runtime, writer.getBuffer());
364365
}
365366
catch (NoClassDefFoundError ncdfe) {
366-
throw newDSAError(getRuntime(), bcExceptionMessage(ncdfe));
367+
throw newDSAError(context.runtime, bcExceptionMessage(ncdfe));
367368
}
368369
catch (IOException e) {
369-
throw newDSAError(getRuntime(), e.getMessage(), e);
370+
throw newDSAError(context.runtime, e.getMessage(), e);
370371
}
371372
}
372373

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import org.jruby.anno.JRubyMethod;
6060
import org.jruby.exceptions.RaiseException;
6161
import org.jruby.runtime.Arity;
62+
import org.jruby.runtime.Block;
6263
import org.jruby.runtime.ObjectAllocator;
6364
import org.jruby.runtime.ThreadContext;
6465
import org.jruby.runtime.Visibility;
@@ -222,7 +223,7 @@ public PKeyEC(Ruby runtime, RubyClass type) {
222223
public String getAlgorithm() { return "EC"; }
223224

224225
@JRubyMethod(rest = true, visibility = Visibility.PRIVATE)
225-
public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) {
226+
public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args, Block block) {
226227
final Ruby runtime = context.runtime;
227228

228229
privateKey = null; publicKey = null;
@@ -241,7 +242,7 @@ public IRubyObject initialize(final ThreadContext context, final IRubyObject[] a
241242

242243
IRubyObject pass = null;
243244
if ( args.length > 1 ) pass = args[1];
244-
final char[] passwd = password(pass);
245+
final char[] passwd = password(context, pass, block);
245246
final RubyString str = readInitArg(context, arg);
246247
final String strJava = str.toString();
247248

@@ -597,13 +598,13 @@ private byte[] toDER() throws IOException {
597598

598599
@Override
599600
@JRubyMethod(name = "to_pem", alias = "export", rest = true)
600-
public RubyString to_pem(final IRubyObject[] args) {
601-
Arity.checkArgumentCount(getRuntime(), args, 0, 2);
601+
public RubyString to_pem(ThreadContext context, final IRubyObject[] args) {
602+
Arity.checkArgumentCount(context.runtime, args, 0, 2);
602603

603604
CipherSpec spec = null; char[] passwd = null;
604605
if ( args.length > 0 ) {
605606
spec = cipherSpec( args[0] );
606-
if ( args.length > 1 ) passwd = password( args[1] );
607+
if ( args.length > 1 ) passwd = password(context, args[1], null);
607608
}
608609

609610
try {
@@ -614,10 +615,10 @@ public RubyString to_pem(final IRubyObject[] args) {
614615
else {
615616
PEMInputOutput.writeECPublicKey(writer, publicKey);
616617
}
617-
return RubyString.newString(getRuntime(), writer.getBuffer());
618+
return RubyString.newString(context.runtime, writer.getBuffer());
618619
}
619620
catch (IOException ex) {
620-
throw newECError(getRuntime(), ex.getMessage());
621+
throw newECError(context.runtime, ex.getMessage());
621622
}
622623
}
623624

@@ -742,7 +743,7 @@ public RubyString to_pem(final ThreadContext context, final IRubyObject[] args)
742743
CipherSpec spec = null; char[] passwd = null;
743744
if ( args.length > 0 ) {
744745
spec = cipherSpec( args[0] );
745-
if ( args.length > 1 ) passwd = password(args[1]);
746+
if ( args.length > 1 ) passwd = password(context, args[1], null);
746747
}
747748

748749
try {

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import org.jruby.anno.JRubyMethod;
6363
import org.jruby.exceptions.RaiseException;
6464
import org.jruby.runtime.Arity;
65+
import org.jruby.runtime.Block;
6566
import org.jruby.runtime.ObjectAllocator;
6667
import org.jruby.runtime.ThreadContext;
6768
import org.jruby.runtime.builtin.IRubyObject;
@@ -218,26 +219,26 @@ static PKeyRSA newInstance(final Ruby runtime, final PublicKey publicKey) {
218219
}
219220

220221
@JRubyMethod(rest = true, visibility = Visibility.PRIVATE)
221-
public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) {
222+
public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args, final Block block) {
222223
final Ruby runtime = context.runtime;
223224

224225
if ( Arity.checkArgumentCount(runtime, args, 0, 2) == 0 ) {
225226
privateKey = null; publicKey = null; return this;
226227
}
227228

228-
IRubyObject arg = args[0]; IRubyObject pass = null;
229-
if ( args.length > 1 ) pass = args[1];
229+
IRubyObject arg = args[0];
230+
IRubyObject arg1 = args.length > 1 ? args[1] : null; // exponent (Fixnum) or password (String)
230231

231232
if ( arg instanceof RubyFixnum ) {
232233
int keySize = RubyNumeric.fix2int((RubyFixnum) arg);
233234
BigInteger exp = RSAKeyGenParameterSpec.F4;
234-
if ( pass != null && ! pass.isNil() ) {
235-
exp = BigInteger.valueOf(RubyNumeric.num2long(pass));
235+
if (arg1 != null && !arg1.isNil()) {
236+
exp = BigInteger.valueOf(RubyNumeric.num2long(arg1));
236237
}
237238
return rsaGenerate(runtime, this, keySize, exp);
238239
}
239240

240-
final char[] passwd = password(pass);
241+
final char[] passwd = password(context, arg1, block);
241242
final RubyString str = readInitArg(context, arg);
242243
final String strJava = str.toString();
243244

@@ -434,13 +435,13 @@ public RubyString to_text() {
434435

435436
@Override
436437
@JRubyMethod(name = { "to_pem", "to_s" }, alias = "export", rest = true)
437-
public RubyString to_pem(final IRubyObject[] args) {
438-
Arity.checkArgumentCount(getRuntime(), args, 0, 2);
438+
public RubyString to_pem(ThreadContext context, final IRubyObject[] args) {
439+
Arity.checkArgumentCount(context.runtime, args, 0, 2);
439440

440441
CipherSpec spec = null; char[] passwd = null;
441442
if ( args.length > 0 ) {
442443
spec = cipherSpec( args[0] );
443-
if ( args.length > 1 ) passwd = password(args[1]);
444+
if ( args.length > 1 ) passwd = password(context, args[1], null);
444445
}
445446

446447
try {
@@ -451,13 +452,13 @@ public RubyString to_pem(final IRubyObject[] args) {
451452
else {
452453
PEMInputOutput.writeRSAPublicKey(writer, publicKey);
453454
}
454-
return RubyString.newString(getRuntime(), writer.getBuffer());
455+
return RubyString.newString(context.runtime, writer.getBuffer());
455456
}
456457
catch (NoClassDefFoundError ncdfe) {
457-
throw newRSAError(getRuntime(), bcExceptionMessage(ncdfe));
458+
throw newRSAError(context.runtime, bcExceptionMessage(ncdfe));
458459
}
459460
catch (IOException ioe) {
460-
throw newRSAError(getRuntime(), ioe.getMessage());
461+
throw newRSAError(context.runtime, ioe.getMessage());
461462
}
462463
}
463464

0 commit comments

Comments
 (0)