src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SunPKCS11.java

Print this page
7191662: JCE providers should be located via ServiceLoader


  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 }