630 firstSearch = false;
631 }
632
633 if ((newCandidates != null) && !newCandidates.isEmpty()) {
634 // For each provider in the candidates set, if it
635 // isn't in the newCandidate set, we should remove
636 // it from the candidate set.
637 for (Iterator<Provider> cansIte = candidates.iterator();
638 cansIte.hasNext(); ) {
639 Provider prov = cansIte.next();
640 if (!newCandidates.contains(prov)) {
641 cansIte.remove();
642 }
643 }
644 } else {
645 candidates = null;
646 break;
647 }
648 }
649
650 if ((candidates == null) || (candidates.isEmpty()))
651 return null;
652
653 Object[] candidatesArray = candidates.toArray();
654 Provider[] result = new Provider[candidatesArray.length];
655
656 for (int i = 0; i < result.length; i++) {
657 result[i] = (Provider)candidatesArray[i];
658 }
659
660 return result;
661 }
662
663 // Map containing cached Spi Class objects of the specified type
664 private static final Map<String, Class<?>> spiMap =
665 new ConcurrentHashMap<>();
666
667 /**
668 * Return the Class object for the given engine type
669 * (e.g. "MessageDigest"). Works for Spis in the java.security package
670 * only.
976 if (attribute.equalsIgnoreCase("ImplementedIn")) {
977 return value.equalsIgnoreCase(prop);
978 }
979
980 return false;
981 }
982
983 static String[] getFilterComponents(String filterKey, String filterValue) {
984 int algIndex = filterKey.indexOf('.');
985
986 if (algIndex < 0) {
987 // There must be a dot in the filter, and the dot
988 // shouldn't be at the beginning of this string.
989 throw new InvalidParameterException("Invalid filter");
990 }
991
992 String serviceName = filterKey.substring(0, algIndex);
993 String algName = null;
994 String attrName = null;
995
996 if (filterValue.length() == 0) {
997 // The filterValue is an empty string. So the filterKey
998 // should be in the format of <crypto_service>.<algorithm_or_type>.
999 algName = filterKey.substring(algIndex + 1).trim();
1000 if (algName.length() == 0) {
1001 // There must be a algorithm or type name.
1002 throw new InvalidParameterException("Invalid filter");
1003 }
1004 } else {
1005 // The filterValue is a non-empty string. So the filterKey must be
1006 // in the format of
1007 // <crypto_service>.<algorithm_or_type> <attribute_name>
1008 int attrIndex = filterKey.indexOf(' ');
1009
1010 if (attrIndex == -1) {
1011 // There is no attribute name in the filter.
1012 throw new InvalidParameterException("Invalid filter");
1013 } else {
1014 attrName = filterKey.substring(attrIndex + 1).trim();
1015 if (attrName.length() == 0) {
1016 // There is no attribute name in the filter.
1017 throw new InvalidParameterException("Invalid filter");
1018 }
1019 }
1020
1021 // There must be an algorithm name in the filter.
1022 if ((attrIndex < algIndex) ||
1023 (algIndex == attrIndex - 1)) {
1024 throw new InvalidParameterException("Invalid filter");
1025 } else {
1026 algName = filterKey.substring(algIndex + 1, attrIndex);
1027 }
1028 }
1029
1030 String[] result = new String[3];
1031 result[0] = serviceName;
1032 result[1] = algName;
1033 result[2] = attrName;
1034
1035 return result;
1041 * (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore). Returns
1042 * an empty Set if there is no provider that supports the
1043 * specified service or if serviceName is null. For a complete list
1044 * of Java cryptographic services, please see the
1045 * {@extLink security_guide_jca
1046 * Java Cryptography Architecture (JCA) Reference Guide}.
1047 * Note: the returned set is immutable.
1048 *
1049 * @param serviceName the name of the Java cryptographic
1050 * service (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore).
1051 * Note: this parameter is case-insensitive.
1052 *
1053 * @return a Set of Strings containing the names of all available
1054 * algorithms or types for the specified Java cryptographic service
1055 * or an empty set if no provider supports the specified service.
1056 *
1057 * @since 1.4
1058 **/
1059 public static Set<String> getAlgorithms(String serviceName) {
1060
1061 if ((serviceName == null) || (serviceName.length() == 0) ||
1062 (serviceName.endsWith("."))) {
1063 return Collections.emptySet();
1064 }
1065
1066 HashSet<String> result = new HashSet<>();
1067 Provider[] providers = Security.getProviders();
1068
1069 for (int i = 0; i < providers.length; i++) {
1070 // Check the keys for each provider.
1071 for (Enumeration<Object> e = providers[i].keys();
1072 e.hasMoreElements(); ) {
1073 String currentKey =
1074 ((String)e.nextElement()).toUpperCase(Locale.ENGLISH);
1075 if (currentKey.startsWith(
1076 serviceName.toUpperCase(Locale.ENGLISH))) {
1077 // We should skip the currentKey if it contains a
1078 // whitespace. The reason is: such an entry in the
1079 // provider property contains attributes for the
1080 // implementation of an algorithm. We are only interested
1081 // in entries which lead to the implementation
|
630 firstSearch = false;
631 }
632
633 if ((newCandidates != null) && !newCandidates.isEmpty()) {
634 // For each provider in the candidates set, if it
635 // isn't in the newCandidate set, we should remove
636 // it from the candidate set.
637 for (Iterator<Provider> cansIte = candidates.iterator();
638 cansIte.hasNext(); ) {
639 Provider prov = cansIte.next();
640 if (!newCandidates.contains(prov)) {
641 cansIte.remove();
642 }
643 }
644 } else {
645 candidates = null;
646 break;
647 }
648 }
649
650 if (candidates == null || candidates.isEmpty())
651 return null;
652
653 Object[] candidatesArray = candidates.toArray();
654 Provider[] result = new Provider[candidatesArray.length];
655
656 for (int i = 0; i < result.length; i++) {
657 result[i] = (Provider)candidatesArray[i];
658 }
659
660 return result;
661 }
662
663 // Map containing cached Spi Class objects of the specified type
664 private static final Map<String, Class<?>> spiMap =
665 new ConcurrentHashMap<>();
666
667 /**
668 * Return the Class object for the given engine type
669 * (e.g. "MessageDigest"). Works for Spis in the java.security package
670 * only.
976 if (attribute.equalsIgnoreCase("ImplementedIn")) {
977 return value.equalsIgnoreCase(prop);
978 }
979
980 return false;
981 }
982
983 static String[] getFilterComponents(String filterKey, String filterValue) {
984 int algIndex = filterKey.indexOf('.');
985
986 if (algIndex < 0) {
987 // There must be a dot in the filter, and the dot
988 // shouldn't be at the beginning of this string.
989 throw new InvalidParameterException("Invalid filter");
990 }
991
992 String serviceName = filterKey.substring(0, algIndex);
993 String algName = null;
994 String attrName = null;
995
996 if (filterValue.isEmpty()) {
997 // The filterValue is an empty string. So the filterKey
998 // should be in the format of <crypto_service>.<algorithm_or_type>.
999 algName = filterKey.substring(algIndex + 1).trim();
1000 if (algName.isEmpty()) {
1001 // There must be a algorithm or type name.
1002 throw new InvalidParameterException("Invalid filter");
1003 }
1004 } else {
1005 // The filterValue is a non-empty string. So the filterKey must be
1006 // in the format of
1007 // <crypto_service>.<algorithm_or_type> <attribute_name>
1008 int attrIndex = filterKey.indexOf(' ');
1009
1010 if (attrIndex == -1) {
1011 // There is no attribute name in the filter.
1012 throw new InvalidParameterException("Invalid filter");
1013 } else {
1014 attrName = filterKey.substring(attrIndex + 1).trim();
1015 if (attrName.isEmpty()) {
1016 // There is no attribute name in the filter.
1017 throw new InvalidParameterException("Invalid filter");
1018 }
1019 }
1020
1021 // There must be an algorithm name in the filter.
1022 if ((attrIndex < algIndex) ||
1023 (algIndex == attrIndex - 1)) {
1024 throw new InvalidParameterException("Invalid filter");
1025 } else {
1026 algName = filterKey.substring(algIndex + 1, attrIndex);
1027 }
1028 }
1029
1030 String[] result = new String[3];
1031 result[0] = serviceName;
1032 result[1] = algName;
1033 result[2] = attrName;
1034
1035 return result;
1041 * (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore). Returns
1042 * an empty Set if there is no provider that supports the
1043 * specified service or if serviceName is null. For a complete list
1044 * of Java cryptographic services, please see the
1045 * {@extLink security_guide_jca
1046 * Java Cryptography Architecture (JCA) Reference Guide}.
1047 * Note: the returned set is immutable.
1048 *
1049 * @param serviceName the name of the Java cryptographic
1050 * service (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore).
1051 * Note: this parameter is case-insensitive.
1052 *
1053 * @return a Set of Strings containing the names of all available
1054 * algorithms or types for the specified Java cryptographic service
1055 * or an empty set if no provider supports the specified service.
1056 *
1057 * @since 1.4
1058 **/
1059 public static Set<String> getAlgorithms(String serviceName) {
1060
1061 if ((serviceName == null) || (serviceName.isEmpty()) ||
1062 (serviceName.endsWith("."))) {
1063 return Collections.emptySet();
1064 }
1065
1066 HashSet<String> result = new HashSet<>();
1067 Provider[] providers = Security.getProviders();
1068
1069 for (int i = 0; i < providers.length; i++) {
1070 // Check the keys for each provider.
1071 for (Enumeration<Object> e = providers[i].keys();
1072 e.hasMoreElements(); ) {
1073 String currentKey =
1074 ((String)e.nextElement()).toUpperCase(Locale.ENGLISH);
1075 if (currentKey.startsWith(
1076 serviceName.toUpperCase(Locale.ENGLISH))) {
1077 // We should skip the currentKey if it contains a
1078 // whitespace. The reason is: such an entry in the
1079 // provider property contains attributes for the
1080 // implementation of an algorithm. We are only interested
1081 // in entries which lead to the implementation
|