@@ -310,20 +310,23 @@ private Cipher(CipherSpi firstSpi, Service firstService,
310310
311311 private static final String SHA512TRUNCATED = "SHA512/2" ;
312312
313+ + // Parse the specified cipher transformation for algorithm and the
314+ + // optional mode and padding. If the transformation contains only
315+ + // algorithm, then only algorithm is returned. Otherwise, the
316+ + // transformation must contain all 3 and they must be non-empty.
313317 private static String [] tokenizeTransformation (String transformation )
314318 throws NoSuchAlgorithmException {
315319 if (transformation == null ) {
316320 throw new NoSuchAlgorithmException ("No transformation given" );
317321 }
318322
319323 /*
320- * array containing the components of a cipher transformation:
324+ * Components of a cipher transformation:
321325 *
322- * index 0: algorithm component (e.g., AES)
323- * index 1: feedback component (e.g., CFB)
324- * index 2: padding component (e.g., PKCS5Padding)
326+ * 1) algorithm component (e.g., AES)
327+ * 2) feedback component (e.g., CFB) - optional
328+ * 3) padding component (e.g., PKCS5Padding) - optional
325329 */
326- String [] parts = { "" , "" , "" };
327330
328331 // check if the transformation contains algorithms with "/" in their
329332 // name which can cause the parsing logic to go wrong
@@ -332,27 +335,35 @@ private static String[] tokenizeTransformation(String transformation)
332335 int startIdx = (sha512Idx == -1 ? 0 :
333336 sha512Idx + SHA512TRUNCATED .length ());
334337 int endIdx = transformation .indexOf ('/' , startIdx );
335- if (endIdx == -1 ) {
336- // algorithm
337- parts [0 ] = transformation .trim ();
338+
339+ boolean algorithmOnly = (endIdx == -1 );
340+ String algo = (algorithmOnly ? transformation .trim () :
341+ transformation .substring (0 , endIdx ).trim ());
342+ if (algo .isEmpty ()) {
343+ throw new NoSuchAlgorithmException ("Invalid transformation: " +
344+ "algorithm not specified-"
345+ + transformation );
346+ }
347+ if (algorithmOnly ) { // done
348+ return new String [] { algo };
338349 } else {
339- // algorithm/mode/padding
340- parts [0 ] = transformation .substring (0 , endIdx ).trim ();
350+ // continue parsing mode and padding
341351 startIdx = endIdx +1 ;
342352 endIdx = transformation .indexOf ('/' , startIdx );
343353 if (endIdx == -1 ) {
344354 throw new NoSuchAlgorithmException ("Invalid transformation"
345355 + " format:" + transformation );
346356 }
347- parts [ 1 ] = transformation .substring (startIdx , endIdx ).trim ();
348- parts [ 2 ] = transformation .substring (endIdx +1 ).trim ();
349- }
350- if (parts [ 0 ] .isEmpty ()) {
351- throw new NoSuchAlgorithmException ("Invalid transformation: " +
352- "algorithm not specified -"
357+ String mode = transformation .substring (startIdx , endIdx ).trim ();
358+ String padding = transformation .substring (endIdx +1 ).trim ();
359+ // ensure mode and padding are specified
360+ if (mode . isEmpty () || padding .isEmpty ()) {
361+ throw new NoSuchAlgorithmException ("Invalid transformation: " +
362+ "missing mode and/or padding -"
353363 + transformation );
364+ }
365+ return new String [] { algo , mode , padding };
354366 }
355- return parts ;
356367 }
357368
358369 // Provider attribute name for supported chaining mode
@@ -448,28 +459,17 @@ private static List<Transform> getTransforms(String transformation)
448459 throws NoSuchAlgorithmException {
449460 String [] parts = tokenizeTransformation (transformation );
450461
451- String alg = parts [0 ];
452- String mode = (parts [1 ].length () == 0 ? null : parts [1 ]);
453- String pad = (parts [2 ].length () == 0 ? null : parts [2 ]);
454-
455- if ((mode == null ) && (pad == null )) {
462+ if (parts .length == 1 ) {
456463 // Algorithm only
457- Transform tr = new Transform (alg , "" , null , null );
458- return Collections .singletonList (tr );
464+ return List .of (new Transform (parts [0 ], "" , null , null ));
459465 } else {
460- // Algorithm w/ at least mode or padding or both
461- List <Transform > list = new ArrayList <>(4 );
462- if ((mode != null ) && (pad != null )) {
463- list .add (new Transform (alg , "/" + mode + "/" + pad , null , null ));
464- }
465- if (mode != null ) {
466- list .add (new Transform (alg , "/" + mode , null , pad ));
467- }
468- if (pad != null ) {
469- list .add (new Transform (alg , "//" + pad , mode , null ));
470- }
471- list .add (new Transform (alg , "" , mode , pad ));
472- return list ;
466+ // Algorithm w/ both mode and padding
467+ return List .of (
468+ new Transform (parts [0 ], "/" + parts [1 ] + "/" + parts [2 ],
469+ null , null ),
470+ new Transform (parts [0 ], "/" + parts [1 ], null , parts [2 ]),
471+ new Transform (parts [0 ], "//" + parts [2 ], parts [1 ], null ),
472+ new Transform (parts [0 ], "" , parts [1 ], parts [2 ]));
473473 }
474474 }
475475
0 commit comments