324 String[] parts = new String[3];
325 int count = 0;
326 StringTokenizer parser = new StringTokenizer(transformation, "/");
327 try {
328 while (parser.hasMoreTokens() && count < 3) {
329 parts[count++] = parser.nextToken().trim();
330 }
331 if (count == 0 || count == 2) {
332 throw new NoSuchAlgorithmException("Invalid transformation"
333 + " format:" +
334 transformation);
335 }
336 // treats all subsequent tokens as part of padding
337 if (count == 3 && parser.hasMoreTokens()) {
338 parts[2] = parts[2] + parser.nextToken("\r\n");
339 }
340 } catch (NoSuchElementException e) {
341 throw new NoSuchAlgorithmException("Invalid transformation " +
342 "format:" + transformation);
343 }
344 if ((parts[0] == null) || (parts[0].length() == 0)) {
345 throw new NoSuchAlgorithmException("Invalid transformation:" +
346 "algorithm not specified-"
347 + transformation);
348 }
349 return parts;
350 }
351
352 // Provider attribute name for supported chaining mode
353 private static final String ATTR_MODE = "SupportedModes";
354 // Provider attribute name for supported padding names
355 private static final String ATTR_PAD = "SupportedPaddings";
356
357 // constants indicating whether the provider supports
358 // a given mode or padding
359 private static final int S_NO = 0; // does not support
360 private static final int S_MAYBE = 1; // unable to determine
361 private static final int S_YES = 2; // does support
362
363 /**
364 * Nested class to deal with modes and paddings.
428 new ConcurrentHashMap<String, Pattern>();
429
430 private static boolean matches(String regexp, String str) {
431 Pattern pattern = patternCache.get(regexp);
432 if (pattern == null) {
433 pattern = Pattern.compile(regexp);
434 patternCache.putIfAbsent(regexp, pattern);
435 }
436 return pattern.matcher(str.toUpperCase(Locale.ENGLISH)).matches();
437 }
438
439 }
440
441 private static List<Transform> getTransforms(String transformation)
442 throws NoSuchAlgorithmException {
443 String[] parts = tokenizeTransformation(transformation);
444
445 String alg = parts[0];
446 String mode = parts[1];
447 String pad = parts[2];
448 if ((mode != null) && (mode.length() == 0)) {
449 mode = null;
450 }
451 if ((pad != null) && (pad.length() == 0)) {
452 pad = null;
453 }
454
455 if ((mode == null) && (pad == null)) {
456 // AES
457 Transform tr = new Transform(alg, "", null, null);
458 return Collections.singletonList(tr);
459 } else { // if ((mode != null) && (pad != null)) {
460 // AES/CBC/PKCS5Padding
461 List<Transform> list = new ArrayList<>(4);
462 list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));
463 list.add(new Transform(alg, "/" + mode, null, pad));
464 list.add(new Transform(alg, "//" + pad, mode, null));
465 list.add(new Transform(alg, "", mode, pad));
466 return list;
467 }
468 }
469
470 // get the transform matching the specified service
471 private static Transform getTransform(Service s,
617 * or if a {@code CipherSpi} implementation for the
618 * specified algorithm is not available from the specified
619 * provider
620 *
621 * @throws NoSuchPaddingException if {@code transformation}
622 * contains a padding scheme that is not available
623 *
624 * @throws NoSuchProviderException if the specified provider is not
625 * registered in the security provider list
626 *
627 * @see java.security.Provider
628 */
629 public static final Cipher getInstance(String transformation,
630 String provider)
631 throws NoSuchAlgorithmException, NoSuchProviderException,
632 NoSuchPaddingException
633 {
634 if ((transformation == null) || transformation.isEmpty()) {
635 throw new NoSuchAlgorithmException("Null or empty transformation");
636 }
637 if ((provider == null) || (provider.length() == 0)) {
638 throw new IllegalArgumentException("Missing provider");
639 }
640 Provider p = Security.getProvider(provider);
641 if (p == null) {
642 throw new NoSuchProviderException("No such provider: " +
643 provider);
644 }
645 return getInstance(transformation, p);
646 }
647
648 private String getProviderName() {
649 return (provider == null) ? "(no provider)" : provider.getName();
650 }
651
652 /**
653 * Returns a {@code Cipher} object that implements the specified
654 * transformation.
655 *
656 * <p> A new Cipher object encapsulating the
657 * CipherSpi implementation from the specified Provider
|
324 String[] parts = new String[3];
325 int count = 0;
326 StringTokenizer parser = new StringTokenizer(transformation, "/");
327 try {
328 while (parser.hasMoreTokens() && count < 3) {
329 parts[count++] = parser.nextToken().trim();
330 }
331 if (count == 0 || count == 2) {
332 throw new NoSuchAlgorithmException("Invalid transformation"
333 + " format:" +
334 transformation);
335 }
336 // treats all subsequent tokens as part of padding
337 if (count == 3 && parser.hasMoreTokens()) {
338 parts[2] = parts[2] + parser.nextToken("\r\n");
339 }
340 } catch (NoSuchElementException e) {
341 throw new NoSuchAlgorithmException("Invalid transformation " +
342 "format:" + transformation);
343 }
344 if ((parts[0] == null) || (parts[0].isEmpty())) {
345 throw new NoSuchAlgorithmException("Invalid transformation:" +
346 "algorithm not specified-"
347 + transformation);
348 }
349 return parts;
350 }
351
352 // Provider attribute name for supported chaining mode
353 private static final String ATTR_MODE = "SupportedModes";
354 // Provider attribute name for supported padding names
355 private static final String ATTR_PAD = "SupportedPaddings";
356
357 // constants indicating whether the provider supports
358 // a given mode or padding
359 private static final int S_NO = 0; // does not support
360 private static final int S_MAYBE = 1; // unable to determine
361 private static final int S_YES = 2; // does support
362
363 /**
364 * Nested class to deal with modes and paddings.
428 new ConcurrentHashMap<String, Pattern>();
429
430 private static boolean matches(String regexp, String str) {
431 Pattern pattern = patternCache.get(regexp);
432 if (pattern == null) {
433 pattern = Pattern.compile(regexp);
434 patternCache.putIfAbsent(regexp, pattern);
435 }
436 return pattern.matcher(str.toUpperCase(Locale.ENGLISH)).matches();
437 }
438
439 }
440
441 private static List<Transform> getTransforms(String transformation)
442 throws NoSuchAlgorithmException {
443 String[] parts = tokenizeTransformation(transformation);
444
445 String alg = parts[0];
446 String mode = parts[1];
447 String pad = parts[2];
448 if ((mode != null) && (mode.isEmpty())) {
449 mode = null;
450 }
451 if ((pad != null) && (pad.isEmpty())) {
452 pad = null;
453 }
454
455 if ((mode == null) && (pad == null)) {
456 // AES
457 Transform tr = new Transform(alg, "", null, null);
458 return Collections.singletonList(tr);
459 } else { // if ((mode != null) && (pad != null)) {
460 // AES/CBC/PKCS5Padding
461 List<Transform> list = new ArrayList<>(4);
462 list.add(new Transform(alg, "/" + mode + "/" + pad, null, null));
463 list.add(new Transform(alg, "/" + mode, null, pad));
464 list.add(new Transform(alg, "//" + pad, mode, null));
465 list.add(new Transform(alg, "", mode, pad));
466 return list;
467 }
468 }
469
470 // get the transform matching the specified service
471 private static Transform getTransform(Service s,
617 * or if a {@code CipherSpi} implementation for the
618 * specified algorithm is not available from the specified
619 * provider
620 *
621 * @throws NoSuchPaddingException if {@code transformation}
622 * contains a padding scheme that is not available
623 *
624 * @throws NoSuchProviderException if the specified provider is not
625 * registered in the security provider list
626 *
627 * @see java.security.Provider
628 */
629 public static final Cipher getInstance(String transformation,
630 String provider)
631 throws NoSuchAlgorithmException, NoSuchProviderException,
632 NoSuchPaddingException
633 {
634 if ((transformation == null) || transformation.isEmpty()) {
635 throw new NoSuchAlgorithmException("Null or empty transformation");
636 }
637 if ((provider == null) || (provider.isEmpty())) {
638 throw new IllegalArgumentException("Missing provider");
639 }
640 Provider p = Security.getProvider(provider);
641 if (p == null) {
642 throw new NoSuchProviderException("No such provider: " +
643 provider);
644 }
645 return getInstance(transformation, p);
646 }
647
648 private String getProviderName() {
649 return (provider == null) ? "(no provider)" : provider.getName();
650 }
651
652 /**
653 * Returns a {@code Cipher} object that implements the specified
654 * transformation.
655 *
656 * <p> A new Cipher object encapsulating the
657 * CipherSpi implementation from the specified Provider
|