1 /* 2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 25 // common infrastructure for SunPKCS11 tests 26 27 import java.io.BufferedReader; 28 import java.io.ByteArrayOutputStream; 29 import java.io.File; 30 import java.io.FileInputStream; 31 import java.io.IOException; 32 import java.io.InputStreamReader; 33 import java.io.StringReader; 34 import java.security.AlgorithmParameters; 35 import java.security.InvalidAlgorithmParameterException; 36 import java.security.KeyPairGenerator; 37 import java.security.NoSuchProviderException; 38 import java.security.Provider; 39 import java.security.ProviderException; 40 import java.security.Security; 41 import java.security.spec.ECGenParameterSpec; 42 import java.security.spec.ECParameterSpec; 43 import java.util.ArrayList; 44 import java.util.Arrays; 45 import java.util.HashMap; 46 import java.util.Iterator; 47 import java.util.List; 48 import java.util.Map; 49 import java.util.Properties; 50 import java.util.ServiceConfigurationError; 51 import java.util.ServiceLoader; 52 import java.util.Set; 53 54 public abstract class PKCS11Test { 55 56 private boolean enableSM = false; 57 58 static final Properties props = System.getProperties(); 59 60 static final String PKCS11 = "PKCS11"; 61 62 // directory of the test source 63 static final String BASE = System.getProperty("test.src", "."); 64 65 static final char SEP = File.separatorChar; 66 67 private static final String DEFAULT_POLICY = 68 BASE + SEP + ".." + SEP + "policy"; 69 70 // directory corresponding to BASE in the /closed hierarchy 71 static final String CLOSED_BASE; 72 73 static { 74 // hack 75 String absBase = new File(BASE).getAbsolutePath(); 76 int k = absBase.indexOf(SEP + "test" + SEP + "sun" + SEP); 77 if (k < 0) k = 0; 78 String p1 = absBase.substring(0, k + 6); 79 String p2 = absBase.substring(k + 5); 80 CLOSED_BASE = p1 + "closed" + p2; 81 82 // set it as a system property to make it available in policy file 83 System.setProperty("closed.base", CLOSED_BASE); 84 } 85 86 // NSS version info 87 public static enum ECCState { None, Basic, Extended }; 88 static double nss_version = -1; 89 static ECCState nss_ecc_status = ECCState.Extended; 90 91 // The NSS library we need to search for in getNSSLibDir() 92 // Default is "libsoftokn3.so", listed as "softokn3" 93 // The other is "libnss3.so", listed as "nss3". 94 static String nss_library = "softokn3"; 95 96 // NSS versions of each library. It is simplier to keep nss_version 97 // for quick checking for generic testing than many if-else statements. 98 static double softoken3_version = -1; 99 static double nss3_version = -1; 100 static Provider pkcs11; 101 102 // Goes through ServiceLoader instead of Provider.getInstance() since it 103 // works on all platforms 104 static { 105 ServiceLoader sl = ServiceLoader.load(java.security.Provider.class); 106 Iterator<Provider> iter = sl.iterator(); 107 Provider p = null; 108 boolean found = false; 109 while (iter.hasNext()) { 110 try { 111 p = iter.next(); 112 if (p.getName().equals("SunPKCS11")) { 113 found = true; 114 break; 115 } 116 } catch (Exception | ServiceConfigurationError e) { 117 // ignore and move on to the next one 118 } 119 } 120 // Nothing found through ServiceLoader; fall back to reflection 121 if (!found) { 122 try { 123 Class clazz = Class.forName("sun.security.pkcs11.SunPKCS11"); 124 p = (Provider) clazz.newInstance(); 125 } catch (Exception ex) { 126 ex.printStackTrace(); 127 } 128 } 129 pkcs11 = p; 130 } 131 132 /* 133 * Use Solaris SPARC 11.2 or later to avoid an intermittent failure 134 * when running SunPKCS11-Solaris (8044554) 135 */ 136 static boolean isBadSolarisSparc(Provider p) { 137 if ("SunPKCS11-Solaris".equals(p.getName()) && badSolarisSparc) { 138 System.out.println("SunPKCS11-Solaris provider requires " + 139 "Solaris SPARC 11.2 or later, skipping"); 140 return true; 141 } 142 return false; 143 } 144 145 // Return a SunPKCS11 provider configured with the specified config file 146 static Provider getSunPKCS11(String config) throws Exception { 147 if (pkcs11 == null) { 148 throw new NoSuchProviderException("No PKCS11 provider available"); 149 } 150 return pkcs11.configure(config); 151 } 152 153 public abstract void main(Provider p) throws Exception; 154 155 private void premain(Provider p) throws Exception { 156 // set a security manager and policy before a test case runs, 157 // and disable them after the test case finished 158 try { 159 if (enableSM) { 160 System.setSecurityManager(new SecurityManager()); 161 } 162 long start = System.currentTimeMillis(); 163 System.out.printf( 164 "Running test with provider %s (security manager %s) ...%n", 165 p.getName(), enableSM ? "enabled" : "disabled"); 166 main(p); 167 long stop = System.currentTimeMillis(); 168 System.out.println("Completed test with provider " + p.getName() + 169 " (" + (stop - start) + " ms)."); 170 } finally { 171 if (enableSM) { 172 System.setSecurityManager(null); 173 } 174 } 175 } 176 177 public static void main(PKCS11Test test) throws Exception { 178 main(test, null); 179 } 180 181 public static void main(PKCS11Test test, String[] args) throws Exception { 182 if (args != null) { 183 if (args.length > 0) { 184 if ("sm".equals(args[0])) { 185 test.enableSM = true; 186 } else { 187 throw new RuntimeException("Unknown Command, use 'sm' as " 188 + "first arguemtn to enable security manager"); 189 } 190 } 191 if (test.enableSM) { 192 System.setProperty("java.security.policy", 193 (args.length > 1) ? BASE + SEP + args[1] 194 : DEFAULT_POLICY); 195 } 196 } 197 198 Provider[] oldProviders = Security.getProviders(); 199 try { 200 System.out.println("Beginning test run " + test.getClass().getName() + "..."); 201 testDefault(test); 202 testNSS(test); 203 testDeimos(test); 204 } finally { 205 // NOTE: Do not place a 'return' in any finally block 206 // as it will suppress exceptions and hide test failures. 207 Provider[] newProviders = Security.getProviders(); 208 boolean found = true; 209 // Do not restore providers if nothing changed. This is especailly 210 // useful for ./Provider/Login.sh, where a SecurityManager exists. 211 if (oldProviders.length == newProviders.length) { 212 found = false; 213 for (int i = 0; i<oldProviders.length; i++) { 214 if (oldProviders[i] != newProviders[i]) { 215 found = true; 216 break; 217 } 218 } 219 } 220 if (found) { 221 for (Provider p: newProviders) { 222 Security.removeProvider(p.getName()); 223 } 224 for (Provider p: oldProviders) { 225 Security.addProvider(p); 226 } 227 } 228 } 229 } 230 231 public static void testDeimos(PKCS11Test test) throws Exception { 232 if (new File("/opt/SUNWconn/lib/libpkcs11.so").isFile() == false || 233 "true".equals(System.getProperty("NO_DEIMOS"))) { 234 return; 235 } 236 String base = getBase(); 237 String p11config = base + SEP + "nss" + SEP + "p11-deimos.txt"; 238 Provider p = getSunPKCS11(p11config); 239 test.premain(p); 240 } 241 242 public static void testDefault(PKCS11Test test) throws Exception { 243 // run test for default configured PKCS11 providers (if any) 244 245 if ("true".equals(System.getProperty("NO_DEFAULT"))) { 246 return; 247 } 248 249 Provider[] providers = Security.getProviders(); 250 for (int i = 0; i < providers.length; i++) { 251 Provider p = providers[i]; 252 if (p.getName().startsWith("SunPKCS11-")) { 253 test.premain(p); 254 } 255 } 256 } 257 258 private static String PKCS11_BASE; 259 static { 260 try { 261 PKCS11_BASE = getBase(); 262 } catch (Exception e) { 263 // ignore 264 } 265 } 266 267 private final static String PKCS11_REL_PATH = "sun/security/pkcs11"; 268 269 public static String getBase() throws Exception { 270 if (PKCS11_BASE != null) { 271 return PKCS11_BASE; 272 } 273 File cwd = new File(System.getProperty("test.src", ".")).getCanonicalFile(); 274 while (true) { 275 File file = new File(cwd, "TEST.ROOT"); 276 if (file.isFile()) { 277 break; 278 } 279 cwd = cwd.getParentFile(); 280 if (cwd == null) { 281 throw new Exception("Test root directory not found"); 282 } 283 } 284 PKCS11_BASE = new File(cwd, PKCS11_REL_PATH.replace('/', SEP)).getAbsolutePath(); 285 return PKCS11_BASE; 286 } 287 288 public static String getNSSLibDir() throws Exception { 289 return getNSSLibDir(nss_library); 290 } 291 292 static String getNSSLibDir(String library) throws Exception { 293 String osName = props.getProperty("os.name"); 294 if (osName.startsWith("Win")) { 295 osName = "Windows"; 296 } else if (osName.equals("Mac OS X")) { 297 osName = "MacOSX"; 298 } 299 String osid = osName + "-" 300 + props.getProperty("os.arch") + "-" + props.getProperty("sun.arch.data.model"); 301 String[] nssLibDirs = osMap.get(osid); 302 if (nssLibDirs == null) { 303 System.out.println("Warning: unsupported OS: " + osid 304 + ", please initialize NSS librarys location firstly, skipping test"); 305 return null; 306 } 307 if (nssLibDirs.length == 0) { 308 System.out.println("Warning: NSS not supported on this platform, skipping test"); 309 return null; 310 } 311 String nssLibDir = null; 312 for (String dir : nssLibDirs) { 313 if (new File(dir).exists() && 314 new File(dir + System.mapLibraryName(library)).exists()) { 315 nssLibDir = dir; 316 System.setProperty("pkcs11test.nss.libdir", nssLibDir); 317 break; 318 } 319 } 320 if (nssLibDir == null) { 321 System.out.println("Warning: can't find NSS librarys on this machine, skipping test"); 322 return null; 323 } 324 return nssLibDir; 325 } 326 327 static boolean isBadNSSVersion(Provider p) { 328 if (isNSS(p) && badNSSVersion) { 329 System.out.println("NSS 3.11 has a DER issue that recent " + 330 "version do not."); 331 return true; 332 } 333 return false; 334 } 335 336 protected static void safeReload(String lib) throws Exception { 337 try { 338 System.load(lib); 339 } catch (UnsatisfiedLinkError e) { 340 if (e.getMessage().contains("already loaded")) { 341 return; 342 } 343 } 344 } 345 346 static boolean loadNSPR(String libdir) throws Exception { 347 // load NSS softoken dependencies in advance to avoid resolver issues 348 safeReload(libdir + System.mapLibraryName("nspr4")); 349 safeReload(libdir + System.mapLibraryName("plc4")); 350 safeReload(libdir + System.mapLibraryName("plds4")); 351 safeReload(libdir + System.mapLibraryName("sqlite3")); 352 safeReload(libdir + System.mapLibraryName("nssutil3")); 353 return true; 354 } 355 356 // Check the provider being used is NSS 357 public static boolean isNSS(Provider p) { 358 return p.getName().toUpperCase().equals("SUNPKCS11-NSS"); 359 } 360 361 static double getNSSVersion() { 362 if (nss_version == -1) 363 getNSSInfo(); 364 return nss_version; 365 } 366 367 static ECCState getNSSECC() { 368 if (nss_version == -1) 369 getNSSInfo(); 370 return nss_ecc_status; 371 } 372 373 public static double getLibsoftokn3Version() { 374 if (softoken3_version == -1) 375 return getNSSInfo("softokn3"); 376 return softoken3_version; 377 } 378 379 public static double getLibnss3Version() { 380 if (nss3_version == -1) 381 return getNSSInfo("nss3"); 382 return nss3_version; 383 } 384 385 /* Read the library to find out the verison */ 386 static void getNSSInfo() { 387 getNSSInfo(nss_library); 388 } 389 390 static double getNSSInfo(String library) { 391 // look for two types of headers in NSS libraries 392 String nssHeader1 = "$Header: NSS"; 393 String nssHeader2 = "Version: NSS"; 394 boolean found = false; 395 String s = null; 396 int i = 0; 397 String libfile = ""; 398 399 if (library.compareTo("softokn3") == 0 && softoken3_version > -1) 400 return softoken3_version; 401 if (library.compareTo("nss3") == 0 && nss3_version > -1) 402 return nss3_version; 403 404 try { 405 libfile = getNSSLibDir() + System.mapLibraryName(library); 406 try (FileInputStream is = new FileInputStream(libfile)) { 407 byte[] data = new byte[1000]; 408 int read = 0; 409 410 while (is.available() > 0) { 411 if (read == 0) { 412 read = is.read(data, 0, 1000); 413 } else { 414 // Prepend last 100 bytes in case the header was split 415 // between the reads. 416 System.arraycopy(data, 900, data, 0, 100); 417 read = 100 + is.read(data, 100, 900); 418 } 419 420 s = new String(data, 0, read); 421 i = s.indexOf(nssHeader1); 422 if (i > 0 || (i = s.indexOf(nssHeader2)) > 0) { 423 found = true; 424 // If the nssHeader is before 920 we can break, otherwise 425 // we may not have the whole header so do another read. If 426 // no bytes are in the stream, that is ok, found is true. 427 if (i < 920) { 428 break; 429 } 430 } 431 } 432 } 433 } catch (Exception e) { 434 e.printStackTrace(); 435 } 436 437 if (!found) { 438 System.out.println("lib" + library + 439 " version not found, set to 0.0: " + libfile); 440 nss_version = 0.0; 441 return nss_version; 442 } 443 444 // the index after whitespace after nssHeader 445 int afterheader = s.indexOf("NSS", i) + 4; 446 String version = s.substring(afterheader, s.indexOf(' ', afterheader)); 447 448 // If a "dot dot" release, strip the extra dots for double parsing 449 String[] dot = version.split("\\."); 450 if (dot.length > 2) { 451 version = dot[0]+"."+dot[1]; 452 for (int j = 2; dot.length > j; j++) { 453 version += dot[j]; 454 } 455 } 456 457 // Convert to double for easier version value checking 458 try { 459 nss_version = Double.parseDouble(version); 460 } catch (NumberFormatException e) { 461 System.out.println("Failed to parse lib" + library + 462 " version. Set to 0.0"); 463 e.printStackTrace(); 464 } 465 466 System.out.print("lib" + library + " version = "+version+". "); 467 468 // Check for ECC 469 if (s.indexOf("Basic") > 0) { 470 nss_ecc_status = ECCState.Basic; 471 System.out.println("ECC Basic."); 472 } else if (s.indexOf("Extended") > 0) { 473 nss_ecc_status = ECCState.Extended; 474 System.out.println("ECC Extended."); 475 } else { 476 System.out.println("ECC None."); 477 } 478 479 if (library.compareTo("softokn3") == 0) { 480 softoken3_version = nss_version; 481 } else if (library.compareTo("nss3") == 0) { 482 nss3_version = nss_version; 483 } 484 485 return nss_version; 486 } 487 488 // Used to set the nss_library file to search for libsoftokn3.so 489 public static void useNSS() { 490 nss_library = "nss3"; 491 } 492 493 public static void testNSS(PKCS11Test test) throws Exception { 494 String libdir = getNSSLibDir(); 495 if (libdir == null) { 496 return; 497 } 498 String base = getBase(); 499 500 if (loadNSPR(libdir) == false) { 501 return; 502 } 503 504 String libfile = libdir + System.mapLibraryName(nss_library); 505 506 String customDBdir = System.getProperty("CUSTOM_DB_DIR"); 507 String dbdir = (customDBdir != null) ? 508 customDBdir : 509 base + SEP + "nss" + SEP + "db"; 510 // NSS always wants forward slashes for the config path 511 dbdir = dbdir.replace('\\', '/'); 512 513 String customConfig = System.getProperty("CUSTOM_P11_CONFIG"); 514 String customConfigName = System.getProperty("CUSTOM_P11_CONFIG_NAME", "p11-nss.txt"); 515 String p11config = (customConfig != null) ? 516 customConfig : 517 base + SEP + "nss" + SEP + customConfigName; 518 519 System.setProperty("pkcs11test.nss.lib", libfile); 520 System.setProperty("pkcs11test.nss.db", dbdir); 521 Provider p = getSunPKCS11(p11config); 522 test.premain(p); 523 } 524 525 // Generate a vector of supported elliptic curves of a given provider 526 static List<ECParameterSpec> getKnownCurves(Provider p) throws Exception { 527 int index; 528 int begin; 529 int end; 530 String curve; 531 532 List<ECParameterSpec> results = new ArrayList<>(); 533 // Get Curves to test from SunEC. 534 String kcProp = Security.getProvider("SunEC"). 535 getProperty("AlgorithmParameters.EC SupportedCurves"); 536 537 if (kcProp == null) { 538 throw new RuntimeException( 539 "\"AlgorithmParameters.EC SupportedCurves property\" not found"); 540 } 541 542 System.out.println("Finding supported curves using list from SunEC\n"); 543 index = 0; 544 for (;;) { 545 // Each set of curve names is enclosed with brackets. 546 begin = kcProp.indexOf('[', index); 547 end = kcProp.indexOf(']', index); 548 if (begin == -1 || end == -1) { 549 break; 550 } 551 552 /* 553 * Each name is separated by a comma. 554 * Just get the first name in the set. 555 */ 556 index = end + 1; 557 begin++; 558 end = kcProp.indexOf(',', begin); 559 if (end == -1) { 560 // Only one name in the set. 561 end = index -1; 562 } 563 564 curve = kcProp.substring(begin, end); 565 ECParameterSpec e = getECParameterSpec(p, curve); 566 System.out.print("\t "+ curve + ": "); 567 try { 568 KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", p); 569 kpg.initialize(e); 570 kpg.generateKeyPair(); 571 results.add(e); 572 System.out.println("Supported"); 573 } catch (ProviderException ex) { 574 System.out.println("Unsupported: PKCS11: " + 575 ex.getCause().getMessage()); 576 } catch (InvalidAlgorithmParameterException ex) { 577 System.out.println("Unsupported: Key Length: " + 578 ex.getMessage()); 579 } 580 } 581 582 if (results.size() == 0) { 583 throw new RuntimeException("No supported EC curves found"); 584 } 585 586 return results; 587 } 588 589 private static ECParameterSpec getECParameterSpec(Provider p, String name) 590 throws Exception { 591 592 AlgorithmParameters parameters = 593 AlgorithmParameters.getInstance("EC", p); 594 595 parameters.init(new ECGenParameterSpec(name)); 596 597 return parameters.getParameterSpec(ECParameterSpec.class); 598 } 599 600 // Check support for a curve with a provided Vector of EC support 601 boolean checkSupport(List<ECParameterSpec> supportedEC, 602 ECParameterSpec curve) { 603 for (ECParameterSpec ec: supportedEC) { 604 if (ec.equals(curve)) { 605 return true; 606 } 607 } 608 return false; 609 } 610 611 private static final Map<String,String[]> osMap; 612 613 // Location of the NSS libraries on each supported platform 614 static { 615 osMap = new HashMap<>(); 616 osMap.put("SunOS-sparc-32", new String[]{"/usr/lib/mps/"}); 617 osMap.put("SunOS-sparcv9-64", new String[]{"/usr/lib/mps/64/"}); 618 osMap.put("SunOS-x86-32", new String[]{"/usr/lib/mps/"}); 619 osMap.put("SunOS-amd64-64", new String[]{"/usr/lib/mps/64/"}); 620 osMap.put("Linux-i386-32", new String[]{ 621 "/usr/lib/i386-linux-gnu/", "/usr/lib32/", "/usr/lib/"}); 622 osMap.put("Linux-amd64-64", new String[]{ 623 "/usr/lib/x86_64-linux-gnu/", "/usr/lib/x86_64-linux-gnu/nss/", 624 "/usr/lib64/"}); 625 osMap.put("Linux-ppc64-64", new String[]{"/usr/lib64/"}); 626 osMap.put("Linux-ppc64le-64", new String[]{"/usr/lib64/"}); 627 osMap.put("Linux-s390x-64", new String[]{"/usr/lib64/"}); 628 osMap.put("Windows-x86-32", new String[]{ 629 PKCS11_BASE + "/nss/lib/windows-i586/".replace('/', SEP)}); 630 osMap.put("Windows-amd64-64", new String[]{ 631 PKCS11_BASE + "/nss/lib/windows-amd64/".replace('/', SEP)}); 632 osMap.put("MacOSX-x86_64-64", new String[]{ 633 PKCS11_BASE + "/nss/lib/macosx-x86_64/"}); 634 osMap.put("Linux-arm-32", new String[]{ 635 "/usr/lib/arm-linux-gnueabi/nss/", 636 "/usr/lib/arm-linux-gnueabihf/nss/"}); 637 osMap.put("Linux-aarch64-64", new String[]{ 638 "/usr/lib/aarch64-linux-gnu/nss/"}); 639 } 640 641 private final static char[] hexDigits = "0123456789abcdef".toCharArray(); 642 643 static final boolean badNSSVersion = 644 getNSSVersion() >= 3.11 && getNSSVersion() < 3.12; 645 646 private static final String distro = distro(); 647 648 static final boolean badSolarisSparc = 649 System.getProperty("os.name").equals("SunOS") && 650 System.getProperty("os.arch").equals("sparcv9") && 651 System.getProperty("os.version").compareTo("5.11") <= 0 && 652 getDistro().compareTo("11.2") < 0; 653 654 public static String toString(byte[] b) { 655 if (b == null) { 656 return "(null)"; 657 } 658 StringBuilder sb = new StringBuilder(b.length * 3); 659 for (int i = 0; i < b.length; i++) { 660 int k = b[i] & 0xff; 661 if (i != 0) { 662 sb.append(':'); 663 } 664 sb.append(hexDigits[k >>> 4]); 665 sb.append(hexDigits[k & 0xf]); 666 } 667 return sb.toString(); 668 } 669 670 public static byte[] parse(String s) { 671 if (s.equals("(null)")) { 672 return null; 673 } 674 try { 675 int n = s.length(); 676 ByteArrayOutputStream out = new ByteArrayOutputStream(n / 3); 677 StringReader r = new StringReader(s); 678 while (true) { 679 int b1 = nextNibble(r); 680 if (b1 < 0) { 681 break; 682 } 683 int b2 = nextNibble(r); 684 if (b2 < 0) { 685 throw new RuntimeException("Invalid string " + s); 686 } 687 int b = (b1 << 4) | b2; 688 out.write(b); 689 } 690 return out.toByteArray(); 691 } catch (IOException e) { 692 throw new RuntimeException(e); 693 } 694 } 695 696 private static int nextNibble(StringReader r) throws IOException { 697 while (true) { 698 int ch = r.read(); 699 if (ch == -1) { 700 return -1; 701 } else if ((ch >= '0') && (ch <= '9')) { 702 return ch - '0'; 703 } else if ((ch >= 'a') && (ch <= 'f')) { 704 return ch - 'a' + 10; 705 } else if ((ch >= 'A') && (ch <= 'F')) { 706 return ch - 'A' + 10; 707 } 708 } 709 } 710 711 <T> T[] concat(T[] a, T[] b) { 712 if ((b == null) || (b.length == 0)) { 713 return a; 714 } 715 T[] r = Arrays.copyOf(a, a.length + b.length); 716 System.arraycopy(b, 0, r, a.length, b.length); 717 return r; 718 } 719 720 /** 721 * Returns supported algorithms of specified type. 722 */ 723 static List<String> getSupportedAlgorithms(String type, String alg, 724 Provider p) { 725 // prepare a list of supported algorithms 726 List<String> algorithms = new ArrayList<>(); 727 Set<Provider.Service> services = p.getServices(); 728 for (Provider.Service service : services) { 729 if (service.getType().equals(type) 730 && service.getAlgorithm().startsWith(alg)) { 731 algorithms.add(service.getAlgorithm()); 732 } 733 } 734 return algorithms; 735 } 736 737 /** 738 * Get the identifier for the operating system distribution 739 */ 740 static String getDistro() { 741 return distro; 742 } 743 744 private static String distro() { 745 if (props.getProperty("os.name").equals("SunOS")) { 746 try (BufferedReader in = 747 new BufferedReader(new InputStreamReader( 748 Runtime.getRuntime().exec("uname -v").getInputStream()))) { 749 750 return in.readLine(); 751 } catch (Exception e) { 752 throw new RuntimeException("Failed to determine distro.", e); 753 } 754 } else { 755 // Not used outside Solaris 756 return null; 757 } 758 } 759 760 static byte[] generateData(int length) { 761 byte data[] = new byte[length]; 762 for (int i=0; i<data.length; i++) { 763 data[i] = (byte) (i % 256); 764 } 765 return data; 766 } 767 }