46 import sun.security.util.Debug;
47 import sun.security.util.ResourcesMgr;
48
49 import sun.security.pkcs11.Secmod.*;
50
51 import sun.security.pkcs11.wrapper.*;
52 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
53
54 /**
55 * PKCS#11 provider main class.
56 *
57 * @author Andreas Sterbenz
58 * @since 1.5
59 */
60 public final class SunPKCS11 extends AuthProvider {
61
62 private static final long serialVersionUID = -1354835039035306505L;
63
64 static final Debug debug = Debug.getInstance("sunpkcs11");
65
66 private static int dummyConfigId;
67
68 // the PKCS11 object through which we make the native calls
69 final PKCS11 p11;
70
71 // name of the configuration file
72 private final String configName;
73
74 // configuration information
75 final Config config;
76
77 // id of the PKCS#11 slot we are using
78 final long slotID;
79
80 private CallbackHandler pHandler;
81 private final Object LOCK_HANDLER = new Object();
82
83 final boolean removable;
84
85 final Module nssModule;
86
87 final boolean nssUseSecmodTrust;
88
89 private volatile Token token;
90
91 private TokenPoller poller;
92
93 Token getToken() {
94 return token;
95 }
96
97 public SunPKCS11() {
98 super("SunPKCS11-Dummy", 1.9d, "SunPKCS11-Dummy");
99 throw new ProviderException
100 ("SunPKCS11 requires configuration file argument");
101 }
102
103 public SunPKCS11(String configName) {
104 this(checkNull(configName), null);
105 }
106
107 public SunPKCS11(InputStream configStream) {
108 this(getDummyConfigName(), checkNull(configStream));
109 }
110
111 private static <T> T checkNull(T obj) {
112 if (obj == null) {
113 throw new NullPointerException();
114 }
115 return obj;
116 }
117
118 private static synchronized String getDummyConfigName() {
119 int id = ++dummyConfigId;
120 return "---DummyConfig-" + id + "---";
121 }
122
123 /**
124 * @deprecated use new SunPKCS11(String) or new SunPKCS11(InputStream)
125 * instead
126 */
127 @Deprecated
128 public SunPKCS11(String configName, InputStream configStream) {
129 super("SunPKCS11-" +
130 Config.getConfig(configName, configStream).getName(),
131 1.9d, Config.getConfig(configName, configStream).getDescription());
132 this.configName = configName;
133 this.config = Config.removeConfig(configName);
134
135 if (debug != null) {
136 System.out.println("SunPKCS11 loading " + configName);
137 }
138
139 String library = config.getLibrary();
140 String functionList = config.getFunctionList();
141 long slotID = config.getSlotID();
142 int slotListIndex = config.getSlotListIndex();
143
144 boolean useSecmod = config.getNssUseSecmod();
145 boolean nssUseSecmodTrust = config.getNssUseSecmodTrust();
146 Module nssModule = null;
147
148 //
149 // Initialization via Secmod. The way this works is as follows:
150 // SunPKCS11 is either in normal mode or in NSS Secmod mode.
151 // Secmod is activated by specifying one or more of the following
152 // options in the config file:
153 // nssUseSecmod, nssSecmodDirectory, nssLibrary, nssModule
154 //
155 // XXX add more explanation here
156 //
157 // If we are in Secmod mode and configured to use either the
158 // nssKeyStore or the nssTrustAnchors module, we automatically
794 if (enabled == false) {
795 break;
796 }
797 try {
798 provider.initToken(null);
799 } catch (PKCS11Exception e) {
800 // ignore
801 }
802 }
803 }
804 void disable() {
805 enabled = false;
806 }
807 }
808
809 // create the poller thread, if not already active
810 private void createPoller() {
811 if (poller != null) {
812 return;
813 }
814 TokenPoller poller = new TokenPoller(this);
815 Thread t = new ManagedLocalsThread(poller, "Poller " + getName());
816 t.setDaemon(true);
817 t.setPriority(Thread.MIN_PRIORITY);
818 t.start();
819 this.poller = poller;
820 }
821
822 // destroy the poller thread, if active
823 private void destroyPoller() {
824 if (poller != null) {
825 poller.disable();
826 poller = null;
827 }
828 }
829
830 private boolean hasValidToken() {
831 /* Commented out to work with Solaris softtoken impl which
832 returns 0-value flags, e.g. both REMOVABLE_DEVICE and
833 TOKEN_PRESENT are false, when it can't access the token.
834 if (removable == false) {
835 return true;
836 }
837 */
838 Token token = this.token;
1439 return null;
1440 }
1441
1442 private Object writeReplace() throws ObjectStreamException {
1443 return new SunPKCS11Rep(this);
1444 }
1445
1446 /**
1447 * Serialized representation of the SunPKCS11 provider.
1448 */
1449 private static class SunPKCS11Rep implements Serializable {
1450
1451 static final long serialVersionUID = -2896606995897745419L;
1452
1453 private final String providerName;
1454
1455 private final String configName;
1456
1457 SunPKCS11Rep(SunPKCS11 provider) throws NotSerializableException {
1458 providerName = provider.getName();
1459 configName = provider.configName;
1460 if (Security.getProvider(providerName) != provider) {
1461 throw new NotSerializableException("Only SunPKCS11 providers "
1462 + "installed in java.security.Security can be serialized");
1463 }
1464 }
1465
1466 private Object readResolve() throws ObjectStreamException {
1467 SunPKCS11 p = (SunPKCS11)Security.getProvider(providerName);
1468 if ((p == null) || (p.configName.equals(configName) == false)) {
1469 throw new NotSerializableException("Could not find "
1470 + providerName + " in installed providers");
1471 }
1472 return p;
1473 }
1474 }
1475 }
|
46 import sun.security.util.Debug;
47 import sun.security.util.ResourcesMgr;
48
49 import sun.security.pkcs11.Secmod.*;
50
51 import sun.security.pkcs11.wrapper.*;
52 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
53
54 /**
55 * PKCS#11 provider main class.
56 *
57 * @author Andreas Sterbenz
58 * @since 1.5
59 */
60 public final class SunPKCS11 extends AuthProvider {
61
62 private static final long serialVersionUID = -1354835039035306505L;
63
64 static final Debug debug = Debug.getInstance("sunpkcs11");
65
66 // the PKCS11 object through which we make the native calls
67 final PKCS11 p11;
68
69 // configuration information
70 final Config config;
71
72 // id of the PKCS#11 slot we are using
73 final long slotID;
74
75 private CallbackHandler pHandler;
76 private final Object LOCK_HANDLER = new Object();
77
78 final boolean removable;
79
80 final Module nssModule;
81
82 final boolean nssUseSecmodTrust;
83
84 private volatile Token token;
85
86 private TokenPoller poller;
87
88 Token getToken() {
89 return token;
90 }
91
92 public SunPKCS11() {
93 this(defConfig);
94 }
95
96 @Override
97 public Provider configure(String configArg) throws InvalidParameterException {
98 if (configArg == null) {
99 throw new InvalidParameterException("SunPKCS11 requires a configuration file");
100 }
101 try {
102 return AccessController.doPrivileged(new PrivilegedExceptionAction<Provider>() {
103 @Override
104 public Provider run() throws Exception {
105 String newConfigName = configArg;
106 return new SunPKCS11(new Config(checkNull(newConfigName)));
107 }
108 });
109 } catch (PrivilegedActionException pae) {
110 InvalidParameterException ipe =
111 new InvalidParameterException("Error configuring SunPKCS11 provider");
112 throw (InvalidParameterException) ipe.initCause(pae.getException());
113 }
114 }
115
116 @Override
117 public String getArgument() {
118 String fn = config.getFileName();
119 try {
120 if (new File(fn).canRead()) {
121 return fn;
122 }
123 } catch (SecurityException se) {
124 if (debug != null) {
125 System.out.println("No permission to read config: " + fn);
126 se.printStackTrace();
127 }
128 }
129 return "";
130
131 }
132
133 private static <T> T checkNull(T obj) {
134 if (obj == null) {
135 throw new NullPointerException();
136 }
137 return obj;
138 }
139
140 private static final Config defConfig;
141 static {
142 Config c = null;
143 if (System.getProperty("os.name").startsWith("SunOS")) {
144 try {
145 c = new Config(AccessController.doPrivileged(new PrivilegedAction<String>() {
146 public String run() {
147 String sep = System.getProperty("file.separator");
148 String javaHome = System.getProperty("java.home");
149 return javaHome + sep + "conf" + sep + "security" + sep +
150 "sunpkcs11-solaris.cfg";
151 }
152 }));
153 } catch (IOException ioe) {
154 if (debug != null) {
155 System.out.println("Error parsing default config: " + ioe);
156 ioe.printStackTrace();
157 }
158 }
159 }
160 defConfig = (c == null? Config.getDummyConfig() : c);
161 }
162
163 SunPKCS11(Config c) {
164 super("SunPKCS11-" + c.getName(), 1.9d, c.getDescription());
165 this.config = c;
166
167 // stop here with minimum initialization when Config.DUMMY is used
168 if (c == Config.getDummyConfig()) {
169 p11 = null;
170 slotID = -1;
171 removable = false;
172 nssModule = null;
173 nssUseSecmodTrust = false;
174 if (debug != null) {
175 System.out.println("SunPKCS11 loading Config.DUMMY");
176 }
177 return;
178 }
179
180 if (debug != null) {
181 System.out.println("SunPKCS11 loading " + config.getFileName());
182 }
183
184 String library = config.getLibrary();
185 String functionList = config.getFunctionList();
186 long slotID = config.getSlotID();
187 int slotListIndex = config.getSlotListIndex();
188
189 boolean useSecmod = config.getNssUseSecmod();
190 boolean nssUseSecmodTrust = config.getNssUseSecmodTrust();
191 Module nssModule = null;
192
193 //
194 // Initialization via Secmod. The way this works is as follows:
195 // SunPKCS11 is either in normal mode or in NSS Secmod mode.
196 // Secmod is activated by specifying one or more of the following
197 // options in the config file:
198 // nssUseSecmod, nssSecmodDirectory, nssLibrary, nssModule
199 //
200 // XXX add more explanation here
201 //
202 // If we are in Secmod mode and configured to use either the
203 // nssKeyStore or the nssTrustAnchors module, we automatically
839 if (enabled == false) {
840 break;
841 }
842 try {
843 provider.initToken(null);
844 } catch (PKCS11Exception e) {
845 // ignore
846 }
847 }
848 }
849 void disable() {
850 enabled = false;
851 }
852 }
853
854 // create the poller thread, if not already active
855 private void createPoller() {
856 if (poller != null) {
857 return;
858 }
859 final TokenPoller poller = new TokenPoller(this);
860 AccessController.doPrivileged(new PrivilegedAction<Void>() {
861 @Override
862 public Void run() {
863 Thread t = new ManagedLocalsThread(poller, "Poller " + getName());
864 t.setDaemon(true);
865 t.setPriority(Thread.MIN_PRIORITY);
866 t.start();
867 return null;
868 }
869 });
870 this.poller = poller;
871 }
872
873 // destroy the poller thread, if active
874 private void destroyPoller() {
875 if (poller != null) {
876 poller.disable();
877 poller = null;
878 }
879 }
880
881 private boolean hasValidToken() {
882 /* Commented out to work with Solaris softtoken impl which
883 returns 0-value flags, e.g. both REMOVABLE_DEVICE and
884 TOKEN_PRESENT are false, when it can't access the token.
885 if (removable == false) {
886 return true;
887 }
888 */
889 Token token = this.token;
1490 return null;
1491 }
1492
1493 private Object writeReplace() throws ObjectStreamException {
1494 return new SunPKCS11Rep(this);
1495 }
1496
1497 /**
1498 * Serialized representation of the SunPKCS11 provider.
1499 */
1500 private static class SunPKCS11Rep implements Serializable {
1501
1502 static final long serialVersionUID = -2896606995897745419L;
1503
1504 private final String providerName;
1505
1506 private final String configName;
1507
1508 SunPKCS11Rep(SunPKCS11 provider) throws NotSerializableException {
1509 providerName = provider.getName();
1510 configName = provider.config.getFileName();
1511 if (Security.getProvider(providerName) != provider) {
1512 throw new NotSerializableException("Only SunPKCS11 providers "
1513 + "installed in java.security.Security can be serialized");
1514 }
1515 }
1516
1517 private Object readResolve() throws ObjectStreamException {
1518 SunPKCS11 p = (SunPKCS11)Security.getProvider(providerName);
1519 if ((p == null) || (p.config.getFileName().equals(configName) == false)) {
1520 throw new NotSerializableException("Could not find "
1521 + providerName + " in installed providers");
1522 }
1523 return p;
1524 }
1525 }
1526 }
|