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