1 /* 2 * Copyright (c) 2005, 2013, 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", "/usr/sfw/lib/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); 162 } 163 164 public synchronized void initialize(DbMode dbMode, String configDir, String nssLibDir) 165 throws IOException { 166 if (isInitialized()) { 167 throw new IOException("NSS is already initialized"); 168 } 169 170 if (dbMode == null) { 171 throw new NullPointerException(); 172 } 173 if ((dbMode != DbMode.NO_DB) && (configDir == null)) { 174 throw new NullPointerException(); 175 } 176 String platformLibName = System.mapLibraryName("nss3"); 177 String platformPath; 178 if (nssLibDir == null) { 179 platformPath = platformLibName; 180 } else { 181 File base = new File(nssLibDir); 182 if (base.isDirectory() == false) { 183 throw new IOException("nssLibDir must be a directory:" + nssLibDir); 184 } 185 File platformFile = new File(base, platformLibName); 186 if (platformFile.isFile() == false) { 187 throw new FileNotFoundException(platformFile.getPath()); 188 } 189 platformPath = platformFile.getPath(); 190 } 191 192 if (configDir != null) { 193 File configBase = new File(configDir); 194 if (configBase.isDirectory() == false ) { 195 throw new IOException("configDir must be a directory: " + configDir); 196 } 197 File secmodFile = new File(configBase, "secmod.db"); 198 if (secmodFile.isFile() == false) { 199 throw new FileNotFoundException(secmodFile.getPath()); 200 } 201 } 202 203 if (DEBUG) System.out.println("lib: " + platformPath); 204 nssHandle = nssLoadLibrary(platformPath); 205 if (DEBUG) System.out.println("handle: " + nssHandle); 206 fetchVersions(); 207 if (supported == false) { 208 throw new IOException 209 ("The specified version of NSS is incompatible, " 210 + "3.7 or later required"); 211 } 212 213 if (DEBUG) System.out.println("dir: " + configDir); 214 boolean initok = nssInit(dbMode.functionName, nssHandle, configDir); 215 if (DEBUG) System.out.println("init: " + initok); 216 if (initok == false) { 217 throw new IOException("NSS initialization failed"); 218 } 219 220 this.configDir = configDir; 221 this.nssLibDir = nssLibDir; 222 } 223 224 /** 225 * Return an immutable list of all available modules. 226 * 227 * @throws IllegalStateException if this Secmod is misconfigured 228 * or not initialized 229 */ 230 public synchronized List<Module> getModules() { 231 try { 232 if (isInitialized() == false) { 233 throw new IllegalStateException("NSS not initialized"); 234 } 235 } catch (IOException e) { 236 // IOException if misconfigured 237 throw new IllegalStateException(e); 238 } 239 if (modules == null) { 240 @SuppressWarnings("unchecked") 241 List<Module> modules = (List<Module>)nssGetModuleList(nssHandle, 242 nssLibDir); 243 this.modules = Collections.unmodifiableList(modules); 244 } 245 return modules; 246 } 247 248 private static byte[] getDigest(X509Certificate cert, String algorithm) { 249 try { 250 MessageDigest md = MessageDigest.getInstance(algorithm); 251 return md.digest(cert.getEncoded()); 252 } catch (GeneralSecurityException e) { 253 throw new ProviderException(e); 254 } 255 } 256 257 boolean isTrusted(X509Certificate cert, TrustType trustType) { 258 Bytes bytes = new Bytes(getDigest(cert, "SHA-1")); 259 TrustAttributes attr = getModuleTrust(ModuleType.KEYSTORE, bytes); 260 if (attr == null) { 261 attr = getModuleTrust(ModuleType.FIPS, bytes); 262 if (attr == null) { 263 attr = getModuleTrust(ModuleType.TRUSTANCHOR, bytes); 264 } 265 } 266 return (attr == null) ? false : attr.isTrusted(trustType); 267 } 268 269 private TrustAttributes getModuleTrust(ModuleType type, Bytes bytes) { 270 Module module = getModule(type); 271 TrustAttributes t = (module == null) ? null : module.getTrust(bytes); 272 return t; 273 } 274 275 /** 276 * Constants describing the different types of NSS modules. 277 * For this API, NSS modules are classified as either one 278 * of the internal modules delivered as part of NSS or 279 * as an external module provided by a 3rd party. 280 */ 281 public static enum ModuleType { 282 /** 283 * The NSS Softtoken crypto module. This is the first 284 * slot of the softtoken object. 285 * This module provides 286 * implementations for cryptographic algorithms but no KeyStore. 287 */ 288 CRYPTO, 289 /** 290 * The NSS Softtoken KeyStore module. This is the second 291 * slot of the softtoken object. 292 * This module provides 293 * implementations for cryptographic algorithms (after login) 294 * and the KeyStore. 295 */ 296 KEYSTORE, 297 /** 298 * The NSS Softtoken module in FIPS mode. Note that in FIPS mode the 299 * softtoken presents only one slot, not separate CRYPTO and KEYSTORE 300 * slots as in non-FIPS mode. 301 */ 302 FIPS, 303 /** 304 * The NSS builtin trust anchor module. This is the 305 * NSSCKBI object. It provides no crypto functions. 306 */ 307 TRUSTANCHOR, 308 /** 309 * An external module. 310 */ 311 EXTERNAL, 312 } 313 314 /** 315 * Returns the first module of the specified type. If no such 316 * module exists, this method returns null. 317 * 318 * @throws IllegalStateException if this Secmod is misconfigured 319 * or not initialized 320 */ 321 public Module getModule(ModuleType type) { 322 for (Module module : getModules()) { 323 if (module.getType() == type) { 324 return module; 325 } 326 } 327 return null; 328 } 329 330 static final String TEMPLATE_EXTERNAL = 331 "library = %s\n" 332 + "name = \"%s\"\n" 333 + "slotListIndex = %d\n"; 334 335 static final String TEMPLATE_TRUSTANCHOR = 336 "library = %s\n" 337 + "name = \"NSS Trust Anchors\"\n" 338 + "slotListIndex = 0\n" 339 + "enabledMechanisms = { KeyStore }\n" 340 + "nssUseSecmodTrust = true\n"; 341 342 static final String TEMPLATE_CRYPTO = 343 "library = %s\n" 344 + "name = \"NSS SoftToken Crypto\"\n" 345 + "slotListIndex = 0\n" 346 + "disabledMechanisms = { KeyStore }\n"; 347 348 static final String TEMPLATE_KEYSTORE = 349 "library = %s\n" 350 + "name = \"NSS SoftToken KeyStore\"\n" 351 + "slotListIndex = 1\n" 352 + "nssUseSecmodTrust = true\n"; 353 354 static final String TEMPLATE_FIPS = 355 "library = %s\n" 356 + "name = \"NSS FIPS SoftToken\"\n" 357 + "slotListIndex = 0\n" 358 + "nssUseSecmodTrust = true\n"; 359 360 /** 361 * A representation of one PKCS#11 slot in a PKCS#11 module. 362 */ 363 public static final class Module { 364 // path of the native library 365 final String libraryName; 366 // descriptive name used by NSS 367 final String commonName; 368 final int slot; 369 final ModuleType type; 370 371 private String config; 372 private SunPKCS11 provider; 373 374 // trust attributes. Used for the KEYSTORE and TRUSTANCHOR modules only 375 private Map<Bytes,TrustAttributes> trust; 376 377 Module(String libraryDir, String libraryName, String commonName, 378 boolean fips, int slot) { 379 ModuleType type; 380 381 if ((libraryName == null) || (libraryName.length() == 0)) { 382 // must be softtoken 383 libraryName = System.mapLibraryName(SOFTTOKEN_LIB_NAME); 384 if (fips == false) { 385 type = (slot == 0) ? ModuleType.CRYPTO : ModuleType.KEYSTORE; 386 } else { 387 type = ModuleType.FIPS; 388 if (slot != 0) { 389 throw new RuntimeException 390 ("Slot index should be 0 for FIPS slot"); 391 } 392 } 393 } else { 394 if (libraryName.endsWith(System.mapLibraryName(TRUST_LIB_NAME)) 395 || commonName.equals("Builtin Roots Module")) { 396 type = ModuleType.TRUSTANCHOR; 397 } else { 398 type = ModuleType.EXTERNAL; 399 } 400 if (fips) { 401 throw new RuntimeException("FIPS flag set for non-internal " 402 + "module: " + libraryName + ", " + commonName); 403 } 404 } 405 // On Ubuntu the libsoftokn3 library is located in a subdirectory 406 // of the system libraries directory. (Since Ubuntu 11.04.) 407 File libraryFile = new File(libraryDir, libraryName); 408 if (!libraryFile.isFile()) { 409 File failover = new File(libraryDir, "nss/" + libraryName); 410 if (failover.isFile()) { 411 libraryFile = failover; 412 } 413 } 414 this.libraryName = libraryFile.getPath(); 415 this.commonName = commonName; 416 this.slot = slot; 417 this.type = type; 418 initConfiguration(); 419 } 420 421 private void initConfiguration() { 422 switch (type) { 423 case EXTERNAL: 424 config = String.format(TEMPLATE_EXTERNAL, libraryName, 425 commonName + " " + slot, slot); 426 break; 427 case CRYPTO: 428 config = String.format(TEMPLATE_CRYPTO, libraryName); 429 break; 430 case KEYSTORE: 431 config = String.format(TEMPLATE_KEYSTORE, libraryName); 432 break; 433 case FIPS: 434 config = String.format(TEMPLATE_FIPS, libraryName); 435 break; 436 case TRUSTANCHOR: 437 config = String.format(TEMPLATE_TRUSTANCHOR, libraryName); 438 break; 439 default: 440 throw new RuntimeException("Unknown module type: " + type); 441 } 442 } 443 444 /** 445 * Get the configuration for this module. This is a string 446 * in the SunPKCS11 configuration format. It can be 447 * customized with additional options and then made 448 * current using the setConfiguration() method. 449 */ 450 @Deprecated 451 public synchronized String getConfiguration() { 452 return config; 453 } 454 455 /** 456 * Set the configuration for this module. 457 * 458 * @throws IllegalStateException if the associated provider 459 * instance has already been created. 460 */ 461 @Deprecated 462 public synchronized void setConfiguration(String config) { 463 if (provider != null) { 464 throw new IllegalStateException("Provider instance already created"); 465 } 466 this.config = config; 467 } 468 469 /** 470 * Return the pathname of the native library that implements 471 * this module. For example, /usr/lib/libpkcs11.so. 472 */ 473 public String getLibraryName() { 474 return libraryName; 475 } 476 477 /** 478 * Returns the type of this module. 479 */ 480 public ModuleType getType() { 481 return type; 482 } 483 484 /** 485 * Returns the provider instance that is associated with this 486 * module. The first call to this method creates the provider 487 * instance. 488 */ 489 @Deprecated 490 public synchronized Provider getProvider() { 491 if (provider == null) { 492 provider = newProvider(); 493 } 494 return provider; 495 } 496 497 synchronized boolean hasInitializedProvider() { 498 return provider != null; 499 } 500 501 void setProvider(SunPKCS11 p) { 502 if (provider != null) { 503 throw new ProviderException("Secmod provider already initialized"); 504 } 505 provider = p; 506 } 507 508 private SunPKCS11 newProvider() { 509 try { 510 InputStream in = new ByteArrayInputStream(config.getBytes("UTF8")); 511 return new SunPKCS11(in); 512 } catch (Exception e) { 513 // XXX 514 throw new ProviderException(e); 515 } 516 } 517 518 synchronized void setTrust(Token token, X509Certificate cert) { 519 Bytes bytes = new Bytes(getDigest(cert, "SHA-1")); 520 TrustAttributes attr = getTrust(bytes); 521 if (attr == null) { 522 attr = new TrustAttributes(token, cert, bytes, CKT_NETSCAPE_TRUSTED_DELEGATOR); 523 trust.put(bytes, attr); 524 } else { 525 // does it already have the correct trust settings? 526 if (attr.isTrusted(TrustType.ALL) == false) { 527 // XXX not yet implemented 528 throw new ProviderException("Cannot change existing trust attributes"); 529 } 530 } 531 } 532 533 TrustAttributes getTrust(Bytes hash) { 534 if (trust == null) { 535 // If provider is not set, create a temporary provider to 536 // retrieve the trust information. This can happen if we need 537 // to get the trust information for the trustanchor module 538 // because we need to look for user customized settings in the 539 // keystore module (which may not have a provider created yet). 540 // Creating a temporary provider and then dropping it on the 541 // floor immediately is flawed, but it's the best we can do 542 // for now. 543 synchronized (this) { 544 SunPKCS11 p = provider; 545 if (p == null) { 546 p = newProvider(); 547 } 548 try { 549 trust = Secmod.getTrust(p); 550 } catch (PKCS11Exception e) { 551 throw new RuntimeException(e); 552 } 553 } 554 } 555 return trust.get(hash); 556 } 557 558 public String toString() { 559 return 560 commonName + " (" + type + ", " + libraryName + ", slot " + slot + ")"; 561 } 562 563 } 564 565 /** 566 * Constants representing NSS trust categories. 567 */ 568 public static enum TrustType { 569 /** Trusted for all purposes */ 570 ALL, 571 /** Trusted for SSL client authentication */ 572 CLIENT_AUTH, 573 /** Trusted for SSL server authentication */ 574 SERVER_AUTH, 575 /** Trusted for code signing */ 576 CODE_SIGNING, 577 /** Trusted for email protection */ 578 EMAIL_PROTECTION, 579 } 580 581 public static enum DbMode { 582 READ_WRITE("NSS_InitReadWrite"), 583 READ_ONLY ("NSS_Init"), 584 NO_DB ("NSS_NoDB_Init"); 585 586 final String functionName; 587 DbMode(String functionName) { 588 this.functionName = functionName; 589 } 590 } 591 592 /** 593 * A LoadStoreParameter for use with the NSS Softtoken or 594 * NSS TrustAnchor KeyStores. 595 * <p> 596 * It allows the set of trusted certificates that are returned by 597 * the KeyStore to be specified. 598 */ 599 public static final class KeyStoreLoadParameter implements LoadStoreParameter { 600 final TrustType trustType; 601 final ProtectionParameter protection; 602 public KeyStoreLoadParameter(TrustType trustType, char[] password) { 603 this(trustType, new PasswordProtection(password)); 604 605 } 606 public KeyStoreLoadParameter(TrustType trustType, ProtectionParameter prot) { 607 if (trustType == null) { 608 throw new NullPointerException("trustType must not be null"); 609 } 610 this.trustType = trustType; 611 this.protection = prot; 612 } 613 public ProtectionParameter getProtectionParameter() { 614 return protection; 615 } 616 public TrustType getTrustType() { 617 return trustType; 618 } 619 } 620 621 static class TrustAttributes { 622 final long handle; 623 final long clientAuth, serverAuth, codeSigning, emailProtection; 624 final byte[] shaHash; 625 TrustAttributes(Token token, X509Certificate cert, Bytes bytes, long trustValue) { 626 Session session = null; 627 try { 628 session = token.getOpSession(); 629 // XXX use KeyStore TrustType settings to determine which 630 // attributes to set 631 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] { 632 new CK_ATTRIBUTE(CKA_TOKEN, true), 633 new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST), 634 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH, trustValue), 635 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING, trustValue), 636 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION, trustValue), 637 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH, trustValue), 638 new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH, bytes.b), 639 new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_MD5_HASH, getDigest(cert, "MD5")), 640 new CK_ATTRIBUTE(CKA_ISSUER, cert.getIssuerX500Principal().getEncoded()), 641 new CK_ATTRIBUTE(CKA_SERIAL_NUMBER, cert.getSerialNumber().toByteArray()), 642 // XXX per PKCS#11 spec, the serial number should be in ASN.1 643 }; 644 handle = token.p11.C_CreateObject(session.id(), attrs); 645 shaHash = bytes.b; 646 clientAuth = trustValue; 647 serverAuth = trustValue; 648 codeSigning = trustValue; 649 emailProtection = trustValue; 650 } catch (PKCS11Exception e) { 651 throw new ProviderException("Could not create trust object", e); 652 } finally { 653 token.releaseSession(session); 654 } 655 } 656 TrustAttributes(Token token, Session session, long handle) 657 throws PKCS11Exception { 658 this.handle = handle; 659 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] { 660 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH), 661 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING), 662 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION), 663 new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH), 664 }; 665 666 token.p11.C_GetAttributeValue(session.id(), handle, attrs); 667 serverAuth = attrs[0].getLong(); 668 codeSigning = attrs[1].getLong(); 669 emailProtection = attrs[2].getLong(); 670 shaHash = attrs[3].getByteArray(); 671 672 attrs = new CK_ATTRIBUTE[] { 673 new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH), 674 }; 675 long c; 676 try { 677 token.p11.C_GetAttributeValue(session.id(), handle, attrs); 678 c = attrs[0].getLong(); 679 } catch (PKCS11Exception e) { 680 // trust anchor module does not support this attribute 681 c = serverAuth; 682 } 683 clientAuth = c; 684 } 685 Bytes getHash() { 686 return new Bytes(shaHash); 687 } 688 boolean isTrusted(TrustType type) { 689 switch (type) { 690 case CLIENT_AUTH: 691 return isTrusted(clientAuth); 692 case SERVER_AUTH: 693 return isTrusted(serverAuth); 694 case CODE_SIGNING: 695 return isTrusted(codeSigning); 696 case EMAIL_PROTECTION: 697 return isTrusted(emailProtection); 698 case ALL: 699 return isTrusted(TrustType.CLIENT_AUTH) 700 && isTrusted(TrustType.SERVER_AUTH) 701 && isTrusted(TrustType.CODE_SIGNING) 702 && isTrusted(TrustType.EMAIL_PROTECTION); 703 default: 704 return false; 705 } 706 } 707 708 private boolean isTrusted(long l) { 709 // XXX CKT_TRUSTED? 710 return (l == CKT_NETSCAPE_TRUSTED_DELEGATOR); 711 } 712 713 } 714 715 private static class Bytes { 716 final byte[] b; 717 Bytes(byte[] b) { 718 this.b = b; 719 } 720 public int hashCode() { 721 return Arrays.hashCode(b); 722 } 723 public boolean equals(Object o) { 724 if (this == o) { 725 return true; 726 } 727 if (o instanceof Bytes == false) { 728 return false; 729 } 730 Bytes other = (Bytes)o; 731 return Arrays.equals(this.b, other.b); 732 } 733 } 734 735 private static Map<Bytes,TrustAttributes> getTrust(SunPKCS11 provider) 736 throws PKCS11Exception { 737 Map<Bytes,TrustAttributes> trustMap = new HashMap<Bytes,TrustAttributes>(); 738 Token token = provider.getToken(); 739 Session session = null; 740 try { 741 session = token.getOpSession(); 742 int MAX_NUM = 8192; 743 CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] { 744 new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST), 745 }; 746 token.p11.C_FindObjectsInit(session.id(), attrs); 747 long[] handles = token.p11.C_FindObjects(session.id(), MAX_NUM); 748 token.p11.C_FindObjectsFinal(session.id()); 749 if (DEBUG) System.out.println("handles: " + handles.length); 750 751 for (long handle : handles) { 752 TrustAttributes trust = new TrustAttributes(token, session, handle); 753 trustMap.put(trust.getHash(), trust); 754 } 755 } finally { 756 token.releaseSession(session); 757 } 758 return trustMap; 759 } 760 761 private static native long nssGetLibraryHandle(String libraryName); 762 763 private static native long nssLoadLibrary(String name) throws IOException; 764 765 private static native boolean nssVersionCheck(long handle, String minVersion); 766 767 private static native boolean nssInit(String functionName, long handle, String configDir); 768 769 private static native Object nssGetModuleList(long handle, String libDir); 770 771 }