@@ -310,19 +310,22 @@ 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 /*
319- * array containing the components of a cipher transformation:
323+ * Components of a cipher transformation:
320324 *
321- * index 0: algorithm component (e.g., AES)
322- * index 1: feedback component (e.g., CFB)
323- * index 2: padding component (e.g., PKCS5Padding)
325+ * 1) algorithm component (e.g., AES)
326+ * 2) feedback component (e.g., CFB) - optional
327+ * 3) padding component (e.g., PKCS5Padding) - optional
324328 */
325- String [] parts = { "" , "" , "" };
326329
327330 // check if the transformation contains algorithms with "/" in their
328331 // name which can cause the parsing logic to go wrong
@@ -331,27 +334,35 @@ private static String[] tokenizeTransformation(String transformation)
331334 int startIdx = (sha512Idx == -1 ? 0 :
332335 sha512Idx + SHA512TRUNCATED .length ());
333336 int endIdx = transformation .indexOf ('/' , startIdx );
334- if (endIdx == -1 ) {
335- // algorithm
336- parts [0 ] = transformation .trim ();
337+
338+ boolean algorithmOnly = (endIdx == -1 );
339+ String algo = (algorithmOnly ? transformation .trim () :
340+ transformation .substring (0 , endIdx ).trim ());
341+ if (algo .isEmpty ()) {
342+ throw new NoSuchAlgorithmException ("Invalid transformation: " +
343+ "algorithm not specified-"
344+ + transformation );
345+ }
346+ if (algorithmOnly ) { // done
347+ return new String [] { algo };
337348 } else {
338- // algorithm/mode/padding
339- parts [0 ] = transformation .substring (0 , endIdx ).trim ();
349+ // continue parsing mode and padding
340350 startIdx = endIdx +1 ;
341351 endIdx = transformation .indexOf ('/' , startIdx );
342352 if (endIdx == -1 ) {
343353 throw new NoSuchAlgorithmException ("Invalid transformation"
344354 + " format:" + transformation );
345355 }
346- parts [ 1 ] = transformation .substring (startIdx , endIdx ).trim ();
347- parts [ 2 ] = transformation .substring (endIdx +1 ).trim ();
348- }
349- if (parts [ 0 ] .isEmpty ()) {
350- throw new NoSuchAlgorithmException ("Invalid transformation: " +
351- "algorithm not specified -"
356+ String mode = transformation .substring (startIdx , endIdx ).trim ();
357+ String padding = transformation .substring (endIdx +1 ).trim ();
358+ // ensure mode and padding are specified
359+ if (mode . isEmpty () || padding .isEmpty ()) {
360+ throw new NoSuchAlgorithmException ("Invalid transformation: " +
361+ "missing mode and/or padding -"
352362 + transformation );
363+ }
364+ return new String [] { algo , mode , padding };
353365 }
354- return parts ;
355366 }
356367
357368 // Provider attribute name for supported chaining mode
@@ -447,28 +458,17 @@ private static List<Transform> getTransforms(String transformation)
447458 throws NoSuchAlgorithmException {
448459 String [] parts = tokenizeTransformation (transformation );
449460
450- String alg = parts [0 ];
451- String mode = (parts [1 ].length () == 0 ? null : parts [1 ]);
452- String pad = (parts [2 ].length () == 0 ? null : parts [2 ]);
453-
454- if ((mode == null ) && (pad == null )) {
461+ if (parts .length == 1 ) {
455462 // Algorithm only
456- Transform tr = new Transform (alg , "" , null , null );
457- return Collections .singletonList (tr );
463+ return List .of (new Transform (parts [0 ], "" , null , null ));
458464 } else {
459- // Algorithm w/ at least mode or padding or both
460- List <Transform > list = new ArrayList <>(4 );
461- if ((mode != null ) && (pad != null )) {
462- list .add (new Transform (alg , "/" + mode + "/" + pad , null , null ));
463- }
464- if (mode != null ) {
465- list .add (new Transform (alg , "/" + mode , null , pad ));
466- }
467- if (pad != null ) {
468- list .add (new Transform (alg , "//" + pad , mode , null ));
469- }
470- list .add (new Transform (alg , "" , mode , pad ));
471- return list ;
465+ // Algorithm w/ both mode and padding
466+ return List .of (
467+ new Transform (parts [0 ], "/" + parts [1 ] + "/" + parts [2 ],
468+ null , null ),
469+ new Transform (parts [0 ], "/" + parts [1 ], null , parts [2 ]),
470+ new Transform (parts [0 ], "//" + parts [2 ], parts [1 ], null ),
471+ new Transform (parts [0 ], "" , parts [1 ], parts [2 ]));
472472 }
473473 }
474474
0 commit comments