1 /* 2 * Copyright (c) 2005, 2015, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.pkcs11; 27 28 import java.io.*; 29 import java.util.*; 30 31 import java.security.*; 32 import java.security.KeyStore.*; 33 import java.security.cert.X509Certificate; 34 35 import sun.security.pkcs11.wrapper.*; 36 import static sun.security.pkcs11.wrapper.PKCS11Constants.*; 37 38 39 /** 40 * The Secmod class defines the interface to the native NSS 41 * library and the configuration information it stores in its 42 * secmod.db file. 43 * 44 * <p>Example code: 45 * <pre> 46 * Secmod secmod = Secmod.getInstance(); 47 * if (secmod.isInitialized() == false) { 48 * secmod.initialize("/home/myself/.mozilla"); 49 * } 50 * 51 * Provider p = secmod.getModule(ModuleType.KEYSTORE).getProvider(); 52 * KeyStore ks = KeyStore.getInstance("PKCS11", p); 53 * ks.load(null, password); 54 * </pre> 55 * 56 * @since 1.6 57 * @author Andreas Sterbenz 58 */ 59 public final class Secmod { 60 61 private final static boolean DEBUG = false; 62 63 private final static Secmod INSTANCE; 64 65 static { 66 sun.security.pkcs11.wrapper.PKCS11.loadNative(); 67 INSTANCE = new Secmod(); 68 } 69 70 private final static String NSS_LIB_NAME = "nss3"; 71 72 private final static String SOFTTOKEN_LIB_NAME = "softokn3"; 73 74 private final static String TRUST_LIB_NAME = "nssckbi"; 75 76 // handle to be passed to the native code, 0 means not initialized 77 private long nssHandle; 78 79 // whether this is a supported version of NSS 80 private boolean supported; 81 82 // list of the modules 83 private List<Module> modules; 84 85 private String configDir; 86 87 private String nssLibDir; 88 89 private Secmod() { 90 // empty 91 } 92 93 /** 94 * Return the singleton Secmod instance. 95 */ 96 public static Secmod getInstance() { 97 return INSTANCE; 98 } 99 100 private boolean isLoaded() { 101 if (nssHandle == 0) { 102 nssHandle = nssGetLibraryHandle(System.mapLibraryName(NSS_LIB_NAME)); 103 if (nssHandle != 0) { 104 fetchVersions(); 105 } 106 } 107 return (nssHandle != 0); 108 } 109 110 private void fetchVersions() { 111 supported = nssVersionCheck(nssHandle, "3.7"); 112 } 113 114 /** 115 * Test whether this Secmod has been initialized. Returns true 116 * if NSS has been initialized using either the initialize() method 117 * or by directly calling the native NSS APIs. The latter may be 118 * the case if the current process contains components that use 119 * NSS directly. 120 * 121 * @throws IOException if an incompatible version of NSS 122 * has been loaded 123 */ 124 public synchronized boolean isInitialized() throws IOException { 125 // NSS does not allow us to check if it is initialized already 126 // assume that if it is loaded it is also initialized 127 if (isLoaded() == false) { 128 return false; 129 } 130 if (supported == false) { 131 throw new IOException 132 ("An incompatible version of NSS is already loaded, " 133 + "3.7 or later required"); 134 } 135 return true; 136 } 137 138 String getConfigDir() { 139 return configDir; 140 } 141 142 String getLibDir() { 143 return nssLibDir; 144 } 145 146 /** 147 * Initialize this Secmod. 148 * 149 * @param configDir the directory containing the NSS configuration 150 * files such as secmod.db 151 * @param nssLibDir the directory containing the NSS libraries 152 * (libnss3.so or nss3.dll) or null if the library is on 153 * the system default shared library path 154 * 155 * @throws IOException if NSS has already been initialized, 156 * the specified directories are invalid, or initialization 157 * fails for any other reason 158 */ 159 public void initialize(String configDir, String nssLibDir) 160 throws IOException { 161 initialize(DbMode.READ_WRITE, configDir, nssLibDir, false); 162 } 163 164 public void initialize(DbMode dbMode, String configDir, String nssLibDir) 165 throws IOException { 166 initialize(dbMode, configDir, nssLibDir, false); 167 } 168 169 public synchronized void initialize(DbMode dbMode, String configDir, 170 String nssLibDir, boolean nssOptimizeSpace) throws IOException { 171 172 if (isInitialized()) { 173 throw new IOException("NSS is already initialized"); 174 } 175 176 if (dbMode == null) { 177 throw new NullPointerException(); 178 } 179 if ((dbMode != DbMode.NO_DB) && (configDir == null)) { 180 throw new NullPointerException(); 181 } 182 String platformLibName = System.mapLibraryName("nss3"); 183 String platformPath; 184 if (nssLibDir == null) { 185 platformPath = platformLibName; 186 } else { 187 File base = new File(nssLibDir); 188 if (base.isDirectory() == false) { 189 throw new IOException("nssLibDir must be a directory:" + nssLibDir); 190 } 191 File platformFile = new File(base, platformLibName); 192 if (platformFile.isFile() == false) { 193 throw new FileNotFoundException(platformFile.getPath()); 194 } 195 platformPath = platformFile.getPath(); 196 } 197 198 if (configDir != null) { 199 File configBase = new File(configDir); 200 if (configBase.isDirectory() == false ) { 201 throw new IOException("configDir must be a directory: " + configDir); 202 } 203 File secmodFile = new File(configBase, "secmod.db"); 204 if (secmodFile.isFile() == false) { 205 throw new FileNotFoundException(secmodFile.getPath()); 206 } 207 } 208 209 if (DEBUG) System.out.println("lib: " + platformPath); 210 nssHandle = nssLoadLibrary(platformPath); 211 if (DEBUG) System.out.println("handle: " + nssHandle); 212 fetchVersions(); 213 if (supported == false) { 214 throw new IOException 215 ("The specified version of NSS is incompatible, " 216 + "3.7 or later required"); 217 } 218 219 if (DEBUG) System.out.println("dir: " + configDir); 220 boolean initok = nssInitialize(dbMode.functionName, nssHandle, 221 configDir, nssOptimizeSpace); 222 if (DEBUG) System.out.println("init: " + initok); 223 if (initok == false) { 224 throw new IOException("NSS initialization failed"); 225 } 226 227 this.configDir = configDir; 228 this.nssLibDir = nssLibDir; 229 } 230 231 /** 232 * Return an immutable list of all available modules. 233 * 234 * @throws IllegalStateException if this Secmod is misconfigured 235 * or not initialized 236 */ 237 public synchronized List<Module> getModules() { 238 try { 239 if (isInitialized() == false) { 240 throw new IllegalStateException("NSS not initialized"); 241 } 242 } catch (IOException e) { 243 // IOException if misconfigured 244 throw new IllegalStateException(e); 245 } 246 if (modules == null) { 247 @SuppressWarnings("unchecked") 248 List<Module> modules = (List<Module>)nssGetModuleList(nssHandle, 249 nssLibDir); 250 this.modules = Collections.unmodifiableList(modules); 251 } 252 return modules; 253 } 254 255 private static byte[] getDigest(X509Certificate cert, String algorithm) { 256 try { 257 MessageDigest md = MessageDigest.getInstance(algorithm); 258 return md.digest(cert.getEncoded()); 259 } catch (GeneralSecurityException e) { 260 throw new ProviderException(e); 261 } 262 } 263 264 boolean isTrusted(X509Certificate cert, TrustType trustType) { 265 Bytes bytes = new Bytes(getDigest(cert, "SHA-1")); 266 TrustAttributes attr = getModuleTrust(ModuleType.KEYSTORE, bytes); 267 if (attr == null) { 268 attr = getModuleTrust(ModuleType.FIPS, bytes); 269 if (attr == null) { 270 attr = getModuleTrust(ModuleType.TRUSTANCHOR, bytes); 271 } 272 } 273 return (attr == null) ? false : attr.isTrusted(trustType); 274 } 275 276 private TrustAttributes getModuleTrust(ModuleType type, Bytes bytes) { 277 Module module = getModule(type); 278 TrustAttributes t = (module == null) ? null : module.getTrust(bytes); 279 return t; 280 } 281 282 /** 283 * Constants describing the different types of NSS modules. 284 * For this API, NSS modules are classified as either one 285 * of the internal modules delivered as part of NSS or 286 * as an external module provided by a 3rd party. 287 */ 288 public static enum ModuleType { 289 /** 290 * The NSS Softtoken crypto module. This is the first 291 * slot of the softtoken object. 292 * This module provides 293 * implementations for cryptographic algorithms but no KeyStore. 294 */ 295 CRYPTO, 296 /** 297 * The NSS Softtoken KeyStore module. This is the second 298 * slot of the softtoken object. 299 * This module provides 300 * implementations for cryptographic algorithms (after login) 301 * and the KeyStore. 302 */ 303 KEYSTORE, 304 /** 305 * The NSS Softtoken module in FIPS mode. Note that in FIPS mode the 306 * softtoken presents only one slot, not separate CRYPTO and KEYSTORE 307 * slots as in non-FIPS mode. 308 */ 309 FIPS, 310 /** 311 * The NSS builtin trust anchor module. This is the 312 * NSSCKBI object. It provides no crypto functions. 313 */ 314 TRUSTANCHOR, 315 /** 316 * An external module. 317 */ 318 EXTERNAL, 319 } 320 321 /** 322 * Returns the first module of the specified type. If no such 323 * module exists, this method returns null. 324 * 325 * @throws IllegalStateException if this Secmod is misconfigured 326 * or not initialized 327 */ 328 public Module getModule(ModuleType type) { 329 for (Module module : getModules()) { 330 if (module.getType() == type) { 331 return module; 332 } 333 } 334 return null; 335 } 336 337 static final String TEMPLATE_EXTERNAL = 338 "library = %s\n" 339 + "name = \"%s\"\n" 340 + "slotListIndex = %d\n"; 341 342 static final String TEMPLATE_TRUSTANCHOR = 343 "library = %s\n" 344 + "name = \"NSS Trust Anchors\"\n" 345 + "slotListIndex = 0\n" 346 + "enabledMechanisms = { KeyStore }\n" 347 + "nssUseSecmodTrust = true\n"; 348 349 static final String TEMPLATE_CRYPTO = 350 "library = %s\n" 351 + "name = \"NSS SoftToken Crypto\"\n" 352 + "slotListIndex = 0\n" 353 + "disabledMechanisms = { KeyStore }\n"; 354 355 static final String TEMPLATE_KEYSTORE = 356 "library = %s\n" 357 + "name = \"NSS SoftToken KeyStore\"\n" 358 + "slotListIndex = 1\n" 359 + "nssUseSecmodTrust = true\n"; 360 361 static final String TEMPLATE_FIPS = 362 "library = %s\n" 363 + "name = \"NSS FIPS SoftToken\"\n" 364 + "slotListIndex = 0\n" 365 + "nssUseSecmodTrust = true\n"; 366 367 /** 368 * A representation of one PKCS#11 slot in a PKCS#11 module. 369 */ 370 public static final class Module { 371 // path of the native library 372 final String libraryName; 373 // descriptive name used by NSS 374 final String commonName; 375 final int slot; 376 final ModuleType type; 377 378 private String config; 379 private SunPKCS11 provider; 380 381 // trust attributes. Used for the KEYSTORE and TRUSTANCHOR modules only 382 private Map<Bytes,TrustAttributes> trust; 383 384 Module(String libraryDir, String libraryName, String commonName, 385 boolean fips, int slot) { 386 ModuleType type; 387 388 if ((libraryName == null) || (libraryName.length() == 0)) { 389 // must be softtoken 390 libraryName = System.mapLibraryName(SOFTTOKEN_LIB_NAME); 391 if (fips == false) { 392 type = (slot == 0) ? ModuleType.CRYPTO : ModuleType.KEYSTORE; 393 } else { 394 type = ModuleType.FIPS; 395 if (slot != 0) { 396 throw new RuntimeException 397 ("Slot index should be 0 for FIPS slot"); 398 } 399 } 400 } else { 401 if (libraryName.endsWith(System.mapLibraryName(TRUST_LIB_NAME)) 402 || commonName.equals("Builtin Roots Module")) { 403 type = ModuleType.TRUSTANCHOR; 404 } else { 405 type = ModuleType.EXTERNAL; 406 } 407 if (fips) { 408 throw new RuntimeException("FIPS flag set for non-internal " 409 + "module: " + libraryName + ", " + commonName); 410 } 411 } 412 // On Ubuntu the libsoftokn3 library is located in a subdirectory 413 // of the system libraries directory. (Since Ubuntu 11.04.) 414 File libraryFile = new File(libraryDir, libraryName); 415 if (!libraryFile.isFile()) { 416 File failover = new File(libraryDir, "nss/" + libraryName); 417 if (failover.isFile()) { 418 libraryFile = failover; 419 } 420 } 421 this.libraryName = libraryFile.getPath(); 422 this.commonName = commonName; 423 this.slot = slot; 424 this.type = type; 425 initConfiguration(); 426 } 427 428 private void initConfiguration() { 429 switch (type) { 430 case EXTERNAL: 431 config = String.format(TEMPLATE_EXTERNAL, libraryName, 432 commonName + " " + slot, slot); 433 break; 434 case CRYPTO: 435 config = String.format(TEMPLATE_CRYPTO, libraryName); 436 break; 437 case KEYSTORE: 438 config = String.format(TEMPLATE_KEYSTORE, libraryName); 439 break; 440 case FIPS: 441 config = String.format(TEMPLATE_FIPS, libraryName); 442 break; 443 case TRUSTANCHOR: 444 config = String.format(TEMPLATE_TRUSTANCHOR, libraryName); 445 break; 446 default: 447 throw new RuntimeException("Unknown module type: " + type); 448 } 449 } 450 451 /** 452 * Get the configuration for this module. This is a string 453 * in the SunPKCS11 configuration format. It can be 454 * customized with additional options and then made 455 * current using the setConfiguration() method. 456 */ 457 @Deprecated 458 public synchronized String getConfiguration() { 459 return config; 460 } 461 462 /** 463 * Set the configuration for this module. 464 * 465 * @throws IllegalStateException if the associated provider 466 * instance has already been created. 467 */ 468 @Deprecated 469 public synchronized void setConfiguration(String config) { 470 if (provider != null) { 471 throw new IllegalStateException("Provider instance already created"); 472 } 473 this.config = config; 474 } 475 476 /** 477 * Return the pathname of the native library that implements 478 * this module. For example, /usr/lib/libpkcs11.so. 479 */ 480 public String getLibraryName() { 481 return libraryName; 482 } 483 484 /** 485 * Returns the type of this module. 486 */ 487 public ModuleType getType() { 488 return type; 489 } 490 491 /** 492 * Returns the provider instance that is associated with this 493 * module. The first call to this method creates the provider 494 * instance. 495 */ 496 @Deprecated 497 public synchronized Provider getProvider() { 498 if (provider == null) { 499 provider = newProvider(); 500 } 501 return provider; 502 } 503 504 synchronized boolean hasInitializedProvider() { 505 return provider != null; 506 } 507 508 void setProvider(SunPKCS11 p) { 509 if (provider != null) { 510 throw new ProviderException("Secmod provider already initialized"); 511 } 512 provider = p; 513 } 514 515 private SunPKCS11 newProvider() { 516 try { 517 return new SunPKCS11(new Config("--" + config)); 518 } catch (Exception e) { 519 // XXX 520 throw new ProviderException(e); 521 } 522 } 523 524 synchronized void setTrust(Token token, X509Certificate cert) { 525 Bytes bytes = new Bytes(getDigest(cert, "SHA-1")); 526 TrustAttributes attr = getTrust(bytes); 527 if (attr == null) { 528 attr = new TrustAttributes(token, cert, bytes, CKT_NETSCAPE_TRUSTED_DELEGATOR); 529 trust.put(bytes, attr); 530 } else { 531 // does it already have the correct trust settings? 532 if (attr.isTrusted(TrustType.ALL) == false) { 533 // XXX not yet implemented 534 throw new ProviderException("Cannot change existing trust attributes"); 535 } 536 } 537 } 538 539 TrustAttributes getTrust(Bytes hash) { 540 if (trust == null) { 541 // If provider is not set, create a temporary provider to 542 // retrieve the trust information. This can happen if we need 543 // to get the trust information for the trustanchor module 544 // because we need to look for user customized settings in the 545 // keystore module (which may not have a provider created yet). 546 // Creating a temporary provider and then dropping it on the 547 // floor immediately is flawed, but it's the best we can do 548 // for now. 549 synchronized (this) { 550 SunPKCS11 p = provider; 551 if (p == null) { 552 p = newProvider(); 553 } 554 try { 555 trust = Secmod.getTrust(p); 556 } catch (PKCS11Exception e) { 557 throw new RuntimeException(e); 558 } 559 } 560 } 561 return trust.get(hash); 562 } 563 564 public String toString() { 565 return 566 commonName + " (" + type + ", " + libraryName + ", slot " + slot + ")"; 567 } 568 569 } 570 571 /** 572 * Constants representing NSS trust categories. 573 */ 574 public static enum TrustType { 575 /** Trusted for all purposes */ 576 ALL, 577 /** Trusted for SSL client authentication */ 578 CLIENT_AUTH, 579 /** Trusted for SSL server authentication */ 580 SERVER_AUTH, 581 /** Trusted for code signing */ 582 CODE_SIGNING, 583 /** Trusted for email protection */ 584 EMAIL_PROTECTION, 585 } 586 587 public static enum DbMode { 588 READ_WRITE("NSS_InitReadWrite"), 589 READ_ONLY ("NSS_Init"), 590 NO_DB ("NSS_NoDB_Init"); 591 592 final String functionName; 593 DbMode(String functionName) { 594 this.functionName = functionName; 595 } 596 } 597 598 /** 599 * A LoadStoreParameter for use with the NSS Softtoken or 600 * NSS TrustAnchor KeyStores. 601 * <p> 602 * It allows the set of trusted certificates that are returned by 603 * the KeyStore to be specified. 604 */ 605 public static final class KeyStoreLoadParameter implements LoadStoreParameter { 606 final TrustType trustType; 607 final ProtectionParameter protection; 608 public KeyStoreLoadParameter(TrustType trustType, char[] password) { 609 this(trustType, new PasswordProtection(password)); 610 611 } 612 public KeyStoreLoadParameter(TrustType trustType, ProtectionParameter prot) { 613 if (trustType == null) { 614 throw new NullPointerException("trustType must not be null"); 615 } 616 this.trustType = trustType; 617 this.protection = prot; 618 } 619 public ProtectionParameter getProtectionParameter() { 620 return protection; 621 } 622 public TrustType getTrustType() { 623 return trustType; 624 } 625 } 626 627 static class TrustAttributes { 628 final long handle; 629 final long clientAuth, serverAuth, codeSigning, emailProtection; 630 final byte[] shaHash; 631 TrustAttributes(Token token, X509Certificate cert, Bytes bytes, long trustValue) { 632 Session session = null; 633 try { 634 session = token.getOpSession(); 635 // XXX use KeyStore TrustType settings to determine which 636 // attributes to set 637 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] { 638 new CK_ATTRIBUTE(CKA_TOKEN, true), 639 new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST), 640 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH, trustValue), 641 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING, trustValue), 642 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION, trustValue), 643 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH, trustValue), 644 new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH, bytes.b), 645 new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_MD5_HASH, getDigest(cert, "MD5")), 646 new CK_ATTRIBUTE(CKA_ISSUER, cert.getIssuerX500Principal().getEncoded()), 647 new CK_ATTRIBUTE(CKA_SERIAL_NUMBER, cert.getSerialNumber().toByteArray()), 648 // XXX per PKCS#11 spec, the serial number should be in ASN.1 649 }; 650 handle = token.p11.C_CreateObject(session.id(), attrs); 651 shaHash = bytes.b; 652 clientAuth = trustValue; 653 serverAuth = trustValue; 654 codeSigning = trustValue; 655 emailProtection = trustValue; 656 } catch (PKCS11Exception e) { 657 throw new ProviderException("Could not create trust object", e); 658 } finally { 659 token.releaseSession(session); 660 } 661 } 662 TrustAttributes(Token token, Session session, long handle) 663 throws PKCS11Exception { 664 this.handle = handle; 665 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] { 666 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH), 667 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING), 668 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION), 669 new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH), 670 }; 671 672 token.p11.C_GetAttributeValue(session.id(), handle, attrs); 673 serverAuth = attrs[0].getLong(); 674 codeSigning = attrs[1].getLong(); 675 emailProtection = attrs[2].getLong(); 676 shaHash = attrs[3].getByteArray(); 677 678 attrs = new CK_ATTRIBUTE[] { 679 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH), 680 }; 681 long c; 682 try { 683 token.p11.C_GetAttributeValue(session.id(), handle, attrs); 684 c = attrs[0].getLong(); 685 } catch (PKCS11Exception e) { 686 // trust anchor module does not support this attribute 687 c = serverAuth; 688 } 689 clientAuth = c; 690 } 691 Bytes getHash() { 692 return new Bytes(shaHash); 693 } 694 boolean isTrusted(TrustType type) { 695 switch (type) { 696 case CLIENT_AUTH: 697 return isTrusted(clientAuth); 698 case SERVER_AUTH: 699 return isTrusted(serverAuth); 700 case CODE_SIGNING: 701 return isTrusted(codeSigning); 702 case EMAIL_PROTECTION: 703 return isTrusted(emailProtection); 704 case ALL: 705 return isTrusted(TrustType.CLIENT_AUTH) 706 && isTrusted(TrustType.SERVER_AUTH) 707 && isTrusted(TrustType.CODE_SIGNING) 708 && isTrusted(TrustType.EMAIL_PROTECTION); 709 default: 710 return false; 711 } 712 } 713 714 private boolean isTrusted(long l) { 715 // XXX CKT_TRUSTED? 716 return (l == CKT_NETSCAPE_TRUSTED_DELEGATOR); 717 } 718 719 } 720 721 private static class Bytes { 722 final byte[] b; 723 Bytes(byte[] b) { 724 this.b = b; 725 } 726 public int hashCode() { 727 return Arrays.hashCode(b); 728 } 729 public boolean equals(Object o) { 730 if (this == o) { 731 return true; 732 } 733 if (o instanceof Bytes == false) { 734 return false; 735 } 736 Bytes other = (Bytes)o; 737 return Arrays.equals(this.b, other.b); 738 } 739 } 740 741 private static Map<Bytes,TrustAttributes> getTrust(SunPKCS11 provider) 742 throws PKCS11Exception { 743 Map<Bytes,TrustAttributes> trustMap = new HashMap<Bytes,TrustAttributes>(); 744 Token token = provider.getToken(); 745 Session session = null; 746 boolean exceptionOccurred = true; 747 try { 748 session = token.getOpSession(); 749 int MAX_NUM = 8192; 750 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] { 751 new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST), 752 }; 753 token.p11.C_FindObjectsInit(session.id(), attrs); 754 long[] handles = token.p11.C_FindObjects(session.id(), MAX_NUM); 755 token.p11.C_FindObjectsFinal(session.id()); 756 if (DEBUG) System.out.println("handles: " + handles.length); 757 758 for (long handle : handles) { 759 try { 760 TrustAttributes trust = new TrustAttributes(token, session, handle); 761 trustMap.put(trust.getHash(), trust); 762 } catch (PKCS11Exception e) { 763 // skip put on pkcs11 error 764 } 765 } 766 exceptionOccurred = false; 767 } finally { 768 if (exceptionOccurred) { 769 token.killSession(session); 770 } else { 771 token.releaseSession(session); 772 } 773 } 774 return trustMap; 775 } 776 777 private static native long nssGetLibraryHandle(String libraryName); 778 779 private static native long nssLoadLibrary(String name) throws IOException; 780 781 private static native boolean nssVersionCheck(long handle, String minVersion); 782 783 private static native boolean nssInitialize(String functionName, long handle, String configDir, boolean nssOptimizeSpace); 784 785 private static native Object nssGetModuleList(long handle, String libDir); 786 787 }