/* * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.security.pkcs11; import java.io.*;import java.util.*; import java.security.*;import java.security.interfaces.*; import javax.crypto.interfaces.*; import javax.security.auth.Subject;import javax.security.auth.login.LoginException;import javax.security.auth.login.FailedLoginException;import javax.security.auth.callback.Callback;import javax.security.auth.callback.CallbackHandler;import javax.security.auth.callback.ConfirmationCallback;import javax.security.auth.callback.PasswordCallback;import javax.security.auth.callback.TextOutputCallback; import sun.security.util.Debug;import sun.security.util.ResourcesMgr; import sun.security.pkcs11.Secmod.*; import sun.security.pkcs11.wrapper.*;import static sun.security.pkcs11.wrapper.PKCS11Constants.*; /** * PKCS#11 provider main class. * * @author Andreas Sterbenz * @since 1.5 */public final class SunPKCS11 extends AuthProvider { private static final long serialVersionUID = -1354835039035306505L; static final Debug debug = Debug.getInstance("sunpkcs11"); private static int dummyConfigId; // the PKCS11 object through which we make the native calls final PKCS11 p11; // name of the configuration file private final String configName; // configuration information final Config config; // id of the PKCS#11 slot we are using final long slotID; private CallbackHandler pHandler; private final Object LOCK_HANDLER = new Object(); final boolean removable; final Module nssModule; final boolean nssUseSecmodTrust; private volatile Token token; private TokenPoller poller; Token getToken() { return token; } public SunPKCS11() { super("SunPKCS11-Dummy", 1.7d, "SunPKCS11-Dummy"); throw new ProviderException ("SunPKCS11 requires configuration file argument"); } public SunPKCS11(String configName) { this(checkNull(configName), null); } public SunPKCS11(InputStream configStream) { this(getDummyConfigName(), checkNull(configStream)); } private static <T> T checkNull(T obj) { if (obj == null) { throw new NullPointerException(); } return obj; } private static synchronized String getDummyConfigName() { int id = ++dummyConfigId; return "---DummyConfig-" + id + "---"; } /** * @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream) * instead */ @Deprecated public SunPKCS11(String configName, InputStream configStream) { super("SunPKCS11-" + Config.getConfig(configName, configStream).getName(), 1.7d, Config.getConfig(configName, configStream).getDescription()); this.configName = configName; this.config = Config.removeConfig(configName); if (debug != null) { System.out.println("SunPKCS11 loading " + configName); } String library = config.getLibrary(); String functionList = config.getFunctionList(); long slotID = config.getSlotID(); int slotListIndex = config.getSlotListIndex(); boolean useSecmod = config.getNssUseSecmod(); boolean nssUseSecmodTrust = config.getNssUseSecmodTrust(); Module nssModule = null; // // Initialization via Secmod. The way this works is as follows: // SunPKCS11 is either in normal mode or in NSS Secmod mode. // Secmod is activated by specifying one or more of the following // options in the config file: // nssUseSecmod, nssSecmodDirectory, nssLibrary, nssModule // // XXX add more explanation here // // If we are in Secmod mode and configured to use either the // nssKeyStore or the nssTrustAnchors module, we automatically // switch to using the NSS trust attributes for trusted certs // (KeyStore). // if (useSecmod) { // note: Config ensures library/slot/slotListIndex not specified // in secmod mode. Secmod secmod = Secmod.getInstance(); DbMode nssDbMode = config.getNssDbMode(); try { String nssLibraryDirectory = config.getNssLibraryDirectory(); String nssSecmodDirectory = config.getNssSecmodDirectory(); if (secmod.isInitialized()) { if (nssSecmodDirectory != null) { String s = secmod.getConfigDir(); if ((s != null) && (s.equals(nssSecmodDirectory) == false)) { throw new ProviderException("Secmod directory " + nssSecmodDirectory + " invalid, NSS already initialized with " + s); } } if (nssLibraryDirectory != null) { String s = secmod.getLibDir(); if ((s != null) && (s.equals(nssLibraryDirectory) == false)) { throw new ProviderException("NSS library directory " + nssLibraryDirectory + " invalid, NSS already initialized with " + s); } } } else { if (nssDbMode != DbMode.NO_DB) { if (nssSecmodDirectory == null) { throw new ProviderException( "Secmod not initialized and " + "nssSecmodDirectory not specified"); } } else { if (nssSecmodDirectory != null) { throw new ProviderException( "nssSecmodDirectory must not be " + "specified in noDb mode"); } } secmod.initialize(nssDbMode, nssSecmodDirectory, nssLibraryDirectory); } } catch (IOException e) { // XXX which exception to throw throw new ProviderException("Could not initialize NSS", e); } List<Module> modules = secmod.getModules(); if (config.getShowInfo()) { System.out.println("NSS modules: " + modules); } String moduleName = config.getNssModule(); if (moduleName == null) { nssModule = secmod.getModule(ModuleType.FIPS); if (nssModule != null) { moduleName = "fips"; } else { moduleName = (nssDbMode == DbMode.NO_DB) ? "crypto" : "keystore"; } } if (moduleName.equals("fips")) { nssModule = secmod.getModule(ModuleType.FIPS); nssUseSecmodTrust = true; functionList = "FC_GetFunctionList"; } else if (moduleName.equals("keystore")) { nssModule = secmod.getModule(ModuleType.KEYSTORE); nssUseSecmodTrust = true; } else if (moduleName.equals("crypto")) { nssModule = secmod.getModule(ModuleType.CRYPTO); } else if (moduleName.equals("trustanchors")) { // XXX should the option be called trustanchor or trustanchors?? nssModule = secmod.getModule(ModuleType.TRUSTANCHOR); nssUseSecmodTrust = true; } else if (moduleName.startsWith("external-")) { int moduleIndex; try { moduleIndex = Integer.parseInt (moduleName.substring("external-".length())); } catch (NumberFormatException e) { moduleIndex = -1; } if (moduleIndex < 1) { throw new ProviderException ("Invalid external module: " + moduleName); } int k = 0; for (Module module : modules) { if (module.getType() == ModuleType.EXTERNAL) { if (++k == moduleIndex) { nssModule = module; break; } } } if (nssModule == null) { throw new ProviderException("Invalid module " + moduleName + ": only " + k + " external NSS modules available"); } } else { throw new ProviderException( "Unknown NSS module: " + moduleName); } if (nssModule == null) { throw new ProviderException( "NSS module not available: " + moduleName); } if (nssModule.hasInitializedProvider()) { throw new ProviderException("Secmod module already configured"); } library = nssModule.libraryName; slotListIndex = nssModule.slot; } this.nssUseSecmodTrust = nssUseSecmodTrust; this.nssModule = nssModule; File libraryFile = new File(library); // if the filename is a simple filename without path // (e.g. "libpkcs11.so"), it may refer to a library somewhere on the // OS library search path. Omit the test for file existance as that // only looks in the current directory. if (libraryFile.getName().equals(library) == false) { if (new File(library).isFile() == false) { String msg = "Library " + library + " does not exist"; if (config.getHandleStartupErrors() == Config.ERR_HALT) { throw new ProviderException(msg); } else { throw new UnsupportedOperationException(msg); } } } try { if (debug != null) { debug.println("Initializing PKCS#11 library " + library); } CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS(); String nssArgs = config.getNssArgs(); if (nssArgs != null) { initArgs.pReserved = nssArgs; } // request multithreaded access first initArgs.flags = CKF_OS_LOCKING_OK; PKCS11 tmpPKCS11; try { tmpPKCS11 = PKCS11.getInstance( library, functionList, initArgs, config.getOmitInitialize()); } catch (PKCS11Exception e) { if (debug != null) { debug.println("Multi-threaded initialization failed: " + e); } if (config.getAllowSingleThreadedModules() == false) { throw e; } // fall back to single threaded access if (nssArgs == null) { // if possible, use null initArgs for better compatibility initArgs = null; } else { initArgs.flags = 0; } tmpPKCS11 = PKCS11.getInstance(library, functionList, initArgs, config.getOmitInitialize()); } p11 = tmpPKCS11; CK_INFO p11Info = p11.C_GetInfo(); if (p11Info.cryptokiVersion.major < 2) { throw new ProviderException("Only PKCS#11 v2.0 and later " + "supported, library version is v" + p11Info.cryptokiVersion); } boolean showInfo = config.getShowInfo(); if (showInfo) { System.out.println("Information for provider " + getName()); System.out.println("Library info:"); System.out.println(p11Info); } if ((slotID < 0) || showInfo) { long[] slots = p11.C_GetSlotList(false); if (showInfo) { System.out.println("All slots: " + toString(slots)); slots = p11.C_GetSlotList(true); System.out.println("Slots with tokens: " + toString(slots)); } if (slotID < 0) { if ((slotListIndex < 0) || (slotListIndex >= slots.length)) { throw new ProviderException("slotListIndex is " + slotListIndex + " but token only has " + slots.length + " slots"); } slotID = slots[slotListIndex]; } } this.slotID = slotID; CK_SLOT_INFO slotInfo = p11.C_GetSlotInfo(slotID); removable = (slotInfo.flags & CKF_REMOVABLE_DEVICE) != 0; initToken(slotInfo); if (nssModule != null) { nssModule.setProvider(this); } } catch (Exception e) { if (config.getHandleStartupErrors() == Config.ERR_IGNORE_ALL) { throw new UnsupportedOperationException ("Initialization failed", e); } else { throw new ProviderException ("Initialization failed", e); } } } private static String toString(long[] longs) { if (longs.length == 0) { return "(none)"; } StringBuilder sb = new StringBuilder(); sb.append(longs[0]); for (int i = 1; i < longs.length; i++) { sb.append(", "); sb.append(longs[i]); } return sb.toString(); } public boolean equals(Object obj) { return this == obj; } public int hashCode() { return System.identityHashCode(this); } private static String[] s(String s1) { return new String[] {s1}; } private static String[] s(String s1, String s2) { return new String[] {s1, s2}; } private static final class Descriptor { final String type; final String algorithm; final String className; final String[] aliases; final int[] mechanisms; private Descriptor(String type, String algorithm, String className, String[] aliases, int[] mechanisms) { this.type = type; this.algorithm = algorithm; this.className = className; this.aliases = aliases; this.mechanisms = mechanisms; } private P11Service service(Token token, int mechanism) { return new P11Service (token, type, algorithm, className, aliases, mechanism); } public String toString() { return type + "." + algorithm; } } // Map from mechanism to List of Descriptors that should be // registered if the mechanism is supported private final static Map<Integer,List<Descriptor>> descriptors = new HashMap<Integer,List<Descriptor>>(); private static int[] m(long m1) { return new int[] {(int)m1}; } private static int[] m(long m1, long m2) { return new int[] {(int)m1, (int)m2}; } private static int[] m(long m1, long m2, long m3) { return new int[] {(int)m1, (int)m2, (int)m3}; } private static int[] m(long m1, long m2, long m3, long m4) { return new int[] {(int)m1, (int)m2, (int)m3, (int)m4}; } private static void d(String type, String algorithm, String className, int[] m) { register(new Descriptor(type, algorithm, className, null, m)); } private static void d(String type, String algorithm, String className, String[] aliases, int[] m) { register(new Descriptor(type, algorithm, className, aliases, m)); } private static void register(Descriptor d) { for (int i = 0; i < d.mechanisms.length; i++) { int m = d.mechanisms[i]; Integer key = Integer.valueOf(m); List<Descriptor> list = descriptors.get(key); if (list == null) { list = new ArrayList<Descriptor>(); descriptors.put(key, list); } list.add(d); } } private final static String MD = "MessageDigest"; private final static String SIG = "Signature"; private final static String KPG = "KeyPairGenerator"; private final static String KG = "KeyGenerator"; private final static String AGP = "AlgorithmParameters"; private final static String KF = "KeyFactory"; private final static String SKF = "SecretKeyFactory"; private final static String CIP = "Cipher"; private final static String MAC = "Mac"; private final static String KA = "KeyAgreement"; private final static String KS = "KeyStore"; private final static String SR = "SecureRandom"; Lines 1–500 of 1394. Load more
/* * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.security.pkcs11; import java.io.*; import java.util.*; import java.security.*; import java.security.interfaces.*; import javax.crypto.interfaces.*; import javax.security.auth.Subject; import javax.security.auth.login.LoginException; import javax.security.auth.login.FailedLoginException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.ConfirmationCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.TextOutputCallback; import sun.security.util.Debug; import sun.security.util.ResourcesMgr; import sun.security.pkcs11.Secmod.*; import sun.security.pkcs11.wrapper.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; /** * PKCS#11 provider main class. * * @author Andreas Sterbenz * @since 1.5 */ public final class SunPKCS11 extends AuthProvider { private static final long serialVersionUID = -1354835039035306505L; static final Debug debug = Debug.getInstance("sunpkcs11"); private static int dummyConfigId; // the PKCS11 object through which we make the native calls final PKCS11 p11; // name of the configuration file private final String configName; // configuration information final Config config; // id of the PKCS#11 slot we are using final long slotID; private CallbackHandler pHandler; private final Object LOCK_HANDLER = new Object(); final boolean removable; final Module nssModule; final boolean nssUseSecmodTrust; private volatile Token token; private TokenPoller poller; Token getToken() { return token; } public SunPKCS11() { super("SunPKCS11-Dummy", 1.7d, "SunPKCS11-Dummy"); throw new ProviderException ("SunPKCS11 requires configuration file argument"); } public SunPKCS11(String configName) { this(checkNull(configName), null); } public SunPKCS11(InputStream configStream) { this(getDummyConfigName(), checkNull(configStream)); } private static <T> T checkNull(T obj) { if (obj == null) { throw new NullPointerException(); } return obj; } private static synchronized String getDummyConfigName() { int id = ++dummyConfigId; return "---DummyConfig-" + id + "---"; } /** * @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream) * instead */ @Deprecated public SunPKCS11(String configName, InputStream configStream) { super("SunPKCS11-" + Config.getConfig(configName, configStream).getName(), 1.7d, Config.getConfig(configName, configStream).getDescription()); this.configName = configName; this.config = Config.removeConfig(configName); if (debug != null) { System.out.println("SunPKCS11 loading " + configName); } String library = config.getLibrary(); String functionList = config.getFunctionList(); long slotID = config.getSlotID(); int slotListIndex = config.getSlotListIndex(); boolean useSecmod = config.getNssUseSecmod(); boolean nssUseSecmodTrust = config.getNssUseSecmodTrust(); Module nssModule = null; // // Initialization via Secmod. The way this works is as follows: // SunPKCS11 is either in normal mode or in NSS Secmod mode. // Secmod is activated by specifying one or more of the following // options in the config file: // nssUseSecmod, nssSecmodDirectory, nssLibrary, nssModule // // XXX add more explanation here // // If we are in Secmod mode and configured to use either the // nssKeyStore or the nssTrustAnchors module, we automatically // switch to using the NSS trust attributes for trusted certs // (KeyStore). // if (useSecmod) { // note: Config ensures library/slot/slotListIndex not specified // in secmod mode. Secmod secmod = Secmod.getInstance(); DbMode nssDbMode = config.getNssDbMode(); try { String nssLibraryDirectory = config.getNssLibraryDirectory(); String nssSecmodDirectory = config.getNssSecmodDirectory(); if (secmod.isInitialized()) { if (nssSecmodDirectory != null) { String s = secmod.getConfigDir(); if ((s != null) && (s.equals(nssSecmodDirectory) == false)) { throw new ProviderException("Secmod directory " + nssSecmodDirectory + " invalid, NSS already initialized with " + s); } } if (nssLibraryDirectory != null) { String s = secmod.getLibDir(); if ((s != null) && (s.equals(nssLibraryDirectory) == false)) { throw new ProviderException("NSS library directory " + nssLibraryDirectory + " invalid, NSS already initialized with " + s); } } } else { if (nssDbMode != DbMode.NO_DB) { if (nssSecmodDirectory == null) { throw new ProviderException( "Secmod not initialized and " + "nssSecmodDirectory not specified"); } } else { if (nssSecmodDirectory != null) { throw new ProviderException( "nssSecmodDirectory must not be " + "specified in noDb mode"); } } secmod.initialize(nssDbMode, nssSecmodDirectory, nssLibraryDirectory); } } catch (IOException e) { // XXX which exception to throw throw new ProviderException("Could not initialize NSS", e); } List<Module> modules = secmod.getModules(); if (config.getShowInfo()) { System.out.println("NSS modules: " + modules); } String moduleName = config.getNssModule(); if (moduleName == null) { nssModule = secmod.getModule(ModuleType.FIPS); if (nssModule != null) { moduleName = "fips"; } else { moduleName = (nssDbMode == DbMode.NO_DB) ? "crypto" : "keystore"; } } if (moduleName.equals("fips")) { nssModule = secmod.getModule(ModuleType.FIPS); nssUseSecmodTrust = true; functionList = "FC_GetFunctionList"; } else if (moduleName.equals("keystore")) { nssModule = secmod.getModule(ModuleType.KEYSTORE); nssUseSecmodTrust = true; } else if (moduleName.equals("crypto")) { nssModule = secmod.getModule(ModuleType.CRYPTO); } else if (moduleName.equals("trustanchors")) { // XXX should the option be called trustanchor or trustanchors?? nssModule = secmod.getModule(ModuleType.TRUSTANCHOR); nssUseSecmodTrust = true; } else if (moduleName.startsWith("external-")) { int moduleIndex; try { moduleIndex = Integer.parseInt (moduleName.substring("external-".length())); } catch (NumberFormatException e) { moduleIndex = -1; } if (moduleIndex < 1) { throw new ProviderException ("Invalid external module: " + moduleName); } int k = 0; for (Module module : modules) { if (module.getType() == ModuleType.EXTERNAL) { if (++k == moduleIndex) { nssModule = module; break; } } } if (nssModule == null) { throw new ProviderException("Invalid module " + moduleName + ": only " + k + " external NSS modules available"); } } else { throw new ProviderException( "Unknown NSS module: " + moduleName); } if (nssModule == null) { throw new ProviderException( "NSS module not available: " + moduleName); } if (nssModule.hasInitializedProvider()) { throw new ProviderException("Secmod module already configured"); } library = nssModule.libraryName; slotListIndex = nssModule.slot; } this.nssUseSecmodTrust = nssUseSecmodTrust; this.nssModule = nssModule; File libraryFile = new File(library); // if the filename is a simple filename without path // (e.g. "libpkcs11.so"), it may refer to a library somewhere on the // OS library search path. Omit the test for file existance as that // only looks in the current directory. if (libraryFile.getName().equals(library) == false) { if (new File(library).isFile() == false) { String msg = "Library " + library + " does not exist"; if (config.getHandleStartupErrors() == Config.ERR_HALT) { throw new ProviderException(msg); } else { throw new UnsupportedOperationException(msg); } } } try { if (debug != null) { debug.println("Initializing PKCS#11 library " + library); } CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS(); String nssArgs = config.getNssArgs(); if (nssArgs != null) { initArgs.pReserved = nssArgs; } // request multithreaded access first initArgs.flags = CKF_OS_LOCKING_OK; PKCS11 tmpPKCS11; try { tmpPKCS11 = PKCS11.getInstance( library, functionList, initArgs, config.getOmitInitialize()); } catch (PKCS11Exception e) { if (debug != null) { debug.println("Multi-threaded initialization failed: " + e); } if (config.getAllowSingleThreadedModules() == false) { throw e; } // fall back to single threaded access if (nssArgs == null) { // if possible, use null initArgs for better compatibility initArgs = null; } else { initArgs.flags = 0; } tmpPKCS11 = PKCS11.getInstance(library, functionList, initArgs, config.getOmitInitialize()); } p11 = tmpPKCS11; CK_INFO p11Info = p11.C_GetInfo(); if (p11Info.cryptokiVersion.major < 2) { throw new ProviderException("Only PKCS#11 v2.0 and later " + "supported, library version is v" + p11Info.cryptokiVersion); } boolean showInfo = config.getShowInfo(); if (showInfo) { System.out.println("Information for provider " + getName()); System.out.println("Library info:"); System.out.println(p11Info); } if ((slotID < 0) || showInfo) { long[] slots = p11.C_GetSlotList(false); if (showInfo) { System.out.println("All slots: " + toString(slots)); slots = p11.C_GetSlotList(true); System.out.println("Slots with tokens: " + toString(slots)); } if (slotID < 0) { if ((slotListIndex < 0) || (slotListIndex >= slots.length)) { throw new ProviderException("slotListIndex is " + slotListIndex + " but token only has " + slots.length + " slots"); } slotID = slots[slotListIndex]; } } this.slotID = slotID; CK_SLOT_INFO slotInfo = p11.C_GetSlotInfo(slotID); removable = (slotInfo.flags & CKF_REMOVABLE_DEVICE) != 0; initToken(slotInfo); if (nssModule != null) { nssModule.setProvider(this); } } catch (Exception e) { if (config.getHandleStartupErrors() == Config.ERR_IGNORE_ALL) { throw new UnsupportedOperationException ("Initialization failed", e); } else { throw new ProviderException ("Initialization failed", e); } } } private static String toString(long[] longs) { if (longs.length == 0) { return "(none)"; } StringBuilder sb = new StringBuilder(); sb.append(longs[0]); for (int i = 1; i < longs.length; i++) { sb.append(", "); sb.append(longs[i]); } return sb.toString(); } public boolean equals(Object obj) { return this == obj; } public int hashCode() { return System.identityHashCode(this); } private static String[] s(String s1) { return new String[] {s1}; } private static String[] s(String s1, String s2) { return new String[] {s1, s2}; } private static final class Descriptor { final String type; final String algorithm; final String className; final String[] aliases; final int[] mechanisms; private Descriptor(String type, String algorithm, String className, String[] aliases, int[] mechanisms) { this.type = type; this.algorithm = algorithm; this.className = className; this.aliases = aliases; this.mechanisms = mechanisms; } private P11Service service(Token token, int mechanism) { return new P11Service (token, type, algorithm, className, aliases, mechanism); } public String toString() { return type + "." + algorithm; } } // Map from mechanism to List of Descriptors that should be // registered if the mechanism is supported private final static Map<Integer,List<Descriptor>> descriptors = new HashMap<Integer,List<Descriptor>>(); private static int[] m(long m1) { return new int[] {(int)m1}; } private static int[] m(long m1, long m2) { return new int[] {(int)m1, (int)m2}; } private static int[] m(long m1, long m2, long m3) { return new int[] {(int)m1, (int)m2, (int)m3}; } private static int[] m(long m1, long m2, long m3, long m4) { return new int[] {(int)m1, (int)m2, (int)m3, (int)m4}; } private static void d(String type, String algorithm, String className, int[] m) { register(new Descriptor(type, algorithm, className, null, m)); } private static void d(String type, String algorithm, String className, String[] aliases, int[] m) { register(new Descriptor(type, algorithm, className, aliases, m)); } private static void register(Descriptor d) { for (int i = 0; i < d.mechanisms.length; i++) { int m = d.mechanisms[i]; Integer key = Integer.valueOf(m); List<Descriptor> list = descriptors.get(key); if (list == null) { list = new ArrayList<Descriptor>(); descriptors.put(key, list); } list.add(d); } } private final static String MD = "MessageDigest"; private final static String SIG = "Signature"; private final static String KPG = "KeyPairGenerator"; private final static String KG = "KeyGenerator"; private final static String AGP = "AlgorithmParameters"; private final static String KF = "KeyFactory"; private final static String SKF = "SecretKeyFactory"; private final static String CIP = "Cipher"; private final static String MAC = "Mac"; private final static String KA = "KeyAgreement"; private final static String KS = "KeyStore"; private final static String SR = "SecureRandom";