Skip to content

Commit af64ffd

Browse files
committed
[fix] make sure Context.ciphers are not mutated
when setting an invalid ciphers value (closing #219)
1 parent 4365585 commit af64ffd

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

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

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -518,26 +518,26 @@ public IRubyObject setup(final ThreadContext context) {
518518

519519
@JRubyMethod
520520
public RubyArray ciphers(final ThreadContext context) { // SSL_CTX_get_ciphers
521-
return matchedCiphersWithCache(context);
521+
return matchedCiphersWithCache(context, this.ciphers);
522522
}
523523

524-
private RubyArray matchedCiphersWithCache(final ThreadContext context) {
524+
private RubyArray matchedCiphersWithCache(final ThreadContext context, final String ciphers) {
525525
final CipherListCache cache = cipherListCache;
526526
if ( protocol.equals(cache.protocol) && ciphers.equals(cache.ciphers) ) {
527527
return newSharedArray(cache.cipherList);
528528
}
529529

530-
final RubyArray match = matchedCiphers(context);
530+
final RubyArray match = matchedCiphers(context, ciphers);
531531
cipherListCache = new CipherListCache(protocol, ciphers, match);
532532
return newSharedArray(match);
533533
}
534534

535-
private RubyArray matchedCiphers(final ThreadContext context) {
535+
private RubyArray matchedCiphers(final ThreadContext context, final String ciphers) {
536536
final Ruby runtime = context.runtime;
537537
try {
538538
final String[] supported = getSupportedCipherSuites(context, protocol);
539539
final Collection<CipherStrings.Def> cipherDefs =
540-
CipherStrings.matchingCiphers(this.ciphers, supported, false);
540+
CipherStrings.matchingCiphers(ciphers, supported, false);
541541

542542
final IRubyObject[] cipherList = new IRubyObject[ cipherDefs.size() ];
543543

@@ -562,8 +562,9 @@ private static RubyArray newSharedArray(RubyArray array) {
562562

563563
@JRubyMethod(name = "ciphers=")
564564
public IRubyObject set_ciphers(final ThreadContext context, final IRubyObject ciphers) {
565+
String cipherString;
565566
if ( ciphers.isNil() ) {
566-
this.ciphers = CipherStrings.SSL_DEFAULT_CIPHER_LIST;
567+
cipherString = CipherStrings.SSL_DEFAULT_CIPHER_LIST;
567568
}
568569
else if ( ciphers instanceof RubyArray ) {
569570
final RubyArray ciphs = (RubyArray) ciphers;
@@ -581,20 +582,23 @@ else if ( ciphers instanceof RubyArray ) {
581582
cipherStr.append(sep).append( elem.toString() );
582583
sep = ":";
583584
}
584-
this.ciphers = cipherStr.toString();
585+
cipherString = cipherStr.toString();
585586
}
586587
else {
587-
this.ciphers = ciphers.asString().toString();
588+
cipherString = ciphers.asString().toString();
588589
}
589590

590-
if (this.ciphers.equals(CipherStrings.SSL_DEFAULT_CIPHER_LIST)) {
591-
this.ciphers = CipherStrings.SSL_DEFAULT_CIPHER_LIST; // due caching
591+
if (cipherString.equals(CipherStrings.SSL_DEFAULT_CIPHER_LIST)) {
592+
cipherString = CipherStrings.SSL_DEFAULT_CIPHER_LIST; // due caching
592593
}
593594

594-
if ( matchedCiphersWithCache(context).isEmpty() ) {
595+
System.out.println("cipherString: " + cipherString + " " + matchedCiphersWithCache(context, cipherString).isEmpty());
596+
597+
if ( matchedCiphersWithCache(context, cipherString).isEmpty() ) {
595598
throw newSSLError(context.runtime, "no cipher match");
596599
}
597600

601+
this.ciphers = cipherString;
598602
return ciphers;
599603
}
600604

src/test/ruby/ssl/test_context.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,16 @@ def test_set_ciphers_empty_array
232232
assert_include ex.message, "no cipher match"
233233
end
234234

235+
def test_invalid_ciphers_does_not_mutate_context
236+
context = OpenSSL::SSL::SSLContext.new
237+
ciphers = context.ciphers
238+
assert !ciphers.empty?
239+
begin
240+
context.ciphers = ['AES256-SHA123']
241+
fail 'raise expected'
242+
rescue OpenSSL::SSL::SSLError
243+
end
244+
assert_equal context.ciphers, ciphers
245+
end
246+
235247
end

0 commit comments

Comments
 (0)