/* * Copyright (c) 2012, Redbilled.fr. 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 org.poreid.security.pcscforjava; import org.poreid.pcscforjava.PCSCResource; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import javax.swing.JOptionPane; /** * Platform specific code and constants * * @since 1.6 * @author Matthieu Leromain */ class PlatformPCSC { static final Throwable initException; PlatformPCSC() { // empty } static { initException = loadLibrary(); } /** * Allows to define the name of the operating system on which the program is * running. * @return String operating system name. */ private static String getPlatformName() { return(System.getProperty("os.name")); } /** * Allows to define if the program is running on a Linux operating system. * @return boolean true if plateform Linux. */ private static boolean isPlatformLinux() { return(getPlatformName().contains("Linux")); } /** * Allows to define if the program is running on a Mac operating system. * @return boolean true if plateform Mac. */ private static boolean isPlatformMac() { return(getPlatformName().contains("Mac")); } /** * Allows to define if the program is running on a Windows operating system. * @return boolean true if plateform Windows. */ private static boolean isPlatformWindows() { return(getPlatformName().contains("Windows")); } /** * Allows to define if the program is running on a 64 bits operating system. * @return true if there is an 64 bits operating system or false otherwise. */ private static boolean isPlatform64Bits() { // X86_64 ; amd64 ... return(System.getProperty("os.arch").indexOf("64") != -1); } /** * Allows to load a JNI * @param sName the name of the JNI. * @return true if the library is correctly loaded false otherwise. */ private static boolean loadPCSCLibrary (String sName) { boolean _bSuccess; String _sPrefix = ""; String _sExtension = ""; String _sFinalName = ""; try { if(isPlatformMac()) { _sPrefix = "lib"; _sExtension = ".dylib"; } else if(isPlatformLinux()) { _sPrefix = "lib"; _sExtension = ".so"; } else if(isPlatformWindows()) _sExtension = ".dll"; else throw new Exception(); if(!isPlatformMac()) { sName += (isPlatform64Bits()) ? "64" : "32"; sName += "bits"; } else { sName += "Univ"; } _sFinalName = _sPrefix + sName + _sExtension; deleteAllTemporariesFiles(_sFinalName, _sExtension); // Retrieve the temporary DLL File _theDll = createTemporaryFile(_sFinalName, _sExtension); // Load the DLL from the filesystem System.load(_theDll.getAbsolutePath()); _theDll.deleteOnExit(); } catch (Exception _e) { // The library is not available JOptionPane.showMessageDialog(null, "The library: " + _sFinalName + " was not found!\n\n" + "There is some possible reasons for " + "this:\n" + "\tThe platform may be not supported by the PCSC4Java - " + "framework.\n" + "\tThe library has been deleted in the PCSC4Java -" + "framework file.\n\n" + "The consequence is that the PCSC service will not be " + "work from your application on this platform.\n\n" + "If you have any doubt please contact the application " + "developer.", "Error: PCSC4Java - framework -> Library not found!", JOptionPane.ERROR_MESSAGE); PCSCResource.setLibraryName(_sFinalName + "###"); return false; } PCSCResource.setLibraryName(_sFinalName); //System.out.println("lib " + _sFinalName + " loaded"); return true; } /** * Deletes all the temporaries files of PCSC4Java which would be always * present. * @param sName the name of the temporaries files. * @param sExtension the extension of the temporaries files. */ private static void deleteAllTemporariesFiles(String sName, String sExtension) { String _sPrefix = sName.replaceAll(sExtension, ""); File _tmp; File _folderTmp = new File(System.getProperty("java.io.tmpdir")); String[] _files = _folderTmp.list(); int _i = 0; while(_i < _files.length) { if(_files[_i].contains(_sPrefix)) { _tmp = new File(System.getProperty("java.io.tmpdir") + File.separator + _files[_i]); _tmp.delete(); } _i++; } } /** * Function which allows to copy a jar file to the filesystem. * @param sName the name of the jar file. * @param sExtension the extension of the jar file. * @return the temporary File. * @throws java.io.IOException If an IO exception occurs. */ private static File createTemporaryFile(String sName, String sExtension) { InputStream _is = null; try { URL _url = PlatformPCSC.class.getResource(sName); _is = _url.openStream(); /* Define the destination file */ File _theDll = File.createTempFile(sName.replace(sExtension, ""), sExtension); _theDll.deleteOnExit(); /* Open the destination file */ FileOutputStream _fos = new FileOutputStream(_theDll); /* Copy the DLL from the JAR to the filesystem */ byte[] _array = new byte[1024*4]; for (int _i = _is.read(_array); _i != -1; _i = _is.read(_array)) { _fos.write(_array, 0, _i); } /* Close all streams */ _fos.close(); _is.close(); return _theDll; } catch (IOException ex) { return null; } } /** * Loads the library. * @return null if success otherwise an exception. */ private static Throwable loadLibrary() { try { //AccessController.doPrivileged(new LoadLibraryAction("PCSC")); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { boolean _bLoad = loadPCSCLibrary("PCSC4Java"); return null; } }); return null; } catch (Throwable e) { // The library is not available JOptionPane.showMessageDialog(null, "The library: " + " was not found!\n\n" + e.getMessage(), "Error: PCSC4Java - framework -> Library not found!", JOptionPane.ERROR_MESSAGE); return e; } } /** * Converts an unsigned byte to integer. * @param b the byte. * @return the unsigned int. */ public static int unsignedByteToInt(byte b) { return (int) b & 0xFF; } /** * Undefined protocol. */ final static int SCARD_PROTOCOL_UNDEFINED = 0x0000; /** * T = 0 protocol. */ final static int SCARD_PROTOCOL_T0 = 0x0001; /** * T = 1 protocol. */ final static int SCARD_PROTOCOL_T1 = 0x0002; /** * T = 0 or T = 1 protocol. */ final static int SCARD_PROTOCOL_Tx = (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1); // PCSC constants defined differently under Windows and MUSCLE /** * Windows */ /** * Raw protocol. */ final static int SCARD_PROTOCOL_RAW = 0x10000; /** * Unknown card. */ final static int SCARD_UNKNOWN = 0x0000; /** * Absent card. */ final static int SCARD_ABSENT = 0x0001; /** * Present card. */ final static int SCARD_PRESENT = 0x0002; /** * Swallowed card. */ final static int SCARD_SWALLOWED = 0x0003; /** * Powered card. */ final static int SCARD_POWERED = 0x0004; /** * Negotiable card. */ final static int SCARD_NEGOTIABLE = 0x0005; /** * Specific card. */ final static int SCARD_SPECIFIC = 0x0006; /** * MUSCLE */ /** * Raw protocol. */ final static int SCARD_PROTOCOL_RAW_MUSCLE = 0x0004; /** * Unknown card. */ final static int SCARD_UNKNOWN_MUSCLE = 0x0001; /** * Absent card. */ final static int SCARD_ABSENT_MUSCLE = 0x0002; /** * Present card. */ final static int SCARD_PRESENT_MUSCLE = 0x0004; /** * Swallowed card. */ final static int SCARD_SWALLOWED_MUSCLE = 0x0008; /** * Powered card. */ final static int SCARD_POWERED_MUSCLE = 0x0010; /** * Negotiable card. */ final static int SCARD_NEGOTIABLE_MUSCLE = 0x0020; /** * Specific card. */ final static int SCARD_SPECIFIC_MUSCLE = 0x0040; }