4343import java .util .LinkedHashMap ;
4444import java .util .List ;
4545import java .util .Map ;
46- import static javax .crypto .Cipher .DECRYPT_MODE ;
47- import static javax .crypto .Cipher .ENCRYPT_MODE ;
4846import javax .crypto .NoSuchPaddingException ;
4947import javax .crypto .spec .GCMParameterSpec ;
5048import javax .crypto .spec .IvParameterSpec ;
7068import org .jruby .util .ByteList ;
7169import org .jruby .util .TypeConverter ;
7270
71+ import static javax .crypto .Cipher .DECRYPT_MODE ;
72+ import static javax .crypto .Cipher .ENCRYPT_MODE ;
7373import static org .jruby .ext .openssl .OpenSSL .*;
7474
7575/**
@@ -142,7 +142,7 @@ static RubyClass _Cipher(final Ruby runtime) {
142142 public static IRubyObject ciphers (final ThreadContext context , final IRubyObject self ) {
143143 final Ruby runtime = context .runtime ;
144144
145- final Collection <String > ciphers = Algorithm .allSupportedCiphers () .keySet ();
145+ final Collection <String > ciphers = Algorithm .AllSupportedCiphers . CIPHERS_MAP .keySet ();
146146 final RubyArray result = runtime .newArray ( ciphers .size () * 2 );
147147 for ( final String cipher : ciphers ) {
148148 result .append ( runtime .newString (cipher ) ); // upper-case
@@ -156,7 +156,7 @@ public static IRubyObject ciphers(final ThreadContext context, final IRubyObject
156156 public static boolean isSupportedCipher (final String name ) {
157157 final String osslName = name .toUpperCase ();
158158 //
159- if ( Algorithm .allSupportedCiphers () .get ( osslName ) != null ) {
159+ if ( Algorithm .AllSupportedCiphers . CIPHERS_MAP .get ( osslName ) != null ) {
160160 return true ;
161161 }
162162 //
@@ -273,125 +273,115 @@ public static final class Algorithm {
273273 NO_PADDING_BLOCK_MODES .add ("GCM" );
274274 }
275275
276- // Ruby to Java name String (or FALSE)
277- static final HashMap <String , String []> supportedCiphers = new LinkedHashMap <String , String []>(120 , 1 );
278- // we're _marking_ unsupported keys with a Boolean.FALSE mapping
279- // all cipher mappings are resolved on `OpenSSL::Cipher.ciphers`
280- // ... probably a slightly _rare_ case to be going for up front
281- static boolean supportedCiphersAll ;
282-
283- static Map <String , String []> allSupportedCiphers () {
284- if ( supportedCiphersAll ) return supportedCiphers ;
285- synchronized ( supportedCiphers ) {
286- if ( supportedCiphersAll ) return supportedCiphers ;
276+ final static class AllSupportedCiphers {
287277
278+ // Ruby to Java name String
279+ static final HashMap <String , String []> CIPHERS_MAP = new LinkedHashMap <String , String []>(120 , 1 );
280+ static {
288281 // cleanup all FALSE keys :
289282 //for ( String key: supportedCiphers.keySet() ) {
290- //if ( supportedCiphers.get(key) == Boolean.FALSE ) supportedCiphers.remove(key);
283+ //if ( supportedCiphers.get(key) == Boolean.FALSE ) supportedCiphers.remove(key);
291284 //}
292285
293286 // OpenSSL: all the block ciphers normally use PKCS#5 padding
294287 String [] modes ;
295288 modes = cipherModes ("AES" ); // null if not supported
296- if ( modes != null ) {
297- for ( final String mode : modes ) {
289+ if (modes != null ) {
290+ for (final String mode : modes ) {
298291 final String realName = "AES/" + mode ; // + "/PKCS5Padding"
299- supportedCiphers .put ( "AES-128-" + mode , new String [] { "AES" , mode , "128" , realName } );
300- supportedCiphers .put ( "AES-192-" + mode , new String [] { "AES" , mode , "192" , realName } );
301- supportedCiphers .put ( "AES-256-" + mode , new String [] { "AES" , mode , "256" , realName } );
292+ CIPHERS_MAP .put ("AES-128-" + mode , new String []{ "AES" , mode , "128" , realName } );
293+ CIPHERS_MAP .put ("AES-192-" + mode , new String []{ "AES" , mode , "192" , realName } );
294+ CIPHERS_MAP .put ("AES-256-" + mode , new String []{ "AES" , mode , "256" , realName } );
302295 }
303296 final String realName = "AES/CBC" ;
304- supportedCiphers .put ( "AES128" , new String [] { "AES" , "CBC" , "128" , realName } );
305- supportedCiphers .put ( "AES192" , new String [] { "AES" , "CBC" , "192" , realName } );
306- supportedCiphers .put ( "AES256" , new String [] { "AES" , "CBC" , "256" , realName } );
297+ CIPHERS_MAP .put ("AES128" , new String []{ "AES" , "CBC" , "128" , realName } );
298+ CIPHERS_MAP .put ("AES192" , new String []{ "AES" , "CBC" , "192" , realName } );
299+ CIPHERS_MAP .put ("AES256" , new String []{ "AES" , "CBC" , "256" , realName } );
307300 }
308301
309302 modes = cipherModes ("Blowfish" );
310- if ( modes != null ) {
311- supportedCiphers .put ( "BF" , new String [] { "BF" , "CBC" , null , "Blowfish/CBC" });
312- for ( final String mode : modes ) {
313- supportedCiphers .put ( "BF-" + mode , new String [] { "BF" , mode , null , "Blowfish/" + mode } );
303+ if (modes != null ) {
304+ CIPHERS_MAP .put ("BF" , new String []{ "BF" , "CBC" , null , "Blowfish/CBC" });
305+ for (final String mode : modes ) {
306+ CIPHERS_MAP .put ("BF-" + mode , new String []{ "BF" , mode , null , "Blowfish/" + mode } );
314307 }
315308 }
316309
317310 modes = cipherModes ("Camellia" );
318- if ( modes != null ) {
319- for ( final String mode : modes ) {
311+ if (modes != null ) {
312+ for (final String mode : modes ) {
320313 final String realName = "Camellia/" + mode ;
321- supportedCiphers .put ( "CAMELLIA-128-" + mode , new String [] { "CAMELLIA" , mode , "128" , realName } );
322- supportedCiphers .put ( "CAMELLIA-192-" + mode , new String [] { "CAMELLIA" , mode , "192" , realName } );
323- supportedCiphers .put ( "CAMELLIA-256-" + mode , new String [] { "CAMELLIA" , mode , "256" , realName } );
314+ CIPHERS_MAP .put ("CAMELLIA-128-" + mode , new String []{ "CAMELLIA" , mode , "128" , realName } );
315+ CIPHERS_MAP .put ("CAMELLIA-192-" + mode , new String []{ "CAMELLIA" , mode , "192" , realName } );
316+ CIPHERS_MAP .put ("CAMELLIA-256-" + mode , new String []{ "CAMELLIA" , mode , "256" , realName } );
324317 }
325318 final String realName = "Camellia/CBC" ;
326- supportedCiphers .put ( "CAMELLIA128" , new String [] { "CAMELLIA" , "CBC" , "128" , realName } );
327- supportedCiphers .put ( "CAMELLIA192" , new String [] { "CAMELLIA" , "CBC" , "192" , realName } );
328- supportedCiphers .put ( "CAMELLIA256" , new String [] { "CAMELLIA" , "CBC" , "256" , realName } );
319+ CIPHERS_MAP .put ("CAMELLIA128" , new String []{ "CAMELLIA" , "CBC" , "128" , realName } );
320+ CIPHERS_MAP .put ("CAMELLIA192" , new String []{ "CAMELLIA" , "CBC" , "192" , realName } );
321+ CIPHERS_MAP .put ("CAMELLIA256" , new String []{ "CAMELLIA" , "CBC" , "256" , realName } );
329322 }
330323
331324 modes = cipherModes ("CAST5" );
332- if ( modes != null ) {
333- supportedCiphers .put ( "CAST" , new String [] { "CAST" , "CBC" , null , "CAST5/CBC" } );
334- supportedCiphers .put ( "CAST-CBC" , supportedCiphers .get ("CAST" ) );
335- for ( final String mode : modes ) {
336- supportedCiphers .put ( "CAST5-" + mode , new String [] { "CAST" , mode , null , "CAST5/" + mode });
325+ if (modes != null ) {
326+ CIPHERS_MAP .put ("CAST" , new String []{ "CAST" , "CBC" , null , "CAST5/CBC" } );
327+ CIPHERS_MAP .put ("CAST-CBC" , CIPHERS_MAP .get ("CAST" ));
328+ for (final String mode : modes ) {
329+ CIPHERS_MAP .put ("CAST5-" + mode , new String []{ "CAST" , mode , null , "CAST5/" + mode });
337330 }
338331 }
339332
340333 modes = cipherModes ("CAST6" );
341- if ( modes != null ) {
342- for ( final String mode : modes ) {
343- supportedCiphers .put ( "CAST6-" + mode , new String [] { "CAST6" , mode , null , "CAST6/" + mode });
334+ if (modes != null ) {
335+ for (final String mode : modes ) {
336+ CIPHERS_MAP .put ("CAST6-" + mode , new String []{ "CAST6" , mode , null , "CAST6/" + mode });
344337 }
345338 }
346339
347340 modes = cipherModes ("DES" );
348- if ( modes != null ) {
349- supportedCiphers .put ( "DES" , new String [] { "DES" , "CBC" , null , "DES/CBC" } );
350- for ( final String mode : modes ) {
351- supportedCiphers .put ( "DES-" + mode , new String [] { "DES" , mode , null , "DES/" + mode });
341+ if (modes != null ) {
342+ CIPHERS_MAP .put ("DES" , new String []{ "DES" , "CBC" , null , "DES/CBC" } );
343+ for (final String mode : modes ) {
344+ CIPHERS_MAP .put ("DES-" + mode , new String []{ "DES" , mode , null , "DES/" + mode });
352345 }
353346 }
354347
355348 modes = cipherModes ("DESede" );
356- if ( modes != null ) {
357- supportedCiphers .put ( "DES-EDE" , new String [] { "DES" , "ECB" , "EDE" , "DESede/ECB" } );
358- supportedCiphers .put ( "DES-EDE-CBC" , new String [] { "DES" , "CBC" , "EDE" , "DESede/CBC" } );
359- supportedCiphers .put ( "DES-EDE-CFB" , new String [] { "DES" , "CBC" , "EDE" , "DESede/CFB" } );
360- supportedCiphers .put ( "DES-EDE-OFB" , new String [] { "DES" , "CBC" , "EDE" , "DESede/OFB" } );
361- supportedCiphers .put ( "DES-EDE3" , new String [] { "DES" , "ECB" , "EDE3" , "DESede/ECB" });
362- for ( final String mode : modes ) {
363- supportedCiphers .put ( "DES-EDE3-" + mode , new String [] { "DES" , mode , "EDE3" , "DESede/" + mode });
349+ if (modes != null ) {
350+ CIPHERS_MAP .put ("DES-EDE" , new String []{ "DES" , "ECB" , "EDE" , "DESede/ECB" } );
351+ CIPHERS_MAP .put ("DES-EDE-CBC" , new String []{ "DES" , "CBC" , "EDE" , "DESede/CBC" } );
352+ CIPHERS_MAP .put ("DES-EDE-CFB" , new String []{ "DES" , "CBC" , "EDE" , "DESede/CFB" } );
353+ CIPHERS_MAP .put ("DES-EDE-OFB" , new String []{ "DES" , "CBC" , "EDE" , "DESede/OFB" } );
354+ CIPHERS_MAP .put ("DES-EDE3" , new String []{ "DES" , "ECB" , "EDE3" , "DESede/ECB" });
355+ for (final String mode : modes ) {
356+ CIPHERS_MAP .put ("DES-EDE3-" + mode , new String []{ "DES" , mode , "EDE3" , "DESede/" + mode });
364357 }
365- supportedCiphers .put ( "DES3" , new String [] { "DES" , "CBC" , "EDE3" , "DESede/CBC" } );
358+ CIPHERS_MAP .put ("DES3" , new String []{ "DES" , "CBC" , "EDE3" , "DESede/CBC" } );
366359 }
367360
368361 modes = cipherModes ("RC2" );
369- if ( modes != null ) {
370- supportedCiphers .put ( "RC2" , new String [] { "RC2" , "CBC" , null , "RC2/CBC" } );
371- for ( final String mode : modes ) {
372- supportedCiphers .put ( "RC2-" + mode , new String [] { "RC2" , mode , null , "RC2/" + mode } );
362+ if (modes != null ) {
363+ CIPHERS_MAP .put ("RC2" , new String []{ "RC2" , "CBC" , null , "RC2/CBC" } );
364+ for (final String mode : modes ) {
365+ CIPHERS_MAP .put ("RC2-" + mode , new String []{ "RC2" , mode , null , "RC2/" + mode } );
373366 }
374- supportedCiphers .put ( "RC2-40-CBC" , new String [] { "RC2" , "CBC" , "40" , "RC2/CBC" } );
375- supportedCiphers .put ( "RC2-64-CBC" , new String [] { "RC2" , "CBC" , "64" , "RC2/CBC" } );
367+ CIPHERS_MAP .put ("RC2-40-CBC" , new String []{ "RC2" , "CBC" , "40" , "RC2/CBC" } );
368+ CIPHERS_MAP .put ("RC2-64-CBC" , new String []{ "RC2" , "CBC" , "64" , "RC2/CBC" } );
376369 }
377370
378371 modes = cipherModes ("RC4" ); // NOTE: stream cipher (BC supported)
379- if ( modes != null ) {
380- supportedCiphers .put ( "RC4" , new String [] { "RC4" , null , null , "RC4" } );
381- supportedCiphers .put ( "RC4-40" , new String [] { "RC4" , null , "40" , "RC4" } );
372+ if (modes != null ) {
373+ CIPHERS_MAP .put ("RC4" , new String []{ "RC4" , null , null , "RC4" } );
374+ CIPHERS_MAP .put ("RC4-40" , new String []{ "RC4" , null , "40" , "RC4" } );
382375 //supportedCiphers.put( "RC2-HMAC-MD5", new String[] { "RC4", null, null, "RC4" });
383376 }
384377
385378 modes = cipherModes ("SEED" );
386- if ( modes != null ) {
387- supportedCiphers .put ( "SEED" , new String [] { "SEED" , "CBC" , null , "SEED/CBC" } );
388- for ( final String mode : modes ) {
389- supportedCiphers .put ( "SEED-" + mode , new String [] { "SEED" , mode , null , "SEED/" + mode });
379+ if (modes != null ) {
380+ CIPHERS_MAP .put ("SEED" , new String []{ "SEED" , "CBC" , null , "SEED/CBC" } );
381+ for (final String mode : modes ) {
382+ CIPHERS_MAP .put ("SEED-" + mode , new String []{ "SEED" , mode , null , "SEED/" + mode });
390383 }
391384 }
392-
393- supportedCiphersAll = true ;
394- return supportedCiphers ;
395385 }
396386 }
397387
@@ -436,7 +426,7 @@ static Algorithm osslToJava(final String osslName) {
436426
437427 private static Algorithm osslToJava (final String osslName , final String padding ) {
438428
439- final String [] algVals = supportedCiphers .get (osslName );
429+ final String [] algVals = AllSupportedCiphers . CIPHERS_MAP .get (osslName );
440430 if ( algVals != null ) {
441431 final String cryptoMode = algVals [1 ];
442432 Algorithm alg = new Algorithm (algVals [0 ], algVals [2 ], cryptoMode );
0 commit comments