├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── dependencies.gradle ├── dist ├── intarsys-security-smartcard-io-1.24.1-javadoc.jar ├── intarsys-security-smartcard-io-1.24.1-sources.jar └── intarsys-security-smartcard-io-1.24.1.jar ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── intarsys-security-smartcard-io ├── build.gradle └── src │ ├── examples │ └── java │ │ └── de │ │ └── intarsys │ │ └── security │ │ └── smartcard │ │ └── pcsc │ │ ├── Connect.java │ │ ├── ListReaders.java │ │ └── MonitorReaders.java │ └── main │ └── java │ └── de │ └── intarsys │ └── security │ └── smartcard │ ├── card │ ├── ATR.java │ ├── ActiveCardConnectionMonitor.java │ ├── CardConnectionDetector.java │ ├── CardConnectionMonitor.java │ ├── CardEvent.java │ ├── CardException.java │ ├── CardFilterTools.java │ ├── CardReset.java │ ├── CardSharingViolation.java │ ├── CardSystem.java │ ├── CardSystemMonitor.java │ ├── CardTerminalFilterTools.java │ ├── CardTools.java │ ├── CardUnavailable.java │ ├── CommonCard.java │ ├── CommonCardConnection.java │ ├── CommonCardConnectionMonitor.java │ ├── CommonCardSystem.java │ ├── CommonCardTerminal.java │ ├── CommonCardTransmitter.java │ ├── EnumCardState.java │ ├── EnumCardTerminalState.java │ ├── ICard.java │ ├── ICardConnection.java │ ├── ICardConnectionFilter.java │ ├── ICardFilter.java │ ├── ICardSystem.java │ ├── ICardTerminal.java │ ├── ICardTerminalFilter.java │ ├── ICardTransmitter.java │ ├── NoCardTerminal.java │ ├── PACKAGE.java │ ├── RegexCardTerminalFilter.java │ ├── RequestAPDU.java │ ├── ResponseAPDU.java │ ├── T0CardTransmitter.java │ ├── T1CardTransmitter.java │ ├── messages.properties │ ├── messages_de.properties │ └── standard │ │ ├── PACKAGE.java │ │ ├── StandardCard.java │ │ ├── StandardCardConnection.java │ │ ├── StandardCardSystem.java │ │ └── StandardCardTerminal.java │ └── pcsc │ ├── CardStatus.java │ ├── CommonPCSCContext.java │ ├── CommonPCSCLib.java │ ├── EmptyContext.java │ ├── INativePCSCLib.java │ ├── IPCSCCardReader.java │ ├── IPCSCConnection.java │ ├── IPCSCContext.java │ ├── IPCSCContextFactory.java │ ├── NativePCSCContextFactory.java │ ├── NativePCSCLib.java │ ├── PACKAGE.java │ ├── PCSCAttribute.java │ ├── PCSCCardReader.java │ ├── PCSCCardReaderState.java │ ├── PCSCCardReset.java │ ├── PCSCCardUnavailable.java │ ├── PCSCConnection.java │ ├── PCSCContext.java │ ├── PCSCContextFactory.java │ ├── PCSCException.java │ ├── PCSCMultiContext.java │ ├── PCSCSharingViolation.java │ ├── PCSCStatusMonitor.java │ ├── PCSCTools.java │ ├── messages.properties │ ├── messages_de.properties │ ├── nativec │ ├── NativePcscDword.java │ ├── NativePcscDwordType.java │ ├── PIN_MODIFY_STRUCTURE.java │ ├── PIN_VERIFY_STRUCTURE.java │ ├── SCARDCONTEXT.java │ ├── SCARDHANDLE.java │ ├── SCARD_READERSTATE.java │ ├── _IPCSC.java │ ├── _PCSC.java │ ├── _PCSCThreadedExecutor.java │ ├── _PCSC_RETURN_CODES.java │ └── package-info.java │ └── package-info.java └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | **/build/ 3 | !src/**/build/ 4 | 5 | # Ignore Gradle GUI config 6 | gradle-app.setting 7 | 8 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 9 | !gradle-wrapper.jar 10 | 11 | # Avoid ignore Gradle wrappper properties 12 | !gradle-wrapper.properties 13 | 14 | # Cache of project 15 | .gradletasknamecache 16 | 17 | # Eclipse Gradle plugin generated files 18 | # Eclipse Core 19 | .project 20 | # JDT-specific (Eclipse Java Development Tools) 21 | .classpath 22 | /bin/ 23 | # Other Eclipse-specific 24 | **/.settings/ 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2013, intarsys GmbH 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # intarsys smartcard-io 2 | 3 | ## Overview 4 | 5 | This project contains a PC/SC wrapper and smartcard abstraction layer. 6 | 7 | ## Build 8 | 9 | The project is provided as a self-contained Gradle project and should compile without problems. 10 | 11 | ## Usage 12 | 13 | A pre-built jar file is available in the "dist" folder. 14 | 15 | ### PC/SC native usage 16 | 17 | On the most basic layer, we simply use a declarative approach to wrap PC/SC API functions. To work on this "abstraction" you can simply use *de.intarsys.security.smartcard.pcsc.nativec._PCSC*. 18 | 19 | If you create this without parameter, the default library for the platform will be used. 20 | 21 | ### PC/SC abstraction usage 22 | 23 | There's a small abstract layer around *de.intarsys.security.smartcard.pcsc.nativec._PCSC* that allows for a little bit more readable code and also includes some indirections to ease life with 3rd-party libraries and workarounds for them. 24 | 25 | In the "examples" directory you will find some demo code. 26 | 27 | The most simple use case is 28 | 29 | ``` 30 | IPCSCContext context = PCSCContextFactory.get().establishContext(); 31 | List readers = context.listReaders(); 32 | if (readers.isEmpty()) { 33 | System.out.println("no reader found"); 34 | return; 35 | } 36 | for (IPCSCCardReader reader : readers) { 37 | PCSCStatusMonitor monitor = new PCSCStatusMonitor(reader); 38 | monitor.addStatusListener(new IStatusListener() { 39 | @Override 40 | public void onException(IPCSCCardReader reader, PCSCException e) { 41 | e.printStackTrace(); 42 | } 43 | 44 | @Override 45 | public void onStatusChange(IPCSCCardReader reader, 46 | PCSCCardReaderState cardReaderState) { 47 | System.out.println("reader " + reader + " state " 48 | + cardReaderState); 49 | } 50 | }); 51 | } 52 | ``` 53 | 54 | To connect to a reader 55 | 56 | ``` 57 | // recommended use: create a new context for the connection 58 | System.out.println("" + reader + " establish context"); 59 | IPCSCContext connectionContext = reader.getContext().establishContext(); 60 | System.out.println("" + reader + " connect"); 61 | IPCSCConnection connection = connectionContext.connect("example", reader.getName(), _IPCSC.SCARD_SHARE_SHARED, 62 | _IPCSC.SCARD_PROTOCOL_Tx); 63 | System.out.println("" + reader + " begin transaction"); 64 | connection.beginTransaction(); 65 | System.out.println("" + reader + " end transaction"); 66 | connection.endTransaction(_IPCSC.SCARD_LEAVE_CARD); 67 | System.out.println("" + reader + " disconnect"); 68 | connection.disconnect(_IPCSC.SCARD_LEAVE_CARD); 69 | System.out.println("" + reader + " dispose context"); 70 | connectionContext.dispose(); 71 | ``` 72 | 73 | ## License 74 | 75 | ``` 76 | BSD 3-Clause License 77 | 78 | Copyright (c) 2013, intarsys GmbH 79 | 80 | Redistribution and use in source and binary forms, with or without 81 | modification, are permitted provided that the following conditions are met: 82 | 83 | 1. Redistributions of source code must retain the above copyright notice, this 84 | list of conditions and the following disclaimer. 85 | 86 | 2. Redistributions in binary form must reproduce the above copyright notice, 87 | this list of conditions and the following disclaimer in the documentation 88 | and/or other materials provided with the distribution. 89 | 90 | 3. Neither the name of the copyright holder nor the names of its 91 | contributors may be used to endorse or promote products derived from 92 | this software without specific prior written permission. 93 | 94 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 95 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 96 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 97 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 98 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 99 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 100 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 101 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 102 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 103 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 104 | ``` 105 | 106 | ## Service & Support 107 | 108 | Service & support should be funneled through the tools available with GitHub. 109 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | subprojects { 2 | 3 | pluginManager.withPlugin('java') { 4 | sourceSets.main.resources.srcDirs += 'src/main/java' 5 | sourceSets.test.resources.srcDirs += 'src/test/java' 6 | 7 | java { 8 | toolchain { 9 | languageVersion.set(JavaLanguageVersion.of(17)) 10 | } 11 | withSourcesJar() 12 | withJavadocJar() 13 | } 14 | sourcesJar { 15 | duplicatesStrategy = DuplicatesStrategy.EXCLUDE 16 | } 17 | javadoc { 18 | options.showFromPublic() 19 | options.addBooleanOption("Xdoclint:-missing", true) 20 | } 21 | 22 | jar { 23 | manifest { 24 | attributes([ 25 | 'Implementation-Title': project.name, 26 | 'Implementation-Version': project.version, 27 | 'Implementation-Vendor': 'intarsys GmbH', 28 | 'Created-By': "Gradle ${gradle.gradleVersion}" 29 | ]) 30 | } 31 | } 32 | } 33 | 34 | project.tasks.withType(GenerateModuleMetadata) { 35 | enabled = false 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dependencies.gradle: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | versionCatalogs { 3 | libs { 4 | // is-lib-runtime 5 | library('intarsysToolsRuntime', 'de.intarsys.runtime:intarsys-tools-runtime:4.25.2') 6 | 7 | // is-lib-nativec 8 | version('is-nativec', '5.14.1') 9 | library('intarsysNativecGeneric', 'de.intarsys.nativec', 'intarsys-nativec-generic').versionRef('is-nativec') 10 | library('intarsysNativecJna', 'de.intarsys.nativec', 'intarsys-nativec-jna').versionRef('is-nativec') 11 | 12 | // Common Java APIs 13 | library('jakartaAnnotationApi', 'jakarta.annotation:jakarta.annotation-api:1.3.5') 14 | 15 | // Logging 16 | library('slf4jApi','org.slf4j:slf4j-api:1.7.36') 17 | library('logbackClassic', 'ch.qos.logback:logback-classic:1.2.11') 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /dist/intarsys-security-smartcard-io-1.24.1-javadoc.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intarsys/smartcard-io/cee7fb456459abee84c9c507051fd77ef9cdf1b6/dist/intarsys-security-smartcard-io-1.24.1-javadoc.jar -------------------------------------------------------------------------------- /dist/intarsys-security-smartcard-io-1.24.1-sources.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intarsys/smartcard-io/cee7fb456459abee84c9c507051fd77ef9cdf1b6/dist/intarsys-security-smartcard-io-1.24.1-sources.jar -------------------------------------------------------------------------------- /dist/intarsys-security-smartcard-io-1.24.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intarsys/smartcard-io/cee7fb456459abee84c9c507051fd77ef9cdf1b6/dist/intarsys-security-smartcard-io-1.24.1.jar -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | version=1.24.1 2 | group=de.intarsys.security.smartcard.io 3 | release=true 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intarsys/smartcard-io/cee7fb456459abee84c9c507051fd77ef9cdf1b6/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if %ERRORLEVEL% equ 0 goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if %ERRORLEVEL% equ 0 goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | set EXIT_CODE=%ERRORLEVEL% 84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 86 | exit /b %EXIT_CODE% 87 | 88 | :mainEnd 89 | if "%OS%"=="Windows_NT" endlocal 90 | 91 | :omega 92 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'java-library' 3 | id 'eclipse-wtp' 4 | } 5 | 6 | configurations { 7 | examplesImplementation.extendsFrom implementation 8 | } 9 | 10 | sourceSets { 11 | examples { 12 | compileClasspath += sourceSets.main.output 13 | runtimeClasspath += sourceSets.main.output 14 | } 15 | } 16 | 17 | dependencies { 18 | 19 | implementation libs.jakartaAnnotationApi 20 | 21 | implementation libs.intarsysNativecGeneric 22 | api libs.intarsysToolsRuntime 23 | 24 | examplesRuntimeOnly libs.logbackClassic 25 | examplesRuntimeOnly libs.intarsysNativecJna 26 | } 27 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/examples/java/de/intarsys/security/smartcard/pcsc/Connect.java: -------------------------------------------------------------------------------- 1 | package de.intarsys.security.smartcard.pcsc; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import de.intarsys.security.smartcard.pcsc.PCSCStatusMonitor.IStatusListener; 7 | import de.intarsys.security.smartcard.pcsc.nativec._IPCSC; 8 | 9 | public class Connect { 10 | 11 | public static void main(String[] args) { 12 | try { 13 | new Connect().run(); 14 | } catch (Exception e) { 15 | e.printStackTrace(); 16 | } 17 | } 18 | 19 | protected void connect(IPCSCCardReader reader) throws PCSCException { 20 | // recommended use: create a new context for the connection 21 | System.out.println("" + reader + " establish context"); 22 | IPCSCContext connectionContext = reader.getContext().establishContext(); 23 | System.out.println("" + reader + " connect"); 24 | IPCSCConnection connection = connectionContext.connect("example", reader.getName(), _IPCSC.SCARD_SHARE_SHARED, 25 | _IPCSC.SCARD_PROTOCOL_Tx); 26 | System.out.println("" + reader + " begin transaction"); 27 | connection.beginTransaction(); 28 | System.out.println("" + reader + " end transaction"); 29 | connection.endTransaction(_IPCSC.SCARD_LEAVE_CARD); 30 | System.out.println("" + reader + " disconnect"); 31 | connection.disconnect(_IPCSC.SCARD_LEAVE_CARD); 32 | System.out.println("" + reader + " dispose context"); 33 | connectionContext.dispose(); 34 | } 35 | 36 | public void run() throws Exception { 37 | IPCSCContext context = PCSCContextFactory.get().establishContext(); 38 | List readers = context.listReaders(); 39 | if (readers.isEmpty()) { 40 | System.out.println("no reader found"); 41 | return; 42 | } 43 | List activeMonitors = new ArrayList(); 44 | for (IPCSCCardReader reader : readers) { 45 | final PCSCStatusMonitor monitor = new PCSCStatusMonitor(reader); 46 | activeMonitors.add(monitor); 47 | monitor.addStatusListener(new IStatusListener() { 48 | @Override 49 | public void onException(IPCSCCardReader reader, PCSCException e) { 50 | e.printStackTrace(); 51 | } 52 | 53 | @Override 54 | public void onStatusChange(IPCSCCardReader reader, PCSCCardReaderState cardReaderState) { 55 | System.out.println("reader " + cardReaderState.getReader() + " state " + cardReaderState); 56 | if (cardReaderState.isPresent()) { 57 | try { 58 | monitor.stop(); 59 | activeMonitors.remove(monitor); 60 | connect(reader); 61 | } catch (PCSCException e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | } 66 | }); 67 | } 68 | while (!activeMonitors.isEmpty() && System.in.available() == 0) { 69 | Thread.sleep(100); 70 | } 71 | context.dispose(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/examples/java/de/intarsys/security/smartcard/pcsc/ListReaders.java: -------------------------------------------------------------------------------- 1 | package de.intarsys.security.smartcard.pcsc; 2 | 3 | import java.util.List; 4 | 5 | public class ListReaders { 6 | 7 | public static void main(String[] args) { 8 | try { 9 | new ListReaders().run(); 10 | } catch (Exception e) { 11 | e.printStackTrace(); 12 | } 13 | } 14 | 15 | public void run() throws Exception { 16 | IPCSCContext context = PCSCContextFactory.get().establishContext(); 17 | List readers = context.listReaders(); 18 | for (IPCSCCardReader reader : readers) { 19 | System.out 20 | .println("found " + reader + " named " + reader.getName()); 21 | } 22 | context.dispose(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/examples/java/de/intarsys/security/smartcard/pcsc/MonitorReaders.java: -------------------------------------------------------------------------------- 1 | package de.intarsys.security.smartcard.pcsc; 2 | 3 | import java.util.List; 4 | 5 | import de.intarsys.security.smartcard.pcsc.PCSCStatusMonitor.IStatusListener; 6 | 7 | public class MonitorReaders { 8 | 9 | public static void main(String[] args) { 10 | try { 11 | new MonitorReaders().run(); 12 | } catch (Exception e) { 13 | e.printStackTrace(); 14 | } 15 | } 16 | 17 | public void run() throws Exception { 18 | IPCSCContext context = PCSCContextFactory.get().establishContext(); 19 | List readers = context.listReaders(); 20 | if (readers.isEmpty()) { 21 | System.out.println("no reader found"); 22 | return; 23 | } 24 | for (IPCSCCardReader reader : readers) { 25 | PCSCStatusMonitor monitor = new PCSCStatusMonitor(reader); 26 | monitor.addStatusListener(new IStatusListener() { 27 | @Override 28 | public void onException(IPCSCCardReader reader, PCSCException e) { 29 | e.printStackTrace(); 30 | } 31 | 32 | @Override 33 | public void onStatusChange(IPCSCCardReader reader, 34 | PCSCCardReaderState cardReaderState) { 35 | System.out.println("reader " + reader + " state " 36 | + cardReaderState); 37 | } 38 | }); 39 | } 40 | while (System.in.available() == 0) { 41 | Thread.sleep(100); 42 | } 43 | context.dispose(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardConnectionDetector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import java.util.ArrayList; 33 | import java.util.Arrays; 34 | import java.util.List; 35 | 36 | import de.intarsys.tools.collection.ListTools; 37 | import de.intarsys.tools.exception.ExceptionTools; 38 | import de.intarsys.tools.string.StringTools; 39 | import de.intarsys.tools.yalf.api.ILogger; 40 | import de.intarsys.tools.yalf.api.Level; 41 | 42 | /** 43 | * Connect to all available terminals and return the {@link ICardConnection} 44 | * that match the given filter. 45 | * 46 | * @param 47 | */ 48 | public class CardConnectionDetector { 49 | 50 | public static class Result { 51 | 52 | private final ICardConnection cardChannel; 53 | 54 | public Result(ICardConnection connection) { 55 | this.cardChannel = connection; 56 | } 57 | 58 | public ICardConnection getCardConnection() { 59 | return cardChannel; 60 | } 61 | 62 | } 63 | 64 | private static final ILogger Log = PACKAGE.Log; 65 | 66 | private List cardTerminals; 67 | 68 | private ICardConnectionFilter cardChannelFilter; 69 | 70 | private int connectionTimeout = 5000; 71 | 72 | private boolean closeConnection = true; 73 | 74 | public CardConnectionDetector() { 75 | } 76 | 77 | public void addCardTerminal(ICardTerminal terminal) { 78 | if (cardTerminals == null) { 79 | cardTerminals = new ArrayList(3); 80 | } 81 | cardTerminals.add(terminal); 82 | } 83 | 84 | public void addCardTerminal(String name) { 85 | ICardTerminal terminal = CardSystem.get().getCardTerminal(name); 86 | if (terminal != null) { 87 | addCardTerminal(terminal); 88 | } 89 | } 90 | 91 | public List findAll() { 92 | return findForTerminals(false); 93 | } 94 | 95 | public R findFirst() { 96 | List result = findForTerminals(true); 97 | if (result == null || result.size() == 0) { 98 | return null; 99 | } else { 100 | return result.get(0); 101 | } 102 | } 103 | 104 | protected List findForConnection(ICardConnection connection) { 105 | return ListTools.with((R) new Result(connection)); 106 | } 107 | 108 | protected List findForTerminal(ICardTerminal terminal) { 109 | ICardConnection connection = null; 110 | ICard card = terminal.getCard(); 111 | try { 112 | List result = null; 113 | connection = CardTools.connectTransacted(card, getConnectionTimeout()); 114 | if (getCardChannelFilter() == null) { 115 | result = findForConnection(connection); 116 | } else { 117 | if (getCardChannelFilter().accept(connection)) { 118 | result = findForConnection(connection); 119 | } 120 | } 121 | if (result == null || result.isEmpty() || isCloseConnection()) { 122 | connection.close(ICardConnection.MODE_LEAVE_CARD); 123 | } 124 | return result; 125 | } catch (Exception ex) { 126 | if (connection != null) { 127 | try { 128 | connection.close(ICardConnection.MODE_RESET); 129 | } catch (CardException e) { 130 | Log.log(Level.DEBUG, "close failed"); 131 | } 132 | } 133 | boolean retry = CardTools.isRetry(card, ex, 0); 134 | if (retry) { 135 | return findForTerminal(terminal); 136 | } else { 137 | Log.trace("{}: {}", this, ExceptionTools.getMessage(ex), ex); 138 | } 139 | return null; 140 | } 141 | } 142 | 143 | protected List findForTerminals(boolean returnFirst) { 144 | List searchTerminals = cardTerminals; 145 | if (searchTerminals == null || searchTerminals.isEmpty()) { 146 | ICardSystem cardSystem = CardSystem.get(); 147 | ICardTerminal[] terminals = cardSystem.getCardTerminals(); 148 | searchTerminals = Arrays.asList(terminals); 149 | } 150 | return findForTerminals(searchTerminals, returnFirst); 151 | } 152 | 153 | protected List findForTerminals(List terminals, boolean returnFirst) { 154 | List allResults = new ArrayList(terminals.size()); 155 | for (ICardTerminal terminal : terminals) { 156 | if (terminal.getCard() == null) { 157 | continue; 158 | } 159 | List result = findForTerminal(terminal); 160 | if (result != null) { 161 | allResults.addAll(result); 162 | if (returnFirst) { 163 | break; 164 | } 165 | } 166 | } 167 | return allResults; 168 | } 169 | 170 | public ICardConnectionFilter getCardChannelFilter() { 171 | return cardChannelFilter; 172 | } 173 | 174 | public int getConnectionTimeout() { 175 | return connectionTimeout; 176 | } 177 | 178 | public boolean isCloseConnection() { 179 | return closeConnection; 180 | } 181 | 182 | public void removeCardTerminal(ICardTerminal removeTerminal) { 183 | if (removeTerminal == null || cardTerminals == null) { 184 | return; 185 | } 186 | cardTerminals.remove(removeTerminal); 187 | } 188 | 189 | public void removeCardTerminalName(String removeTerminalName) { 190 | if (StringTools.isEmpty(removeTerminalName) || cardTerminals == null) { 191 | return; 192 | } 193 | for (ICardTerminal terminal : cardTerminals) { 194 | if (terminal.getName().equals(removeTerminalName)) { 195 | cardTerminals.remove(terminal); 196 | break; 197 | } 198 | } 199 | } 200 | 201 | public void setCardChannelFilter(ICardConnectionFilter cardConnectionFilter) { 202 | this.cardChannelFilter = cardConnectionFilter; 203 | } 204 | 205 | public void setCloseConnection(boolean closeConnection) { 206 | this.closeConnection = closeConnection; 207 | } 208 | 209 | public void setConnectionTimeout(int connectionTimeout) { 210 | this.connectionTimeout = connectionTimeout; 211 | } 212 | 213 | } 214 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardConnectionMonitor.java: -------------------------------------------------------------------------------- 1 | package de.intarsys.security.smartcard.card; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import de.intarsys.tools.concurrent.ITaskCallback; 7 | import de.intarsys.tools.concurrent.TaskFailed; 8 | import de.intarsys.tools.exception.ExceptionTools; 9 | import de.intarsys.tools.yalf.api.ILogger; 10 | 11 | /** 12 | * A concrete monitor that delegates connection events to its listeners 13 | * 14 | */ 15 | public class CardConnectionMonitor extends CommonCardConnectionMonitor { 16 | 17 | private static final ILogger Log = PACKAGE.Log; 18 | 19 | private final List> listeners = new ArrayList<>(); 20 | 21 | private boolean closeConnection = false; 22 | 23 | public CardConnectionMonitor(ICardSystem cardSystem) { 24 | super(cardSystem); 25 | } 26 | 27 | /** 28 | * Add an {@link ITaskCallback} to get informed about the outcome of a 29 | * connection attempt. 30 | * 31 | * The listener should wrap any {@link CardException} it wants to throw 32 | * while working on the connection callback in a {@link RuntimeException}. 33 | * 34 | * The listeners are executed in sequence of registration. An exception in 35 | * any of the listeners will cause the connection to be closed. 36 | * 37 | * @param listener 38 | */ 39 | public void addCardConnectionListener(ITaskCallback listener) { 40 | synchronized (listeners) { 41 | listeners.add(listener); 42 | } 43 | } 44 | 45 | public boolean isCloseConnection() { 46 | return closeConnection; 47 | } 48 | 49 | @Override 50 | protected void onCardInserted(ICard card) { 51 | super.onCardInserted(card); 52 | EnumCardState state = card.getState(); 53 | if (state.isConnectedShared() || state.isNotConnected()) { 54 | connect(card); 55 | } 56 | } 57 | 58 | @Override 59 | protected void onConnected(ICardConnection connection) throws CardException { 60 | List> tempListeners; 61 | synchronized (listeners) { 62 | tempListeners = new ArrayList<>(listeners); 63 | } 64 | boolean close = isCloseConnection(); 65 | try { 66 | for (ITaskCallback listener : tempListeners) { 67 | listener.finished(connection); 68 | } 69 | } catch (RuntimeException e) { 70 | close = true; 71 | CardException nested = ExceptionTools.getFromChain(e, CardException.class); 72 | if (nested != null) { 73 | throw nested; 74 | } 75 | throw e; 76 | } finally { 77 | if (close) { 78 | try { 79 | connection.close(ICardConnection.MODE_LEAVE_CARD); 80 | } catch (CardException e) { 81 | Log.warn("{} close {} failed", getLogPrefix(), connection); //$NON-NLS-1$ 82 | } 83 | } 84 | } 85 | } 86 | 87 | @Override 88 | protected void onConnectionFailed(ICard card, TaskFailed exception) { 89 | List> tempListeners; 90 | synchronized (listeners) { 91 | tempListeners = new ArrayList<>(listeners); 92 | } 93 | for (ITaskCallback listener : tempListeners) { 94 | listener.failed(exception); 95 | } 96 | } 97 | 98 | public void removeCardConnectionListener(ITaskCallback listener) { 99 | synchronized (listeners) { 100 | listeners.remove(listener); 101 | } 102 | } 103 | 104 | public void setCloseConnection(boolean closeConnection) { 105 | this.closeConnection = closeConnection; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.tools.event.Event; 33 | import de.intarsys.tools.event.EventType; 34 | 35 | /** 36 | * An event triggered by the {@link ICardTerminal} to indicate an {@link ICard} 37 | * state change. 38 | * 39 | */ 40 | public class CardEvent extends Event { 41 | 42 | public static final EventType ID = new EventType("CardEvent"); //$NON-NLS-1$ 43 | 44 | private final EnumCardState oldState; 45 | 46 | private final EnumCardState newState; 47 | 48 | public CardEvent(ICard source, EnumCardState oldState, 49 | EnumCardState newState) { 50 | super(source); 51 | this.oldState = oldState; 52 | this.newState = newState; 53 | } 54 | 55 | public ICard getCard() { 56 | return (ICard) getSource(); 57 | } 58 | 59 | public ICardTerminal getCardTerminal() { 60 | return getCard().getCardTerminal(); 61 | } 62 | 63 | @Override 64 | public EventType getEventType() { 65 | return ID; 66 | } 67 | 68 | public EnumCardState getNewState() { 69 | return newState; 70 | } 71 | 72 | public EnumCardState getOldState() { 73 | return oldState; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.security.smartcard.pcsc.PCSCCardReset; 33 | import de.intarsys.security.smartcard.pcsc.PCSCCardUnavailable; 34 | import de.intarsys.security.smartcard.pcsc.PCSCSharingViolation; 35 | 36 | /** 37 | * An exception in the card abstraction layer. 38 | */ 39 | public class CardException extends Exception { 40 | 41 | private static final long serialVersionUID = 1L; 42 | 43 | public static CardException create(String message, Throwable e) { 44 | if (e instanceof CardException) { 45 | return (CardException) e; 46 | } 47 | if (e instanceof PCSCCardReset) { 48 | return new CardReset(); 49 | } 50 | if (e instanceof PCSCSharingViolation) { 51 | return new CardSharingViolation(); 52 | } 53 | if (e instanceof PCSCCardUnavailable) { 54 | return new CardUnavailable(e.getMessage(), e); 55 | } 56 | return new CardException(message, e); 57 | } 58 | 59 | public static CardException create(Throwable e) { 60 | if (e instanceof CardException) { 61 | return (CardException) e; 62 | } 63 | if (e instanceof PCSCCardReset) { 64 | return new CardReset(); 65 | } 66 | if (e instanceof PCSCSharingViolation) { 67 | return new CardSharingViolation(); 68 | } 69 | if (e instanceof PCSCCardUnavailable) { 70 | return new CardUnavailable(e.getMessage(), e); 71 | } 72 | return new CardException(e.getLocalizedMessage(), e); 73 | } 74 | 75 | public CardException() { 76 | super(); 77 | } 78 | 79 | public CardException(String message) { 80 | super(message); 81 | } 82 | 83 | public CardException(String message, Throwable cause) { 84 | super(message, cause); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardFilterTools.java: -------------------------------------------------------------------------------- 1 | package de.intarsys.security.smartcard.card; 2 | 3 | import de.intarsys.tools.reflect.ObjectCreationException; 4 | 5 | public class CardFilterTools { 6 | 7 | public static ICardFilter createCardFilter(Object value) throws ObjectCreationException { 8 | if (value == null) { 9 | return null; 10 | } 11 | throw new ObjectCreationException(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardReset.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.tools.message.IMessageBundle; 33 | 34 | /** 35 | * Indicate a card reset. 36 | * 37 | */ 38 | public class CardReset extends CardException { 39 | 40 | private static final IMessageBundle Msg = PACKAGE.Messages; 41 | 42 | public CardReset() { 43 | } 44 | 45 | @Override 46 | public String getLocalizedMessage() { 47 | return Msg.getString("CardReset.message"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardSharingViolation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | /** 33 | * Indicate a card sharing violation 34 | * 35 | */ 36 | public class CardSharingViolation extends CardException { 37 | 38 | public CardSharingViolation() { 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.tools.component.SingletonProvider; 33 | import de.intarsys.tools.servicelocator.ServiceLocator; 34 | 35 | /** 36 | * The plugged in card system implementation. 37 | *

38 | * This singleton gives access to the platform {@link ICardSystem}. 39 | * 40 | */ 41 | @SingletonProvider 42 | public class CardSystem { 43 | 44 | public static void dispose() { 45 | ICardSystem tempCardSystem = ServiceLocator.get().remove(ICardSystem.class); 46 | if (tempCardSystem != null) { 47 | tempCardSystem.dispose(); 48 | } 49 | } 50 | 51 | public static ICardSystem get() { 52 | return ServiceLocator.get().get(ICardSystem.class); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardTerminalFilterTools.java: -------------------------------------------------------------------------------- 1 | package de.intarsys.security.smartcard.card; 2 | 3 | import de.intarsys.tools.reflect.ObjectCreationException; 4 | 5 | public class CardTerminalFilterTools { 6 | 7 | public static ICardTerminalFilter createCardTerminalFilter(Object value) throws ObjectCreationException { 8 | if (value == null) { 9 | return null; 10 | } 11 | throw new ObjectCreationException(); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CardUnavailable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | /** 33 | * Indicate a card drop. 34 | * 35 | */ 36 | public class CardUnavailable extends CardException { 37 | 38 | public CardUnavailable() { 39 | super(); 40 | } 41 | 42 | public CardUnavailable(String message) { 43 | super(message); 44 | } 45 | 46 | public CardUnavailable(String message, Throwable cause) { 47 | super(message, cause); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CommonCardConnectionMonitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import java.util.Random; 33 | import java.util.concurrent.Future; 34 | import java.util.concurrent.TimeUnit; 35 | 36 | import de.intarsys.tools.attribute.Attribute; 37 | import de.intarsys.tools.concurrent.ITaskCallback; 38 | import de.intarsys.tools.concurrent.Promise; 39 | import de.intarsys.tools.concurrent.TaskFailed; 40 | import de.intarsys.tools.exception.ExceptionTools; 41 | import de.intarsys.tools.yalf.api.ILogger; 42 | 43 | /** 44 | * Abstract superclass to ease the implementation of monitors that connect to a 45 | * card upon insertion. 46 | *

47 | * Subclasses must redefine onConnected() to take further actions after initial 48 | * connection is established. The default will close the connection immediately. 49 | */ 50 | public abstract class CommonCardConnectionMonitor extends CardSystemMonitor { 51 | 52 | private static final ILogger Log = PACKAGE.Log; 53 | 54 | private final Attribute attrConnection = new Attribute("connection"); 55 | 56 | private final Attribute attrDelay = new Attribute("delay"); 57 | 58 | public CommonCardConnectionMonitor(ICardSystem cardSystem) { 59 | super(cardSystem); 60 | } 61 | 62 | /** 63 | * Spawn a task to connect to the card. The client is informed about the outcome 64 | * of the task via the callback methods "onConnected" or "onConnectionFailed". 65 | * These callbacks are performed with the data argument supplied by the original 66 | * caller. 67 | * 68 | * @param card 69 | * The {@link ICard} to connect to. 70 | * @return 71 | */ 72 | public Future connect(final ICard card) { 73 | synchronized (attrConnection) { 74 | Object connectionMarker = card.getAttribute(attrConnection); 75 | if (connectionMarker != null) { 76 | if (connectionMarker instanceof ICardConnection) { 77 | if (((ICardConnection) connectionMarker).isValid()) { 78 | return Promise.newFailed(new IllegalStateException("already connecting/connected")); 79 | } 80 | } else { 81 | return Promise.newFailed(new IllegalStateException("already connecting/connected")); 82 | } 83 | } 84 | Log.info("{} connect {}...", getLogPrefix(), card); //$NON-NLS-1$ 85 | Future connectTask = CardTools.connectTransacted(card, 86 | new ITaskCallback() { 87 | @Override 88 | public void failed(TaskFailed exception) { 89 | synchronized (attrConnection) { 90 | card.setAttribute(attrConnection, null); 91 | } 92 | boolean retry = isStarted() && CardTools.isRetry(card, exception, 2); 93 | if (retry) { 94 | Log.info("{} connect {} failed ({}), retry", getLogPrefix(), card, 95 | ExceptionTools.getMessage(exception)); 96 | connectLater(card); 97 | } else { 98 | Log.info("{} connect {} failed", getLogPrefix(), card, exception); 99 | onConnectionFailed(card, exception); 100 | } 101 | } 102 | 103 | @Override 104 | public void finished(ICardConnection connection) { 105 | synchronized (attrConnection) { 106 | card.setAttribute(attrConnection, connection); 107 | } 108 | Log.info("{} connect {} success", getLogPrefix(), connection); //$NON-NLS-1$ 109 | CardTools.resetRetry(card); 110 | if (!isStarted()) { 111 | doClose(connection); 112 | return; 113 | } 114 | /* 115 | * get out of connection thread 116 | */ 117 | getEventExecutor().submit(new Runnable() { 118 | @Override 119 | public void run() { 120 | if (isStarted()) { 121 | try { 122 | onConnected(connection); 123 | card.setAttribute(attrDelay, null); 124 | return; 125 | } catch (CardReset e) { 126 | Log.info("{} connect {} reset, retry", getLogPrefix(), connection); 127 | connectLater(card); 128 | } catch (CardUnavailable e) { 129 | Log.info("{} connect {} removed", getLogPrefix(), connection); 130 | } catch (Exception e) { 131 | Log.warn("{} connect {} exception", getLogPrefix(), connection, e); 132 | } 133 | onConnectedGiveup(connection); 134 | } 135 | doClose(connection); 136 | } 137 | }); 138 | } 139 | }); 140 | card.setAttribute(attrConnection, connectTask); 141 | return connectTask; 142 | } 143 | } 144 | 145 | public void connectLater(ICard card) { 146 | if (!isStarted()) { 147 | return; 148 | } 149 | Long delay = (Long) card.getAttribute(attrDelay); 150 | if (delay == null) { 151 | delay = 1000L + new Random().nextInt(1000); 152 | } else if (delay > 20000L) { 153 | // 154 | } else { 155 | delay = delay * 2; 156 | } 157 | card.setAttribute(attrDelay, delay); 158 | Log.info("{} schedule {} for re-connection in {} ms", this, card, delay); 159 | getEventExecutor().schedule(new Runnable() { 160 | @Override 161 | public void run() { 162 | if (!card.getState().isInvalid()) { 163 | connect(card); 164 | } 165 | } 166 | }, delay, TimeUnit.MILLISECONDS); 167 | } 168 | 169 | protected void doClose(ICardConnection connection) { 170 | try { 171 | connection.close(ICardConnection.MODE_LEAVE_CARD); 172 | } catch (CardException e) { 173 | Log.trace("{} connect {} close unexpected exception", getLogPrefix(), //$NON-NLS-1$ 174 | connection, ExceptionTools.getMessage(e)); 175 | } 176 | } 177 | 178 | protected void onConnected(ICardConnection connection) throws CardException { 179 | doClose(connection); 180 | } 181 | 182 | protected void onConnectedGiveup(ICardConnection connection) { 183 | } 184 | 185 | protected void onConnectionFailed(ICard card, TaskFailed exception) { 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CommonCardTerminal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | import java.util.concurrent.ScheduledExecutorService; 35 | 36 | import de.intarsys.tools.attribute.AttributeMap; 37 | import de.intarsys.tools.event.Event; 38 | import de.intarsys.tools.event.EventDispatcher; 39 | import de.intarsys.tools.event.EventType; 40 | import de.intarsys.tools.event.INotificationListener; 41 | import de.intarsys.tools.yalf.api.ILogger; 42 | 43 | /** 44 | * Abstract superclass for implementing {@link ICardTerminal} 45 | *

46 | * To provide asynchronous communication with cards, the card terminal may 47 | * delegate tasks to an executor. Typical examples are connection creation or 48 | * transaction setup, as these may be pending dependent on some external system 49 | * state. 50 | * 51 | */ 52 | public abstract class CommonCardTerminal implements ICardTerminal { 53 | 54 | private static final ILogger Log = PACKAGE.Log; 55 | 56 | private final CommonCardSystem cardSystem; 57 | 58 | private EnumCardTerminalState state; 59 | 60 | protected final Object lock = new Object(); 61 | 62 | private final EventDispatcher eventDispatcher; 63 | 64 | private final AttributeMap attributes = new AttributeMap(); 65 | 66 | private CommonCard card; 67 | 68 | private final String id; 69 | 70 | private final List resourceFinalizers; 71 | 72 | protected CommonCardTerminal(CommonCardSystem cardSystem, String id) 73 | throws CardException { 74 | super(); 75 | if (cardSystem == null) { 76 | throw new CardException("card system required"); 77 | } 78 | this.id = id; 79 | this.cardSystem = cardSystem; 80 | this.resourceFinalizers = new ArrayList(2); 81 | this.eventDispatcher = new EventDispatcher(this); 82 | this.state = EnumCardTerminalState.CONNECTED; 83 | } 84 | 85 | @Override 86 | public void addNotificationListener(EventType type, 87 | INotificationListener listener) { 88 | eventDispatcher.addNotificationListener(type, listener); 89 | } 90 | 91 | @Override 92 | public void addSecondaryResourceFinalizer(Runnable finalizer) { 93 | synchronized (this) { 94 | resourceFinalizers.add(finalizer); 95 | } 96 | } 97 | 98 | protected abstract CommonCardConnection basicConnectDirect(String id, 99 | ScheduledExecutorService executor) throws CardException; 100 | 101 | protected void basicDispose() { 102 | freeSecondaryResources(); 103 | } 104 | 105 | protected CommonCard basicGetCard() { 106 | return card; 107 | } 108 | 109 | protected void basicSetCard(CommonCard card) { 110 | this.card = card; 111 | } 112 | 113 | protected void checkValidity() throws CardException { 114 | if (isDisposed()) { 115 | throw new CardUnavailable(); 116 | } 117 | } 118 | 119 | @Override 120 | public final ICardConnection connectDirect() throws CardException { 121 | String suffix = CardTools.createId(); 122 | String executorId = getId() + "-*-" + suffix; 123 | ScheduledExecutorService executor = CardTools.createExecutor(executorId); 124 | return basicConnectDirect(suffix, executor); 125 | } 126 | 127 | @Override 128 | public final void dispose() { 129 | CommonCard tempCard; 130 | synchronized (lock) { 131 | if (state == EnumCardTerminalState.INVALID) { 132 | return; 133 | } 134 | state = EnumCardTerminalState.INVALID; 135 | tempCard = card; 136 | card = null; 137 | } 138 | if (tempCard != null) { 139 | tempCard.dispose(); 140 | } 141 | basicDispose(); 142 | } 143 | 144 | @Override 145 | public void freeSecondaryResources() { 146 | List tempFinalizers; 147 | synchronized (this) { 148 | tempFinalizers = new ArrayList(resourceFinalizers); 149 | resourceFinalizers.clear(); 150 | } 151 | for (Runnable finalizer : tempFinalizers) { 152 | finalizer.run(); 153 | } 154 | } 155 | 156 | @Override 157 | public Object getAttribute(Object key) { 158 | return attributes.getAttribute(key); 159 | } 160 | 161 | @Override 162 | public ICard getCard() { 163 | synchronized (lock) { 164 | return card; 165 | } 166 | } 167 | 168 | @Override 169 | public CommonCardSystem getCardSystem() { 170 | return cardSystem; 171 | } 172 | 173 | protected EventDispatcher getEventDispatcher() { 174 | return eventDispatcher; 175 | } 176 | 177 | public String getId() { 178 | return id; 179 | } 180 | 181 | protected String getLogLabel() { 182 | return "terminal " + id; 183 | } 184 | 185 | @Override 186 | public EnumCardTerminalState getState() { 187 | synchronized (lock) { 188 | return state; 189 | } 190 | } 191 | 192 | @Override 193 | public boolean isDisposed() { 194 | synchronized (lock) { 195 | return state == EnumCardTerminalState.INVALID; 196 | } 197 | } 198 | 199 | @Override 200 | public Object removeAttribute(Object key) { 201 | return attributes.removeAttribute(key); 202 | } 203 | 204 | @Override 205 | public void removeNotificationListener(EventType type, 206 | INotificationListener listener) { 207 | eventDispatcher.removeNotificationListener(type, listener); 208 | } 209 | 210 | @Override 211 | public Object setAttribute(Object key, Object value) { 212 | return attributes.setAttribute(key, value); 213 | } 214 | 215 | @Override 216 | public String toString() { 217 | return getLogLabel(); 218 | } 219 | 220 | protected void triggerCardEvent(ICard card, EnumCardState oldState, 221 | EnumCardState newState) { 222 | final CardEvent event = new CardEvent(card, oldState, newState); 223 | triggerEvent(event); 224 | } 225 | 226 | protected void triggerEvent(final Event event) { 227 | getEventDispatcher().triggerEvent(event); 228 | } 229 | 230 | } 231 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/CommonCardTransmitter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | /** 33 | * Abstract superclass for implementing {@link ICardTransmitter} 34 | * 35 | */ 36 | public class CommonCardTransmitter implements ICardTransmitter { 37 | 38 | private final ICardTransmitter cardTransmitter; 39 | 40 | public CommonCardTransmitter(ICardTransmitter transmitter) { 41 | super(); 42 | this.cardTransmitter = transmitter; 43 | } 44 | 45 | protected ResponseAPDU basicTransmit(RequestAPDU request) throws CardException { 46 | RequestAPDU encodedRequest = encodeRequest(request); 47 | ResponseAPDU encodedResponse = getCardTransmitter().transmit(encodedRequest); 48 | return decodeResponse(encodedResponse); 49 | } 50 | 51 | protected ResponseAPDU decodeResponse(ResponseAPDU response) throws CardException { 52 | return response; 53 | } 54 | 55 | protected RequestAPDU encodeRequest(RequestAPDU request) throws CardException { 56 | return request; 57 | } 58 | 59 | protected RequestAPDU fixLengthExpected(RequestAPDU request, int correctLE) { 60 | int cla = request.getCla(); 61 | int ins = request.getIns(); 62 | int p1 = request.getP1(); 63 | int p2 = request.getP2(); 64 | byte[] data = request.getData(); 65 | if (data == null) { 66 | return new RequestAPDU(cla, ins, p1, p2, correctLE, false); 67 | } else { 68 | return new RequestAPDU(cla, ins, p1, p2, data, correctLE, false); 69 | } 70 | } 71 | 72 | public ICardTransmitter getCardTransmitter() { 73 | return cardTransmitter; 74 | } 75 | 76 | @Override 77 | public ResponseAPDU transmit(RequestAPDU request) throws CardException { 78 | return basicTransmit(request); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/EnumCardState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.tools.enumeration.EnumItem; 33 | import de.intarsys.tools.enumeration.EnumMeta; 34 | 35 | /** 36 | * The enumeration of supported states for a {@link ICard}. 37 | */ 38 | @SuppressWarnings("unchecked") 39 | public class EnumCardState extends EnumItem { 40 | 41 | public static final EnumCardState CONNECTED_EXCLUSIVE = new EnumCardState( 42 | "connectedExclusive"); //$NON-NLS-1$ 43 | 44 | public static final EnumCardState CONNECTED_SHARED = new EnumCardState( 45 | "connectedShared"); //$NON-NLS-1$ 46 | 47 | public static final EnumCardState INVALID = new EnumCardState("invalid"); //$NON-NLS-1$ 48 | 49 | /** The meta data for the enumeration. */ 50 | public static final EnumMeta META = getMeta(EnumCardState.class); 51 | 52 | public static final EnumCardState NOT_CONNECTED = new EnumCardState( 53 | "notConnected"); //$NON-NLS-1$ 54 | 55 | public static final EnumCardState UNKNOWN = new EnumCardState("unknown"); //$NON-NLS-1$ 56 | 57 | static { 58 | UNKNOWN.setDefault(); 59 | } 60 | 61 | protected EnumCardState(String id) { 62 | super(id); 63 | } 64 | 65 | public boolean isConnectedExclusive() { 66 | return this == CONNECTED_EXCLUSIVE; 67 | } 68 | 69 | public boolean isConnectedShared() { 70 | return this == CONNECTED_SHARED; 71 | } 72 | 73 | public boolean isInvalid() { 74 | return this == INVALID; 75 | } 76 | 77 | public boolean isNotConnected() { 78 | return this == NOT_CONNECTED || this == UNKNOWN; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/EnumCardTerminalState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.tools.enumeration.EnumItem; 33 | import de.intarsys.tools.enumeration.EnumMeta; 34 | 35 | /** 36 | * The enumeration of supported states for a {@link ICardTerminal}. 37 | */ 38 | @SuppressWarnings("unchecked") 39 | public class EnumCardTerminalState extends EnumItem { 40 | 41 | public static final EnumCardTerminalState CONNECTED = new EnumCardTerminalState( 42 | "connected"); //$NON-NLS-1$ 43 | 44 | public static final EnumCardTerminalState INVALID = new EnumCardTerminalState( 45 | "invalid"); //$NON-NLS-1$ 46 | 47 | /** The meta data for the enumeration. */ 48 | public static final EnumMeta META = getMeta(EnumCardTerminalState.class); 49 | 50 | static { 51 | CONNECTED.setDefault(); 52 | } 53 | 54 | protected EnumCardTerminalState(String id) { 55 | super(id); 56 | } 57 | 58 | public boolean isConnected() { 59 | return this == CONNECTED; 60 | } 61 | 62 | public boolean isInvalid() { 63 | return this == INVALID; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/ICard.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import java.util.concurrent.Future; 33 | 34 | import de.intarsys.tools.attribute.IAttributeSupport; 35 | import de.intarsys.tools.concurrent.ITaskCallback; 36 | 37 | /** 38 | * The abstraction of a smartcard inserted in an {@link ICardTerminal}. An 39 | * {@link ICard} can be achieved by calling {@link ICardTerminal#getCard()} if 40 | * present. 41 | * 42 | * Ensure thread safe implementation for {@link IAttributeSupport}! 43 | */ 44 | public interface ICard extends IAttributeSupport { 45 | 46 | /** 47 | * Connect to the card exclusive. 48 | * 49 | * @param protocol 50 | * 51 | * @return A {@link ICardConnection} 52 | */ 53 | public ICardConnection connectExclusive(int protocol) throws CardException; 54 | 55 | /** 56 | * Connect to the card asynchronously. 57 | * 58 | * @param protocol 59 | * @param callback 60 | * The callback to be executed upon termination of the operation. 61 | * 62 | * @return A Future giving access to the ongoing operation. 63 | */ 64 | public Future connectShared(int protocol, 65 | ITaskCallback callback); 66 | 67 | /** 68 | * The {@link ATR} identifying the {@link ICard}. 69 | * 70 | * @return The {@link ATR} identifying the {@link ICard}. 71 | */ 72 | public ATR getAtr(); 73 | 74 | /** 75 | * The {@link ICardTerminal} where the {@link ICard} is inserted. 76 | * 77 | * @return The {@link ICardTerminal} where the {@link ICard} is inserted. 78 | */ 79 | public ICardTerminal getCardTerminal(); 80 | 81 | /** 82 | * The current state of the {@link ICard}. 83 | * 84 | * @return The current state of the {@link ICard}. 85 | */ 86 | public EnumCardState getState(); 87 | 88 | /** 89 | * true if this card is "attached" via contactless reader. 90 | * 91 | * @return 92 | */ 93 | public boolean isContactless(); 94 | 95 | } 96 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/ICardConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import java.util.concurrent.Future; 33 | 34 | import de.intarsys.security.smartcard.pcsc.nativec._IPCSC; 35 | import de.intarsys.tools.attribute.IAttributeSupport; 36 | import de.intarsys.tools.concurrent.ITaskCallback; 37 | 38 | /** 39 | * The abstraction of a connection opened to an {@link ICard}. An 40 | * {@link ICardConnection} can be achieved by calling some of the "connect.." 41 | * methods in {@link ICard} or {@link ICardTerminal}. 42 | * 43 | */ 44 | public interface ICardConnection extends ICardTransmitter, IAttributeSupport { 45 | 46 | public static final int MODE_LEAVE_CARD = _IPCSC.SCARD_LEAVE_CARD; 47 | public static final int MODE_RESET = _IPCSC.SCARD_RESET_CARD; 48 | public static final int MODE_UNPOWER = _IPCSC.SCARD_UNPOWER_CARD; 49 | public static final int MODE_EJECT = _IPCSC.SCARD_EJECT_CARD; 50 | 51 | /** 52 | * Open an transaction asynchronously. 53 | * 54 | * @param callback 55 | * The callback to be executed upon termination of the operation. 56 | * @return A {@link Future} giving access to the ongoing operation. 57 | */ 58 | public Future beginTransaction(ITaskCallback callback); 59 | 60 | /** 61 | * Close an open {@link ICardConnection}. "mode" is one of 62 | * {@link ICardConnection#MODE_EJECT }, 63 | * {@link ICardConnection#MODE_LEAVE_CARD}, 64 | * {@link ICardConnection#MODE_RESET}, {@link ICardConnection#MODE_UNPOWER} 65 | * 66 | * @throws CardException 67 | */ 68 | public void close(int mode) throws CardException; 69 | 70 | /** 71 | * Send a control request to the card terminal. The request is sent as it is 72 | * requested (no mapping is performed). 73 | * 74 | * @param controlCode 75 | * @param inBuffer 76 | * @param inBufferOffset 77 | * @param inBufferLength 78 | * @param outBufferSize 79 | * @return 80 | * @throws CardException 81 | */ 82 | public byte[] control(int controlCode, byte[] inBuffer, int inBufferOffset, 83 | int inBufferLength, int outBufferSize) throws CardException; 84 | 85 | /** 86 | * Send a control request to the card terminal. The request control code is 87 | * adapted according to the environment (Win* or PCSClite). 88 | * 89 | * @param controlCode 90 | * @param inBuffer 91 | * @param inBufferOffset 92 | * @param inBufferLength 93 | * @param outBufferSize 94 | * @return 95 | * @throws CardException 96 | */ 97 | public byte[] controlMapped(int controlCode, byte[] inBuffer, 98 | int inBufferOffset, int inBufferLength, int outBufferSize) 99 | throws CardException; 100 | 101 | /** 102 | * End a previously started transaction. 103 | * 104 | * @throws CardException 105 | */ 106 | public void endTransaction() throws CardException; 107 | 108 | /** 109 | * Get attribute data from the card terminal. 110 | * 111 | * @param attribId 112 | * @return 113 | * @throws CardException 114 | */ 115 | public byte[] getAttrib(int attribId) throws CardException; 116 | 117 | /** 118 | * The {@link ICard} to which we have opened a {@link ICardConnection}. 119 | * 120 | * @return The {@link ICard} to which we have opened a 121 | * {@link ICardConnection}. This may return null for a direct 122 | * connection! 123 | */ 124 | public ICard getCard(); 125 | 126 | /** 127 | * The {@link ICardTerminal } to which we have opened a 128 | * {@link ICardConnection}. This is important in addition to #getCard, 129 | * because we may have a direct connection *without* an {@link ICard} 130 | * 131 | * @return The {@link ICardTerminal } to which we have opened a 132 | * {@link ICardConnection}. 133 | */ 134 | public ICardTerminal getCardTerminal(); 135 | 136 | /** 137 | * The active protocol. 138 | * 139 | * @return 140 | */ 141 | public int getProtocol(); 142 | 143 | /** 144 | * Experimental - access PCSC State. This is used for keep-alive only... 145 | * 146 | */ 147 | public void getStatus() throws CardException; 148 | 149 | /** 150 | * @return true if a transaction is active 151 | */ 152 | public boolean isTransactionActive(); 153 | 154 | /** 155 | * @return true if the channel is closed and this object should not be used anymore. 156 | */ 157 | public boolean isValid(); 158 | 159 | /** 160 | * Reconnect an existing connection. 161 | * 162 | * @param mode 163 | */ 164 | public void reconnect(int mode) throws CardException; 165 | 166 | } 167 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/ICardConnectionFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | /** 33 | * A filter for {@link ICardConnection} instances. 34 | *

35 | * Implementors can select (or reject) {@link ICardConnection} instances. 36 | * 37 | */ 38 | public interface ICardConnectionFilter { 39 | 40 | /** 41 | * true if connection is acceptable. 42 | * 43 | * @param connection 44 | * @return true if connection is acceptable. 45 | */ 46 | boolean accept(ICardConnection connection); 47 | 48 | } -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/ICardFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | /** 33 | * A filter for {@link ICard} instances. 34 | * 35 | */ 36 | public interface ICardFilter { 37 | 38 | /** 39 | * true if card is acceptable. 40 | * 41 | * @param card 42 | * @return true if card is acceptable. 43 | */ 44 | public boolean accept(ICard card); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/ICardSystem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.security.smartcard.card.ICardSystem.DefaultResolver; 33 | import de.intarsys.security.smartcard.card.standard.StandardCardSystem; 34 | import de.intarsys.security.smartcard.pcsc.PCSCContextFactory; 35 | import de.intarsys.tools.event.AttributeChangedEvent; 36 | import de.intarsys.tools.event.INotificationSupport; 37 | import de.intarsys.tools.servicelocator.IServiceResolver; 38 | import de.intarsys.tools.servicelocator.ServiceImplementation; 39 | 40 | /** 41 | * The abstraction of the smartcard environment connected to the system. The 42 | * {@link ICardSystem} may interface to native PCSC, using the javax.smartcardio 43 | * or whatever. 44 | *

45 | * {@link ICardSystem} monitors the card environment in a monitoring thread. 46 | * Token events (found and removed) are propagated to registered listeners as 47 | * {@link AttributeChangedEvent} named "ATTR_CARD_TERMINALS". 48 | *

49 | * {@link ICardSystem} is used in a multithreaded environment and its state is 50 | * accessed by either the monitoring thread or the client code requesting the 51 | * {@link ICardTerminal} instances. 52 | */ 53 | @ServiceImplementation(defaultResolver = DefaultResolver.class) 54 | public interface ICardSystem extends INotificationSupport { 55 | 56 | public static class DefaultResolver implements IServiceResolver { 57 | @Override 58 | public ICardSystem apply(Class t) { 59 | return new StandardCardSystem(PCSCContextFactory.get()); 60 | } 61 | } 62 | 63 | public static final String ATTR_CARD_TERMINALS = "cardTerminals"; 64 | 65 | /** 66 | * Dispose all of the objects resources. This method should be safe to be 67 | * called in any object state, especially when the object is in an 68 | * invalid/error state and when the object is already disposed. 69 | */ 70 | public void dispose(); 71 | 72 | /** 73 | * The card terminal with the requested name. The {@link ICardTerminal} 74 | * instances preserve identity. 75 | * 76 | * @param name 77 | * @return The card terminal with the requested name. 78 | */ 79 | public ICardTerminal getCardTerminal(String name); 80 | 81 | /** 82 | * The {@link ICardTerminal} instances currently available. The 83 | * {@link ICardTerminal} instances preserve identity. 84 | * 85 | * @return The {@link ICardTerminal} instances currently available. 86 | */ 87 | public ICardTerminal[] getCardTerminals(); 88 | 89 | /** 90 | * true if this object is already disposed. 91 | * 92 | * @return 93 | */ 94 | public boolean isDisposed(); 95 | 96 | /** 97 | * true if this object is currently enabled. 98 | * 99 | * @return 100 | */ 101 | public boolean isEnabled(); 102 | 103 | /** 104 | * Enable/disable the {@link ICardSystem}. 105 | * 106 | * @param enabled 107 | */ 108 | public void setEnabled(boolean enabled); 109 | 110 | } 111 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/ICardTerminal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.security.smartcard.pcsc.nativec._IPCSC; 33 | import de.intarsys.tools.attribute.IAttributeSupport; 34 | import de.intarsys.tools.event.INotificationSupport; 35 | 36 | /** 37 | * The abstraction of a single terminal, optionally containing a token, 38 | * connected to the system. 39 | *

40 | * {@link ICardTerminal} monitors the state of the associated terminal / token 41 | * in a thread of its own as long as connected. 42 | *

43 | * {@link ICardTerminal} is used in a multithreaded environment and its state is 44 | * accessed by either its monitoring thread or the client code . 45 | * 46 | * Ensure thread safe implementation for {@link IAttributeSupport}! 47 | */ 48 | public interface ICardTerminal extends INotificationSupport, IAttributeSupport { 49 | 50 | public static final int PROTOCOL_RAW = _IPCSC.SCARD_PROTOCOL_RAW; 51 | public static final int PROTOCOL_T0 = _IPCSC.SCARD_PROTOCOL_T0; 52 | public static final int PROTOCOL_T1 = _IPCSC.SCARD_PROTOCOL_T1; 53 | public static final int PROTOCOL_Tx = _IPCSC.SCARD_PROTOCOL_Tx; 54 | 55 | public abstract void addSecondaryResourceFinalizer(Runnable runnable); 56 | 57 | /** 58 | * Connect to the card terminal directly. 59 | * 60 | * @return A {@link ICardConnection} 61 | */ 62 | public abstract ICardConnection connectDirect() throws CardException; 63 | 64 | /** 65 | * Dispose all of the objects resources. This method should be safe to be 66 | * called in any object state, especially when the object is in an 67 | * invalid/error state and when the object is already disposed. 68 | */ 69 | public void dispose(); 70 | 71 | public abstract void freeSecondaryResources(); 72 | 73 | /** 74 | * The {@link ICard} currently inserted or null. 75 | * 76 | * @return The {@link ICard} currently inserted or null. 77 | */ 78 | public abstract ICard getCard(); 79 | 80 | /** 81 | * The {@link ICardSystem} that created this {@link ICardTerminal}. 82 | * 83 | * @return The {@link ICardSystem} that created this {@link ICardTerminal}. 84 | */ 85 | public ICardSystem getCardSystem(); 86 | 87 | /** 88 | * The name of the {@link ICardTerminal}. 89 | * 90 | * @return The name of the {@link ICardTerminal}. 91 | */ 92 | public abstract String getName(); 93 | 94 | /** 95 | * The state of the {@link ICardTerminal}. 96 | * 97 | * @return The state of the {@link ICardTerminal}. 98 | */ 99 | public abstract EnumCardTerminalState getState(); 100 | 101 | /** 102 | * true if this object is already disposed. 103 | * 104 | * @return 105 | */ 106 | public boolean isDisposed(); 107 | 108 | /** 109 | * act as if card was removed an re-inserted. 110 | */ 111 | public void renew(); 112 | } -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/ICardTerminalFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | /** 33 | * A filter for {@link ICardTerminal} instances. 34 | *

35 | * Implementors can select (or reject) {@link ICardTerminal} instances. 36 | * 37 | */ 38 | public interface ICardTerminalFilter { 39 | 40 | /** 41 | * true if terminal is acceptable. 42 | * 43 | * @param terminal 44 | * @return true if terminal is acceptable. 45 | */ 46 | public boolean accept(ICardTerminal terminal); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/ICardTransmitter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | /** 33 | * An object that can transmit APDUs from/to an {@link ICard}. 34 | *

35 | * This is typically provided by {@link ICardConnection} . Another option is 36 | * daisy chaining the {@link ICardTransmitter} to implement SM or other 37 | * decorations. 38 | * 39 | */ 40 | public interface ICardTransmitter { 41 | 42 | /** 43 | * Transmit an APDU . 44 | * 45 | * @param request 46 | * The APDU request 47 | * @return The APDU response. 48 | * @throws CardException 49 | */ 50 | public ResponseAPDU transmit(RequestAPDU request) throws CardException; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/NoCardTerminal.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.tools.event.EventType; 33 | import de.intarsys.tools.event.INotificationListener; 34 | import de.intarsys.tools.message.IMessageBundle; 35 | 36 | public class NoCardTerminal implements ICardTerminal { 37 | 38 | private static final IMessageBundle Msg = PACKAGE.Messages; 39 | 40 | public NoCardTerminal() { 41 | // 42 | } 43 | 44 | @Override 45 | public void addNotificationListener(EventType type, 46 | INotificationListener listener) { 47 | // 48 | } 49 | 50 | @Override 51 | public void addSecondaryResourceFinalizer(Runnable runnable) { 52 | // 53 | } 54 | 55 | @Override 56 | public ICardConnection connectDirect() throws CardException { 57 | throw new CardException("no terminal"); //$NON-NLS-1$ 58 | } 59 | 60 | @Override 61 | public void dispose() { 62 | // 63 | } 64 | 65 | @Override 66 | public void freeSecondaryResources() { 67 | // 68 | } 69 | 70 | @Override 71 | public Object getAttribute(Object key) { 72 | return null; 73 | } 74 | 75 | @Override 76 | public ICard getCard() { 77 | return null; 78 | } 79 | 80 | @Override 81 | public ICardSystem getCardSystem() { 82 | return null; 83 | } 84 | 85 | @Override 86 | public String getName() { 87 | return Msg.getString("NoCardTerminal.name"); //$NON-NLS-1$ 88 | } 89 | 90 | @Override 91 | public EnumCardTerminalState getState() { 92 | return de.intarsys.security.smartcard.card.EnumCardTerminalState.CONNECTED; 93 | } 94 | 95 | public boolean isCardPresent() { 96 | return false; 97 | } 98 | 99 | @Override 100 | public boolean isDisposed() { 101 | return false; 102 | } 103 | 104 | @Override 105 | public Object removeAttribute(Object key) { 106 | return null; 107 | } 108 | 109 | @Override 110 | public void removeNotificationListener(EventType type, 111 | INotificationListener listener) { 112 | // 113 | } 114 | 115 | @Override 116 | public void renew() { 117 | } 118 | 119 | @Override 120 | public Object setAttribute(Object key, Object o) { 121 | return null; 122 | } 123 | 124 | @Override 125 | public String toString() { 126 | return ""; //$NON-NLS-1$ 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/PACKAGE.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import de.intarsys.tools.message.IMessageBundle; 33 | import de.intarsys.tools.message.MessageTools; 34 | import de.intarsys.tools.yalf.api.ILogger; 35 | import de.intarsys.tools.yalf.common.LogTools; 36 | 37 | class PACKAGE { 38 | public static final ILogger Log = LogTools.getLogger(PACKAGE.class); 39 | 40 | public static final IMessageBundle Messages = MessageTools 41 | .getMessageBundle(PACKAGE.class); 42 | } 43 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/RegexCardTerminalFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import java.util.HashMap; 33 | import java.util.Map; 34 | import java.util.regex.Matcher; 35 | import java.util.regex.Pattern; 36 | 37 | public class RegexCardTerminalFilter implements ICardTerminalFilter { 38 | 39 | private static final String PATTERN_STRING = "\\s*(\\w*)\\s*[:=]([^;]*);?"; //$NON-NLS-1$ 40 | 41 | private static final Pattern PATTERN = Pattern.compile(PATTERN_STRING); 42 | 43 | public static RegexCardTerminalFilter create(String definition) { 44 | RegexCardTerminalFilter filter = new RegexCardTerminalFilter(); 45 | Matcher m = PATTERN.matcher(definition); 46 | while (m.find()) { 47 | String key = m.group(1); 48 | String value = m.group(2); 49 | filter.addMatch(key, value.trim()); 50 | } 51 | return filter; 52 | } 53 | 54 | private Map patterns = new HashMap(); 55 | 56 | @Override 57 | public boolean accept(ICardTerminal terminal) { 58 | Pattern pattern; 59 | // 60 | pattern = patterns.get("name"); //$NON-NLS-1$ 61 | if (pattern != null && !pattern.matcher(terminal.getName()).matches()) { 62 | return false; 63 | } 64 | return true; 65 | } 66 | 67 | public void addMatch(String key, String regularExpression) { 68 | patterns.put(key, Pattern.compile(regularExpression)); 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | StringBuilder sb = new StringBuilder(); 74 | for (Map.Entry entry : patterns.entrySet()) { 75 | sb.append(entry.getKey()); 76 | sb.append("="); //$NON-NLS-1$ 77 | sb.append(entry.getValue().pattern()); 78 | } 79 | return sb.toString(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/ResponseAPDU.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | import java.io.ByteArrayInputStream; 33 | import java.io.InputStream; 34 | 35 | import de.intarsys.tools.hex.HexTools; 36 | 37 | /** 38 | * The data object received from the {@link ICard}. 39 | *

40 | * See ISO 7816-4 41 | * 42 | */ 43 | public class ResponseAPDU { 44 | 45 | private final byte[] bytes; 46 | 47 | public ResponseAPDU(byte[] response) throws CardException { 48 | assert (response != null); 49 | if (response.length < 2) { 50 | throw new CardException("Invalid response received from card reader"); //$NON-NLS-1$ 51 | } 52 | this.bytes = response; 53 | } 54 | 55 | public ResponseAPDU(byte[] data, int sw) { 56 | if (data == null) { 57 | data = new byte[0]; 58 | } 59 | bytes = new byte[data.length + 2]; 60 | System.arraycopy(data, 0, bytes, 0, data.length); 61 | bytes[data.length] = (byte) ((sw >> 8) & 0xff); 62 | bytes[data.length + 1] = (byte) (sw & 0xff); 63 | } 64 | 65 | public ResponseAPDU(byte[] data, int sw1, int sw2) { 66 | if (data == null) { 67 | data = new byte[0]; 68 | } 69 | bytes = new byte[data.length + 2]; 70 | System.arraycopy(data, 0, bytes, 0, data.length); 71 | bytes[data.length] = (byte) sw1; 72 | bytes[data.length + 1] = (byte) sw2; 73 | } 74 | 75 | /** 76 | * The whole APDU content including SW. 77 | * 78 | * @return The whole APDU content including SW. 79 | */ 80 | public byte[] getBytes() { 81 | return bytes; 82 | } 83 | 84 | /** 85 | * The net data of the APDU. 86 | * 87 | * @return The net data of the APDU. 88 | */ 89 | public byte[] getData() { 90 | byte[] data = new byte[bytes.length - 2]; 91 | System.arraycopy(bytes, 0, data, 0, data.length); 92 | return data; 93 | } 94 | 95 | /** 96 | * Fill length bytes starting at offset of the net data of the APDU into 97 | * pBytes. The number of bytes really transferred are returned. 98 | * 99 | * @param pBytes 100 | * @param offset 101 | * @param length 102 | * @return The number of bytes copied. 103 | */ 104 | public int getData(byte[] pBytes, int offset, int length) { 105 | int count = bytes.length - 2; 106 | if (length < count) { 107 | count = length; 108 | } 109 | System.arraycopy(bytes, 0, pBytes, offset, count); 110 | return count; 111 | } 112 | 113 | /** 114 | * The net data of the APDU as an {@link InputStream}. 115 | * 116 | * @return 117 | */ 118 | public InputStream getInputStream() { 119 | return new ByteArrayInputStream(bytes, 0, bytes.length - 2); 120 | } 121 | 122 | /** 123 | * The two SW bytes as an int (MSB first). 124 | * 125 | * @return 126 | */ 127 | public int getSw() { 128 | return ((bytes[bytes.length - 2] & 0xFF) << 8) + (bytes[bytes.length - 1] & 0xFF); 129 | } 130 | 131 | /** 132 | * First byte of SW. 133 | * 134 | * @return 135 | */ 136 | public int getSw1() { 137 | return bytes[bytes.length - 2] & 0xFF; 138 | } 139 | 140 | /** 141 | * Second byte of SW. 142 | * 143 | * @return 144 | */ 145 | public int getSw2() { 146 | return bytes[bytes.length - 1] & 0xFF; 147 | } 148 | 149 | public String getSwString() { 150 | return "0x" + Integer.toHexString(getSw1()) + "" + Integer.toHexString(getSw2()); 151 | } 152 | 153 | /** 154 | * True if APDU contains net data. 155 | * 156 | * @return 157 | * 158 | */ 159 | public boolean hasData() { 160 | return bytes.length > 2; 161 | } 162 | 163 | /** 164 | * True if SW code == 9000 165 | * 166 | * @return 167 | */ 168 | public boolean isOk() { 169 | return getSw1() == 0x90 && getSw2() == 0x00; 170 | } 171 | 172 | @Override 173 | public String toString() { 174 | return HexTools.bytesToHexString(bytes); 175 | } 176 | 177 | } 178 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/T0CardTransmitter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | /** 33 | * A simple transmittter for T0 protocol. 34 | * 35 | * T0 specific code as described in 36 | * http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-a. aspx 37 | * 38 | */ 39 | public class T0CardTransmitter extends CommonCardTransmitter { 40 | 41 | class T0Request { 42 | private RequestAPDU request; 43 | private byte[] bytes; 44 | private int offset = 0; 45 | private boolean ready = false; 46 | private boolean envelope = false; 47 | 48 | public T0Request(RequestAPDU request) { 49 | super(); 50 | convert(request); 51 | } 52 | 53 | protected void convert(RequestAPDU request) { 54 | this.request = request; 55 | byte p3 = 0x00; 56 | int lc = request.getLc(); 57 | int le = request.getLe(); 58 | if (lc == -1 && le == -1) { 59 | // case 1 60 | p3 = 0x00; 61 | } else if (lc == -1 && le >= 0) { 62 | // case 2 63 | if (le <= 256) { 64 | p3 = (byte) le; 65 | } else { 66 | p3 = 0x00; 67 | } 68 | } else if (lc >= 0 && le == -1) { 69 | // case 3 70 | if (lc < 256) { 71 | p3 = (byte) lc; 72 | } else { 73 | // use CLA ENVELOPE 74 | envelope = true; 75 | } 76 | } else { 77 | // case 4 78 | if (lc < 256) { 79 | p3 = (byte) lc; 80 | } else { 81 | // use CLA ENVELOPE 82 | envelope = true; 83 | } 84 | } 85 | int length = 5; 86 | if (request.getData() != null) { 87 | length += request.getData().length; 88 | } 89 | if (envelope) { 90 | bytes = request.getBytes(); 91 | } else { 92 | bytes = new byte[length]; 93 | bytes[0] = (byte) request.getCla(); 94 | bytes[1] = (byte) request.getIns(); 95 | bytes[2] = (byte) request.getP1(); 96 | bytes[3] = (byte) request.getP2(); 97 | bytes[4] = p3; 98 | if (request.getData() != null) { 99 | System.arraycopy(request.getData(), 0, bytes, 5, request.getData().length); 100 | } 101 | } 102 | } 103 | 104 | protected RequestAPDU createRequest() { 105 | if (envelope) { 106 | int len = Math.min(256, bytes.length); 107 | byte[] chunk = new byte[len]; 108 | System.arraycopy(bytes, offset, chunk, 0, chunk.length); 109 | offset += len; 110 | if (offset >= bytes.length) { 111 | ready = true; 112 | } 113 | return new RequestAPDU(request.getCla(), INS_ENVELOPE, 0, 0, chunk, -1, false); 114 | } else { 115 | ready = true; 116 | return new RequestAPDU(bytes); 117 | } 118 | } 119 | 120 | public boolean isReady() { 121 | return ready; 122 | } 123 | 124 | public ResponseAPDU transmit() throws CardException { 125 | RequestAPDU tRequest = createRequest(); 126 | ResponseAPDU response = basicTransmit(tRequest); 127 | if (response.getSw() == 0x9000 && request.getLe() > 0 && response.getBytes().length == 2) { 128 | // "GET RESPONSE" command 129 | RequestAPDU getReq = new RequestAPDU(request.getCla(), INS_GET_RESPONSE, 0, 0, request.getLe(), false); 130 | response = basicTransmit(getReq); 131 | } 132 | // wrong length 133 | if (response.getSw1() == 0x6C) { 134 | int le = response.getSw2(); 135 | convert(fixLengthExpected(request, le)); 136 | offset = 0; 137 | RequestAPDU fixedRequest = createRequest(); 138 | response = basicTransmit(fixedRequest); 139 | } 140 | // more available 141 | if (response.getSw1() == 0x61) { 142 | int len = response.getSw2(); 143 | RequestAPDU fixedRequest = new RequestAPDU(request.getCla(), INS_GET_RESPONSE, 0, 0, len, false); 144 | response = basicTransmit(fixedRequest); 145 | } 146 | return response; 147 | } 148 | 149 | } 150 | 151 | protected static final int INS_GET_RESPONSE = 0xC0; 152 | 153 | protected static final int INS_ENVELOPE = 0xC2; 154 | 155 | public T0CardTransmitter(ICardTransmitter transmitter) { 156 | super(transmitter); 157 | } 158 | 159 | @Override 160 | public ResponseAPDU transmit(RequestAPDU request) throws CardException { 161 | ResponseAPDU response = null; 162 | T0Request t0Request = new T0Request(request); 163 | while (!t0Request.isReady()) { 164 | response = t0Request.transmit(); 165 | } 166 | return response; 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/T1CardTransmitter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card; 31 | 32 | /** 33 | * A simple transmittter for T1 protocol. 34 | * 35 | */ 36 | public class T1CardTransmitter extends CommonCardTransmitter { 37 | 38 | public T1CardTransmitter(ICardTransmitter transmitter) { 39 | super(transmitter); 40 | } 41 | 42 | @Override 43 | public ResponseAPDU transmit(RequestAPDU request) throws CardException { 44 | ResponseAPDU response = null; 45 | response = transmitT1(request); 46 | return response; 47 | } 48 | 49 | protected ResponseAPDU transmitT1(RequestAPDU request) throws CardException { 50 | ResponseAPDU response = super.transmit(request); 51 | if (response.getSw1() == 0x6C) { 52 | int le = response.getSw2(); 53 | RequestAPDU fixedRequest = fixLengthExpected(request, le); 54 | response = super.transmit(fixedRequest); 55 | } 56 | return response; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/messages.properties: -------------------------------------------------------------------------------- 1 | ########################################################################## 2 | # 3 | # o_ 4 | # in|tarsys GmbH (c) 5 | # 6 | # NLS information 7 | # 8 | 9 | CardSharingViolationException.message=The card is in exclusive use by an other application right now. 10 | CardInvalidException.message=The card is no longer accessible 11 | 12 | NoCardTerminal.name=No card reader available 13 | 14 | CardSystemMonitor.unsupportedCard=The card is not supported for this function. 15 | CardSystemMonitor.stateConnected=Card connected. 16 | CardSystemMonitor.stateConnectedFailedCancel=Card connection canceled 17 | CardSystemMonitor.stateConnectedFailed=Card connection failed: {0} 18 | CardSystemMonitor.stateConnectedFailedUnspecified=Card connection failed 19 | CardSystemMonitor.stateNoCardAvailable=No card available. 20 | CardSystemMonitor.stateConnectedExclusive=The card is in use by another application. 21 | CardSystemMonitor.stateNotConnected=Card not connected. 22 | CardSystemMonitor.stateConnecting=Connecting to card ... 23 | 24 | CardReset.message=The card was reset -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/messages_de.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intarsys/smartcard-io/cee7fb456459abee84c9c507051fd77ef9cdf1b6/intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/messages_de.properties -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/standard/PACKAGE.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card.standard; 31 | 32 | import de.intarsys.tools.message.IMessageBundle; 33 | import de.intarsys.tools.message.MessageTools; 34 | import de.intarsys.tools.yalf.api.ILogger; 35 | import de.intarsys.tools.yalf.common.LogTools; 36 | 37 | class PACKAGE { 38 | public static final ILogger Log = LogTools.getLogger(PACKAGE.class); 39 | 40 | public static final IMessageBundle Messages = MessageTools 41 | .getMessageBundle(PACKAGE.class); 42 | } 43 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/standard/StandardCard.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card.standard; 31 | 32 | import java.util.concurrent.ScheduledExecutorService; 33 | 34 | import de.intarsys.security.smartcard.card.ATR; 35 | import de.intarsys.security.smartcard.card.CardException; 36 | import de.intarsys.security.smartcard.card.CommonCard; 37 | import de.intarsys.security.smartcard.card.CommonCardConnection; 38 | import de.intarsys.security.smartcard.card.EnumCardState; 39 | import de.intarsys.security.smartcard.card.ICardTerminal; 40 | import de.intarsys.tools.yalf.api.ILogger; 41 | 42 | /** 43 | * The abstraction of a smartcard inserted in a {@link StandardCardTerminal}. A 44 | * {@link StandardCard} can be achieved by calling {@link 45 | * ICardTerminal#getCard()} 46 | *

47 | * {@link StandardCard} is part of the abstraction layer that is built on top of 48 | * the PCSC API. 49 | * 50 | */ 51 | public class StandardCard extends CommonCard { 52 | 53 | private static final ILogger Log = PACKAGE.Log; 54 | 55 | public StandardCard(StandardCardTerminal cardTerminal, ATR atr) { 56 | super(cardTerminal, atr); 57 | } 58 | 59 | @Override 60 | protected CommonCardConnection basicConnectExclusive(String suffix, int protocol, ScheduledExecutorService executor) 61 | throws CardException { 62 | return basicGetCardTerminal().basicConnectExclusive(this, suffix, protocol, 63 | executor); 64 | } 65 | 66 | @Override 67 | protected CommonCardConnection basicConnectShared(String suffix, int protocol, ScheduledExecutorService executor) 68 | throws CardException { 69 | return basicGetCardTerminal().basicConnectShared(this, suffix, protocol, 70 | executor); 71 | } 72 | 73 | @Override 74 | protected StandardCardTerminal basicGetCardTerminal() { 75 | return (StandardCardTerminal) super.basicGetCardTerminal(); 76 | } 77 | 78 | /* 79 | * make method available in package 80 | * 81 | * @see de.intarsys.security.smartcard.card.CommonCard#dispose() 82 | */ 83 | @Override 84 | protected void dispose() { 85 | super.dispose(); 86 | } 87 | 88 | /* 89 | * make method available in package 90 | * 91 | * @see 92 | * de.intarsys.security.smartcard.card.CommonCard#setState(de.intarsys.security 93 | * .smartcard.card.EnumCardState) 94 | */ 95 | @Override 96 | protected void setState(EnumCardState newState) { 97 | super.setState(newState); 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/card/standard/StandardCardConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.card.standard; 31 | 32 | import java.util.concurrent.ScheduledExecutorService; 33 | 34 | import de.intarsys.security.smartcard.card.CardException; 35 | import de.intarsys.security.smartcard.card.CommonCardConnection; 36 | import de.intarsys.security.smartcard.card.RequestAPDU; 37 | import de.intarsys.security.smartcard.card.ResponseAPDU; 38 | import de.intarsys.security.smartcard.pcsc.IPCSCConnection; 39 | import de.intarsys.security.smartcard.pcsc.PCSCException; 40 | import de.intarsys.security.smartcard.pcsc.nativec._IPCSC; 41 | import de.intarsys.tools.yalf.api.ILogger; 42 | 43 | /** 44 | * The abstraction of a connection opened to a {@link StandardCard}. A 45 | * {@link StandardCardConnection} can be achieved by calling some of the 46 | * "connect.." methods in {@link StandardCard}. 47 | *

48 | * {@link StandardCardConnection} is used in a multithreaded environment and its 49 | * state is changed by either one of the multiple clients working with the 50 | * {@link StandardCard} or the {@link StandardCardTerminal} controlling its 51 | * state. 52 | *

53 | * {@link StandardCard} is part of the abstraction layer that is built on top of 54 | * the PCSC API. From a PCSC point of view, both a PCSC context AND a PCSC 55 | * connection are made for a new StandardCardConnection. This is the least 56 | * common denominator for different PCSC platforms and versions. Again, this is 57 | * why both the connection and the context are disposed when closing the 58 | * connection. 59 | * 60 | */ 61 | public class StandardCardConnection extends CommonCardConnection { 62 | 63 | private static final ILogger Log = PACKAGE.Log; 64 | 65 | private final IPCSCConnection pcscConnection; 66 | 67 | protected StandardCardConnection(StandardCard pCard, 68 | ScheduledExecutorService executorTask, boolean exclusive, 69 | IPCSCConnection pPcscConnection) { 70 | super(pCard, pPcscConnection.getId(), executorTask, exclusive); 71 | this.pcscConnection = pPcscConnection; 72 | Log.debug("{} created for {}", this, pcscConnection); //$NON-NLS-1$ 73 | } 74 | 75 | protected StandardCardConnection(StandardCardTerminal pCardTerminal, ScheduledExecutorService executorTask, 76 | boolean exclusive, IPCSCConnection pPcscConnection) { 77 | super(pCardTerminal, pPcscConnection.getId(), executorTask, exclusive); 78 | this.pcscConnection = pPcscConnection; 79 | Log.debug("{} created for {}", this, pcscConnection); //$NON-NLS-1$ 80 | } 81 | 82 | @Override 83 | protected void basicBeginTransaction() throws CardException { 84 | try { 85 | pcscConnection.beginTransaction(); 86 | } catch (PCSCException e) { 87 | throw CardException.create(e); 88 | } 89 | super.basicBeginTransaction(); 90 | } 91 | 92 | @Override 93 | protected void basicClose(int mode) throws CardException { 94 | try { 95 | pcscConnection.disconnect(mode); 96 | } catch (Exception e) { 97 | // 98 | } 99 | try { 100 | pcscConnection.getContext().dispose(); 101 | } catch (PCSCException e) { 102 | throw CardException.create(e); 103 | } 104 | } 105 | 106 | @Override 107 | protected byte[] basicControl(int controlCode, byte[] inBuffer, 108 | int inBufferOffset, int inBufferLength, int outBufferSize) 109 | throws CardException { 110 | try { 111 | return pcscConnection.control(controlCode, inBuffer, 112 | inBufferOffset, inBufferLength, outBufferSize); 113 | } catch (PCSCException e) { 114 | throw CardException.create(e); 115 | } 116 | } 117 | 118 | @Override 119 | protected byte[] basicControlMapped(int controlCode, byte[] inBuffer, 120 | int inBufferOffset, int inBufferLength, int outBufferSize) 121 | throws CardException { 122 | try { 123 | return pcscConnection.controlMapped(controlCode, inBuffer, 124 | inBufferOffset, inBufferLength, outBufferSize); 125 | } catch (PCSCException e) { 126 | throw CardException.create(e); 127 | } 128 | } 129 | 130 | @Override 131 | protected void basicEndTransaction() throws CardException { 132 | try { 133 | pcscConnection.endTransaction(_IPCSC.SCARD_LEAVE_CARD); 134 | } catch (PCSCException e) { 135 | throw CardException.create(e); 136 | } 137 | } 138 | 139 | @Override 140 | protected byte[] basicGetAttrib(int attribId) throws CardException { 141 | try { 142 | return pcscConnection.getAttrib(attribId); 143 | } catch (PCSCException e) { 144 | throw CardException.create(e); 145 | } 146 | } 147 | 148 | @Override 149 | protected StandardCard basicGetCard() { 150 | return (StandardCard) super.basicGetCard(); 151 | } 152 | 153 | @Override 154 | protected void basicGetStatus() throws CardException { 155 | try { 156 | pcscConnection.getStatus(); 157 | } catch (PCSCException e) { 158 | throw CardException.create(e); 159 | } 160 | } 161 | 162 | @Override 163 | protected void basicReconnect(int mode) throws CardException { 164 | try { 165 | pcscConnection.reconnect(pcscConnection.getShareMode(), 166 | pcscConnection.getProtocol(), mode); 167 | } catch (PCSCException e) { 168 | throw CardException.create(e); 169 | } 170 | } 171 | 172 | @Override 173 | protected ResponseAPDU basicTransmit(RequestAPDU request) 174 | throws CardException { 175 | try { 176 | byte[] response = pcscConnection.transmit(request.getBytes(), 0, 177 | request.getLength(), request.getReceiveLength(), 178 | request.isSensitiveContent()); 179 | return new ResponseAPDU(response); 180 | } catch (PCSCException e) { 181 | throw CardException.create(e); 182 | } 183 | } 184 | 185 | public IPCSCConnection getPcscConnection() { 186 | return pcscConnection; 187 | } 188 | 189 | @Override 190 | public int getProtocol() { 191 | return pcscConnection.getProtocol(); 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/CardStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | /** Some kind of value holder for what SCardStatus returns */ 33 | public class CardStatus { 34 | 35 | byte[] atr; 36 | private int protocol; 37 | private String[] readerNames; 38 | private int state; 39 | 40 | public CardStatus(String readerName, int state, int protocol, byte[] atr) { 41 | this(new String[] { readerName }, state, protocol, atr); 42 | } 43 | 44 | public CardStatus(String[] readerNames, int state, int protocol, byte[] atr) { 45 | this.readerNames = readerNames; 46 | this.state = state; 47 | this.protocol = protocol; 48 | this.atr = atr; 49 | } 50 | 51 | public byte[] getAtr() { 52 | return atr; 53 | } 54 | 55 | public int getProtocol() { 56 | return protocol; 57 | } 58 | 59 | public String getReaderName() { 60 | return readerNames[0]; 61 | } 62 | 63 | public String[] getReaderNames() { 64 | return readerNames; 65 | } 66 | 67 | public int getState() { 68 | return state; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/CommonPCSCLib.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import javax.annotation.PostConstruct; 33 | 34 | import de.intarsys.security.smartcard.pcsc.nativec._IPCSC; 35 | import de.intarsys.security.smartcard.pcsc.nativec._PCSC; 36 | import de.intarsys.security.smartcard.pcsc.nativec._PCSCThreadedExecutor; 37 | import de.intarsys.tools.system.SystemTools; 38 | import de.intarsys.tools.yalf.api.ILogger; 39 | 40 | /** 41 | * A common implementation for a native library, installed in the 42 | * {@link NativePCSCContextFactory}. 43 | * 44 | * The separation of common code to this superclass was due to the fact that the 45 | * PC/SC API implementations of some manufacturer were quite poor and needed 46 | * some special tweaks on each call on the java side... 47 | * 48 | * In these days we only use the standard concrete implementation 49 | * {@link NativePCSCLib}. 50 | * 51 | */ 52 | public abstract class CommonPCSCLib implements INativePCSCLib { 53 | 54 | private static final ILogger Log = PACKAGE.Log; 55 | 56 | private _IPCSC pcsc; 57 | 58 | private String path; 59 | 60 | private boolean useExecutorThread = false; 61 | 62 | private boolean useBlockingGetStatusChange = SystemTools.isWindows(); 63 | 64 | public CommonPCSCLib() { 65 | } 66 | 67 | protected void createNativeWrapper() { 68 | try { 69 | _PCSC nativeWrapper = new _PCSC(path); 70 | if (useExecutorThread) { 71 | pcsc = new _PCSCThreadedExecutor(nativeWrapper); 72 | } else { 73 | pcsc = nativeWrapper; 74 | } 75 | } catch (Throwable t) { 76 | Log.warn("No PC/SC interface available: {}\n{}", t.getMessage(), t); 77 | } 78 | } 79 | 80 | public String getPath() { 81 | return path; 82 | } 83 | 84 | public _IPCSC getPcsc() { 85 | return pcsc; 86 | } 87 | 88 | @PostConstruct 89 | public void initialize() { 90 | createNativeWrapper(); 91 | NativePCSCContextFactory.get().registerLibrary(this); 92 | } 93 | 94 | public boolean isUseBlockingGetStatusChange() { 95 | return useBlockingGetStatusChange; 96 | } 97 | 98 | public boolean isUseExecutorThread() { 99 | return useExecutorThread; 100 | } 101 | 102 | public void setPath(String path) { 103 | this.path = path; 104 | } 105 | 106 | public void setUseBlockingGetStatusChange(boolean useBlockingGetStatusChange) { 107 | this.useBlockingGetStatusChange = useBlockingGetStatusChange; 108 | } 109 | 110 | public void setUseExecutorThread(boolean useExecutorThread) { 111 | this.useExecutorThread = useExecutorThread; 112 | } 113 | 114 | @Override 115 | public String toString() { 116 | StringBuilder sb = new StringBuilder(); 117 | sb.append("PC/SC library; path "); 118 | sb.append(getPath()); 119 | sb.append("; executor "); 120 | sb.append(isUseExecutorThread()); 121 | sb.append("; blocking "); 122 | sb.append(isUseBlockingGetStatusChange()); 123 | return sb.toString(); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/EmptyContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import java.util.Collections; 33 | import java.util.List; 34 | import java.util.concurrent.TimeoutException; 35 | 36 | /** 37 | * A dummy context. 38 | * 39 | */ 40 | public class EmptyContext implements IPCSCContext { 41 | 42 | public EmptyContext() { 43 | // 44 | } 45 | 46 | public void acquire() { 47 | // 48 | } 49 | 50 | public void cancelGetStatusChange() throws PCSCException { 51 | } 52 | 53 | @Override 54 | public IPCSCConnection connect(String id, String readerName, int shareMode, int protocol) throws PCSCException { 55 | return null; 56 | } 57 | 58 | @Override 59 | public void dispose() { 60 | // 61 | } 62 | 63 | @Override 64 | public IPCSCContext establishContext() { 65 | return new EmptyContext(); 66 | } 67 | 68 | @Override 69 | public PCSCCardReaderState getStatusChange(String readerName, 70 | PCSCCardReaderState currentState, int millisecTimeout) 71 | throws PCSCException, TimeoutException { 72 | return null; 73 | } 74 | 75 | @Override 76 | public boolean isDisposed() { 77 | return false; 78 | } 79 | 80 | @Override 81 | public List listReaders() { 82 | return Collections.emptyList(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/INativePCSCLib.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | /** 33 | * The abstraction of an external library implementing the PC/SC API. These 34 | * libraries get installed in the {@link NativePCSCContextFactory}. 35 | * 36 | * Currently we only need to create the {@link IPCSCContext}, but who knows... 37 | */ 38 | public interface INativePCSCLib extends IPCSCContextFactory { 39 | 40 | } 41 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/IPCSCCardReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | /** 33 | * The iconified PC/SC card reader terminal. 34 | * 35 | * This is created by {@link IPCSCContext#listReaders()}. 36 | * 37 | */ 38 | public interface IPCSCCardReader { 39 | 40 | /** 41 | * The {@link IPCSCContext} that created this reader. 42 | * 43 | * @return 44 | */ 45 | public IPCSCContext getContext(); 46 | 47 | /** 48 | * the unique id 49 | * 50 | * @return 51 | */ 52 | public String getId(); 53 | 54 | /** 55 | * The PSCS reader name. 56 | * 57 | * @return 58 | */ 59 | public String getName(); 60 | 61 | /** 62 | * Get the current {@link PCSCCardReaderState}. 63 | * 64 | * @return 65 | * @throws PCSCException 66 | */ 67 | public PCSCCardReaderState getState() throws PCSCException; 68 | 69 | } -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/IPCSCConnection.java: -------------------------------------------------------------------------------- 1 | package de.intarsys.security.smartcard.pcsc; 2 | 3 | /** 4 | * The iconified PC/SC connection. The methods are mapped directly to the 5 | * repsective PC/SC API functions. 6 | * 7 | * This is created by {@link IPCSCContext#connect(String, String, int, int)}. 8 | * 9 | */ 10 | public interface IPCSCConnection { 11 | 12 | /** 13 | * Start a new transaction. 14 | * 15 | * @throws PCSCException 16 | */ 17 | public void beginTransaction() throws PCSCException; 18 | 19 | /** 20 | * Send a control code. 21 | * 22 | * @param controlCode 23 | * @param inBuffer 24 | * @param inBufferOffset 25 | * @param inBufferLength 26 | * @param outBufferSize 27 | * @return 28 | * @throws PCSCException 29 | */ 30 | public byte[] control(int controlCode, byte[] inBuffer, int inBufferOffset, 31 | int inBufferLength, int outBufferSize) throws PCSCException; 32 | 33 | /** 34 | * Send a control code, mapped to fit the current platform where PC/SC is 35 | * running. This is needed as PC/SC control codes vary between windows and 36 | * PCSC Lite. 37 | * 38 | * @param controlCode 39 | * @param inBuffer 40 | * @param inBufferOffset 41 | * @param inBufferLength 42 | * @param outBufferSize 43 | * @return 44 | * @throws PCSCException 45 | */ 46 | public byte[] controlMapped(int controlCode, byte[] inBuffer, 47 | int inBufferOffset, int inBufferLength, int outBufferSize) 48 | throws PCSCException; 49 | 50 | /** 51 | * Disconnect this connection. It is not valid to use this connection from 52 | * now. 53 | * 54 | * @param mode 55 | * @throws PCSCException 56 | */ 57 | public void disconnect(int mode) throws PCSCException; 58 | 59 | /** 60 | * End the current transaction. 61 | * 62 | * @param mode 63 | * @throws PCSCException 64 | */ 65 | public void endTransaction(int mode) throws PCSCException; 66 | 67 | /** 68 | * GEt an PC/SC attribute. 69 | * 70 | * @param id 71 | * @return 72 | * @throws PCSCException 73 | */ 74 | public byte[] getAttrib(int id) throws PCSCException; 75 | 76 | /** 77 | * The {@link IPCSCContext} that created the connection. 78 | * 79 | * @return 80 | */ 81 | public IPCSCContext getContext(); 82 | 83 | /** 84 | * A name uniquely identifying the connection 85 | * 86 | * @return 87 | */ 88 | public String getId(); 89 | 90 | /** 91 | * The protocol used. 92 | * 93 | * @return 94 | */ 95 | public int getProtocol(); 96 | 97 | /** 98 | * The share mode used. 99 | * 100 | * @return 101 | */ 102 | public int getShareMode(); 103 | 104 | /** 105 | * Get some information about the connected reader 106 | * 107 | * @throws PCSCException 108 | */ 109 | public CardStatus getStatus() throws PCSCException; 110 | 111 | /** 112 | * Reconnect the connection. 113 | * 114 | * @param shareMode 115 | * @param protocol 116 | * @param mode 117 | * @throws PCSCException 118 | */ 119 | public void reconnect(int shareMode, int protocol, int mode) 120 | throws PCSCException; 121 | 122 | /** 123 | * Send bytes to the card. 124 | * 125 | * In extension to the PC/SC API we introduce a flag if the content sent to 126 | * the card may be logged to some device. The default implementation can log 127 | * all communication. 128 | * 129 | * @param bytes 130 | * @param i 131 | * @param length 132 | * @param receiveLength 133 | * @param sensitiveContent 134 | * @return 135 | * @throws PCSCException 136 | */ 137 | public byte[] transmit(byte[] bytes, int i, int length, int receiveLength, 138 | boolean sensitiveContent) throws PCSCException; 139 | 140 | } 141 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/IPCSCContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import java.util.List; 33 | import java.util.concurrent.TimeoutException; 34 | 35 | /** 36 | * The iconified PC/SC context. 37 | * 38 | * This is created by some {@link IPCSCContextFactory}, available at 39 | * {@link PCSCContextFactory#get()} 40 | * 41 | */ 42 | public interface IPCSCContext extends IPCSCContextFactory { 43 | 44 | /** 45 | * Open an {@link IPCSCConnection}. 46 | * 47 | * @param id 48 | * @param readerName 49 | * @param shareMode 50 | * @param protocol 51 | * @return 52 | * @throws PCSCException 53 | */ 54 | public IPCSCConnection connect(String id, String readerName, int shareMode, int protocol) throws PCSCException; 55 | 56 | /** 57 | * Dispose the PC/SC context. 58 | * 59 | * @throws PCSCException 60 | */ 61 | public abstract void dispose() throws PCSCException; 62 | 63 | /** 64 | * Get a {@link PCSCCardReaderState} for the context and the selected 65 | * reader. 66 | * 67 | * @param readerName 68 | * @param currentState 69 | * @param millisecTimeout 70 | * @return 71 | * @throws PCSCException 72 | * @throws TimeoutException 73 | */ 74 | public PCSCCardReaderState getStatusChange(String readerName, PCSCCardReaderState currentState, int millisecTimeout) 75 | throws PCSCException, TimeoutException; 76 | 77 | /** 78 | * true if this object is already disposed. 79 | * 80 | * @return true if this object is already disposed. 81 | */ 82 | public boolean isDisposed(); 83 | 84 | /** 85 | * Enumerate all readers. 86 | * 87 | * @return 88 | * @throws PCSCException 89 | */ 90 | public abstract List listReaders() throws PCSCException; 91 | 92 | } -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/IPCSCContextFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import de.intarsys.security.smartcard.pcsc.IPCSCContextFactory.DefaultResolver; 33 | import de.intarsys.tools.servicelocator.IServiceResolver; 34 | import de.intarsys.tools.servicelocator.ServiceImplementation; 35 | 36 | /** 37 | * A factory for an {@link IPCSCContext}. 38 | * 39 | * This is a simplification to allow client code to ask a new context directly 40 | * from an existing context. 41 | * 42 | */ 43 | @ServiceImplementation(defaultResolver = DefaultResolver.class) 44 | public interface IPCSCContextFactory { 45 | 46 | public static class DefaultResolver implements IServiceResolver { 47 | @Override 48 | public IPCSCContextFactory apply(Class t) { 49 | return NativePCSCContextFactory.get(); 50 | } 51 | } 52 | 53 | /** 54 | * Create a new {@link IPCSCContext}. 55 | * 56 | * @return The new {@link IPCSCContext}. 57 | * @throws PCSCException 58 | */ 59 | public IPCSCContext establishContext() throws PCSCException; 60 | 61 | } 62 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/NativePCSCContextFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | import de.intarsys.security.smartcard.pcsc.nativec._PCSC; 36 | import de.intarsys.tools.component.SingletonClass; 37 | import de.intarsys.tools.system.SystemTools; 38 | import de.intarsys.tools.yalf.api.ILogger; 39 | import de.intarsys.tools.yalf.api.Level; 40 | 41 | /** 42 | * An {@link IPCSCContextFactory} wrapping native libraries. 43 | * 44 | */ 45 | @SingletonClass 46 | public class NativePCSCContextFactory implements IPCSCContextFactory { 47 | 48 | private static ILogger Log = PACKAGE.Log; 49 | 50 | private static final NativePCSCContextFactory ACTIVE = new NativePCSCContextFactory(); 51 | 52 | public static final String SYSTEM_DEFAULT_LIBRARY = _PCSC.SYSTEM_DEFAULT_LIBRARY; 53 | 54 | public static NativePCSCContextFactory get() { 55 | return ACTIVE; 56 | } 57 | 58 | private final List libraries; 59 | 60 | private NativePCSCContextFactory() { 61 | libraries = new ArrayList(2); 62 | } 63 | 64 | @Override 65 | public IPCSCContext establishContext() throws PCSCException { 66 | if (libraries.isEmpty()) { 67 | Log.log(Level.INFO, "loading PC/SC system default library"); //$NON-NLS-1$ 68 | NativePCSCLib lib = new NativePCSCLib(); 69 | lib.setPath(SYSTEM_DEFAULT_LIBRARY); 70 | lib.setUseExecutorThread(false); 71 | lib.setUseBlockingGetStatusChange(SystemTools.isWindows()); 72 | lib.initialize(); 73 | } 74 | List contexts = new ArrayList(libraries.size()); 75 | PCSCException cause = null; 76 | for (INativePCSCLib pcsclib : libraries) { 77 | IPCSCContext context; 78 | 79 | try { 80 | context = pcsclib.establishContext(); 81 | contexts.add(context); 82 | } catch (PCSCException e) { 83 | cause = e; 84 | Log.log(Level.SEVERE, "Failed to establish PC/SC context", e); //$NON-NLS-1$ 85 | } 86 | } 87 | if (contexts.size() == 0) { 88 | if (cause == null) { 89 | throw new PCSCException("Failed to establish PC/SC context"); //$NON-NLS-1$ 90 | } else { 91 | throw cause; 92 | } 93 | } 94 | if (contexts.size() == 1) { 95 | return contexts.get(0); 96 | } 97 | return new PCSCMultiContext(this, contexts); 98 | } 99 | 100 | public List getLibraries() { 101 | return new ArrayList<>(libraries); 102 | } 103 | 104 | public void registerLibrary(INativePCSCLib pcsclib) { 105 | if (Log.isLoggable(Level.TRACE)) { 106 | Log.trace("Adding library " + pcsclib); //$NON-NLS-1$ 107 | } 108 | libraries.add(pcsclib); 109 | } 110 | 111 | @Override 112 | public String toString() { 113 | return "PCSC context factory"; //$NON-NLS-1$ 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/NativePCSCLib.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import de.intarsys.security.smartcard.pcsc.nativec._IPCSC; 33 | 34 | /** 35 | * The default {@link INativePCSCLib} implementation. 36 | * 37 | */ 38 | public class NativePCSCLib extends CommonPCSCLib { 39 | 40 | public NativePCSCLib() { 41 | } 42 | 43 | @Override 44 | public IPCSCContext establishContext() throws PCSCException { 45 | _IPCSC pcsc = getPcsc(); 46 | if (pcsc == null) { 47 | return new EmptyContext(); 48 | } 49 | PCSCContext result = new PCSCContext(this, pcsc); 50 | result.setUseBlockingGetStatusChange(isUseBlockingGetStatusChange()); 51 | return result; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PACKAGE.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import de.intarsys.tools.message.IMessageBundle; 33 | import de.intarsys.tools.message.MessageTools; 34 | import de.intarsys.tools.yalf.api.ILogger; 35 | import de.intarsys.tools.yalf.common.LogTools; 36 | 37 | class PACKAGE { 38 | 39 | public static final ILogger Log = LogTools 40 | .getLogger("de.intarsys.security.smartcard.pcsc"); 41 | 42 | public static final IMessageBundle Messages = MessageTools 43 | .getMessageBundle(PACKAGE.class); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PCSCCardReader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import java.util.concurrent.TimeoutException; 33 | 34 | import de.intarsys.tools.oid.IOIDGenerator; 35 | import de.intarsys.tools.oid.PronouncableOIDGenerator; 36 | import de.intarsys.tools.yalf.api.ILogger; 37 | 38 | /** 39 | * The default {@link IPCSCCardReader} implementation. 40 | * 41 | * {@link PCSCCardReader} instances are not implemented "unique" - each 42 | * {@link IPCSCContext#listReaders()} will create a new instance. 43 | * 44 | */ 45 | public class PCSCCardReader implements IPCSCCardReader { 46 | 47 | private static final IOIDGenerator OID_GENERATOR = new PronouncableOIDGenerator(); 48 | 49 | private static final ILogger Log = PACKAGE.Log; 50 | 51 | private final String name; 52 | 53 | private final IPCSCContext context; 54 | 55 | private final String id; 56 | 57 | public PCSCCardReader(IPCSCContext context, String readerName) { 58 | this.context = context; 59 | this.name = readerName; 60 | this.id = OID_GENERATOR.createOID(); 61 | } 62 | 63 | @Override 64 | public IPCSCContext getContext() { 65 | return context; 66 | } 67 | 68 | @Override 69 | public String getId() { 70 | return id; 71 | } 72 | 73 | @Override 74 | public String getName() { 75 | return name; 76 | } 77 | 78 | @Override 79 | public PCSCCardReaderState getState() throws PCSCException { 80 | try { 81 | return getContext().getStatusChange(this.getName(), null, 0); 82 | } catch (TimeoutException e) { 83 | // will not happen 84 | return PCSCCardReaderState.UNAWARE; 85 | } 86 | } 87 | 88 | @Override 89 | public String toString() { 90 | return "pcscreader " + getId() + ", " + getName(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PCSCCardReaderState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import java.util.HashMap; 33 | import java.util.Map; 34 | 35 | import de.intarsys.security.smartcard.pcsc.nativec.SCARD_READERSTATE; 36 | import de.intarsys.security.smartcard.pcsc.nativec._IPCSC; 37 | import de.intarsys.tools.hex.HexTools; 38 | import de.intarsys.tools.string.IPrettyPrintable; 39 | import de.intarsys.tools.string.PrettyPrinter; 40 | 41 | /** 42 | * The PC/SC model level card reader state. 43 | * 44 | */ 45 | public class PCSCCardReaderState implements IPrettyPrintable { 46 | 47 | public static final PCSCCardReaderState UNAWARE = new PCSCCardReaderState(null); 48 | 49 | private final SCARD_READERSTATE readerState; 50 | 51 | private static final Map STATE_LABELS = new HashMap(); 52 | 53 | static { 54 | STATE_LABELS.put(_IPCSC.SCARD_STATE_ATRMATCH, "ATRMATCH"); 55 | STATE_LABELS.put(_IPCSC.SCARD_STATE_CHANGED, "CHANGED"); 56 | STATE_LABELS.put(_IPCSC.SCARD_STATE_EMPTY, "EMPTY"); 57 | STATE_LABELS.put(_IPCSC.SCARD_STATE_EXCLUSIVE, "EXCLUSIVE"); 58 | STATE_LABELS.put(_IPCSC.SCARD_STATE_IGNORE, "IGNORE"); 59 | STATE_LABELS.put(_IPCSC.SCARD_STATE_INUSE, "INUSE"); 60 | STATE_LABELS.put(_IPCSC.SCARD_STATE_MUTE, "MUTE"); 61 | STATE_LABELS.put(_IPCSC.SCARD_STATE_PRESENT, "PRESENT"); 62 | STATE_LABELS.put(_IPCSC.SCARD_STATE_UNAVAILABLE, "UNAVAILABLE"); 63 | STATE_LABELS.put(_IPCSC.SCARD_STATE_UNAWARE, "UNAWARE"); 64 | STATE_LABELS.put(_IPCSC.SCARD_STATE_UNKNOWN, "UNKNOWN"); 65 | STATE_LABELS.put(_IPCSC.SCARD_STATE_UNPOWERED, "UNPOWERED"); 66 | } 67 | 68 | protected PCSCCardReaderState(SCARD_READERSTATE readerState) { 69 | this.readerState = readerState; 70 | } 71 | 72 | public byte[] getATR() { 73 | if (readerState == null) { 74 | return null; 75 | } 76 | byte[] atr = readerState.getATR(); 77 | if (atr.length < 5) { 78 | return null; 79 | } 80 | return atr; 81 | } 82 | 83 | public int getCurrentState() { 84 | if (readerState == null) { 85 | return _IPCSC.SCARD_STATE_UNAWARE; 86 | } 87 | return readerState.getCurrentState(); 88 | } 89 | 90 | public int getEventState() { 91 | if (readerState == null) { 92 | return _IPCSC.SCARD_STATE_UNAWARE; 93 | } 94 | return readerState.getEventState(); 95 | } 96 | 97 | public String getReader() { 98 | if (readerState == null) { 99 | return null; 100 | } 101 | return readerState.getReader(); 102 | } 103 | 104 | public boolean isATRMatch() { 105 | return (getEventState() & _IPCSC.SCARD_STATE_ATRMATCH) != 0; 106 | } 107 | 108 | public boolean isChanged() { 109 | return (getEventState() & _IPCSC.SCARD_STATE_CHANGED) != 0; 110 | } 111 | 112 | public boolean isEmpty() { 113 | return (getEventState() & _IPCSC.SCARD_STATE_EMPTY) != 0; 114 | } 115 | 116 | public boolean isExclusive() { 117 | return (getEventState() & _IPCSC.SCARD_STATE_EXCLUSIVE) != 0; 118 | } 119 | 120 | public boolean isIgnore() { 121 | return (getEventState() & _IPCSC.SCARD_STATE_IGNORE) != 0; 122 | } 123 | 124 | public boolean isInUse() { 125 | return (getEventState() & _IPCSC.SCARD_STATE_INUSE) != 0; 126 | } 127 | 128 | public boolean isMute() { 129 | return (getEventState() & _IPCSC.SCARD_STATE_MUTE) != 0; 130 | } 131 | 132 | public boolean isPresent() { 133 | return (getEventState() & _IPCSC.SCARD_STATE_PRESENT) != 0; 134 | } 135 | 136 | protected boolean isSet(int state, Integer flag) { 137 | return (state & flag) != 0; 138 | } 139 | 140 | public boolean isUnavailable() { 141 | return (getEventState() & _IPCSC.SCARD_STATE_UNAVAILABLE) != 0; 142 | } 143 | 144 | public boolean isUnknown() { 145 | return (getEventState() & _IPCSC.SCARD_STATE_UNKNOWN) != 0; 146 | } 147 | 148 | private boolean isUnpowered() { 149 | return (getEventState() & _IPCSC.SCARD_STATE_UNPOWERED) != 0; 150 | } 151 | @Override 152 | public final String toString() { 153 | return new PrettyPrinter().toString(this); 154 | } 155 | 156 | @Override 157 | public void toString(PrettyPrinter printer) { 158 | if (readerState == null) { 159 | printer.appendString(""); 160 | return; 161 | } 162 | printer.appendMember("reader", readerState.getReader(), null); 163 | printer.appendMember("currentState", Integer.toBinaryString(readerState.getCurrentState()), 164 | toStringState(readerState.getCurrentState())); 165 | printer.appendMember("eventState", Integer.toBinaryString(readerState.getEventState()), 166 | toStringState(readerState.getEventState())); 167 | printer.appendMember("cAtr", readerState.getATRSize(), null); 168 | printer.appendMember("bAtr", HexTools.bytesToHexString(readerState.getATR()), null); 169 | } 170 | 171 | protected String toStringState(int state) { 172 | StringBuilder builder = new StringBuilder(); 173 | for (Integer flag : STATE_LABELS.keySet()) { 174 | if (isSet(state, flag)) { 175 | if (builder.length() > 0) { 176 | builder.append(", "); //$NON-NLS-1$ 177 | } 178 | builder.append(STATE_LABELS.get(flag)); 179 | } 180 | } 181 | return builder.toString(); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PCSCCardReset.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import de.intarsys.security.smartcard.pcsc.nativec._PCSC_RETURN_CODES; 33 | 34 | /** 35 | * Signal a PCSC level card reset. 36 | * 37 | */ 38 | public class PCSCCardReset extends PCSCException { 39 | 40 | public PCSCCardReset() { 41 | super(_PCSC_RETURN_CODES.SCARD_W_RESET_CARD); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PCSCCardUnavailable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | /** 33 | * Signal a PCSC level card drop. 34 | * 35 | * This is not software recoverable. 36 | * 37 | */ 38 | public class PCSCCardUnavailable extends PCSCException { 39 | 40 | public PCSCCardUnavailable(int errorCode) { 41 | super(errorCode); 42 | } 43 | 44 | public PCSCCardUnavailable(int errorCode, String message) { 45 | super(errorCode, message); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PCSCContextFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import de.intarsys.tools.component.SingletonProvider; 33 | import de.intarsys.tools.servicelocator.ServiceLocator; 34 | import de.intarsys.tools.system.SystemTools; 35 | 36 | /** 37 | * A singleton access for the {@link IPCSCContextFactory} on this system. 38 | * 39 | */ 40 | @SingletonProvider 41 | public class PCSCContextFactory { 42 | 43 | private static boolean pcscLite = false; 44 | 45 | static { 46 | pcscLite = !SystemTools.isWindows(); 47 | } 48 | 49 | public static IPCSCContextFactory get() { 50 | return ServiceLocator.get().get(IPCSCContextFactory.class); 51 | } 52 | 53 | public static synchronized boolean isPcscLite() { 54 | return pcscLite; 55 | } 56 | 57 | public static synchronized int mapControlCode(int code) { 58 | if (pcscLite) { 59 | return 0x42000000 | code; 60 | } 61 | return 0x310000 | (code << 2); 62 | } 63 | 64 | protected static synchronized void setPcscLite(boolean pPcscLite) { 65 | pcscLite = pPcscLite; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PCSCException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, this 8 | * list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import de.intarsys.security.smartcard.pcsc.nativec._PCSC_RETURN_CODES; 33 | import de.intarsys.tools.message.IMessageBundle; 34 | import de.intarsys.tools.reflect.ClassTools; 35 | 36 | /** 37 | * An exceptional condition in the PC/SC handling 38 | * 39 | */ 40 | public class PCSCException extends Exception implements _PCSC_RETURN_CODES { 41 | 42 | private static final long serialVersionUID = 1L; 43 | 44 | private static final IMessageBundle Msg = PACKAGE.Messages; 45 | 46 | public static void checkReturnCode(int rc) throws PCSCException { 47 | if (rc == SCARD_S_SUCCESS) { 48 | return; 49 | } 50 | /* 51 | * these are "recoverable" states where the card rests in the terminal 52 | */ 53 | if (rc == // 54 | _PCSC_RETURN_CODES.SCARD_W_RESET_CARD // 55 | || rc == _PCSC_RETURN_CODES.SCARD_W_UNPOWERED_CARD // 56 | ) { 57 | throw new PCSCCardReset(); 58 | } 59 | if (rc == // 60 | _PCSC_RETURN_CODES.SCARD_W_REMOVED_CARD // 61 | || rc == _PCSC_RETURN_CODES.SCARD_W_UNRESPONSIVE_CARD // 62 | || rc == _PCSC_RETURN_CODES.SCARD_W_UNSUPPORTED_CARD // 63 | || rc == _PCSC_RETURN_CODES.SCARD_E_CARD_UNSUPPORTED // 64 | || rc == _PCSC_RETURN_CODES.SCARD_E_NO_SMARTCARD) { 65 | throw new PCSCCardUnavailable(rc); 66 | } 67 | if (rc == _PCSC_RETURN_CODES.SCARD_E_SHARING_VIOLATION) { 68 | throw new PCSCSharingViolation(rc); 69 | } 70 | throw new PCSCException(rc); 71 | } 72 | 73 | public static void checkReturnCode(int rc, int size) throws PCSCException { 74 | if (rc == _PCSC_RETURN_CODES.ERROR_INSUFFICIENT_BUFFER 75 | || rc == _PCSC_RETURN_CODES.SCARD_E_INSUFFICIENT_BUFFER) { 76 | throw new PCSCException(rc, ": at least " + size + " bytes required"); 77 | } 78 | checkReturnCode(rc); 79 | } 80 | 81 | private int errorCode = 0; 82 | 83 | public PCSCException(int errorCode) { 84 | this.errorCode = errorCode; 85 | } 86 | 87 | public PCSCException(int errorCode, String message) { 88 | super(message); 89 | this.errorCode = errorCode; 90 | } 91 | 92 | public PCSCException(String message) { 93 | super(message); 94 | } 95 | 96 | public PCSCException(String message, Throwable cause) { 97 | super(message, cause); 98 | } 99 | 100 | public int getErrorCode() { 101 | return errorCode; 102 | } 103 | 104 | @Override 105 | public String getMessage() { 106 | String tempMsg = super.getMessage(); 107 | if (errorCode == 0) { 108 | return tempMsg; 109 | } 110 | if (tempMsg == null) { 111 | tempMsg = ""; 112 | } 113 | 114 | String name = ClassTools.getConstantName(_PCSC_RETURN_CODES.class, errorCode); 115 | if (name != null) { 116 | String msg = Msg.getPattern("PCSCException.error." + name); //$NON-NLS-1$ 117 | if (msg != null) { 118 | return Msg.format(msg, tempMsg); 119 | } else { 120 | return Msg.getString("PCSCException.error_default", name, //$NON-NLS-1$ 121 | tempMsg); 122 | } 123 | } else { 124 | return Msg.getString("PCSCException.error_default", errorCode, tempMsg); //$NON-NLS-1$ 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PCSCMultiContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | import java.util.concurrent.TimeoutException; 35 | 36 | /** 37 | * A special context that can elegate to multiple libraries. 38 | * 39 | * This is useful in situations where we dynamically use (manufacturer 40 | * dependent) PC/SC implementations, for example on a USB stick. No you can 41 | * control these, together with the standard PC/SC resources, using single 42 | * {@link IPCSCContext}. 43 | * 44 | */ 45 | public class PCSCMultiContext implements IPCSCContext { 46 | 47 | private final List contexts; 48 | 49 | private final IPCSCContextFactory system; 50 | 51 | private boolean disposed = false; 52 | 53 | public PCSCMultiContext(IPCSCContextFactory system, 54 | List contexts) { 55 | this.system = system; 56 | this.contexts = contexts; 57 | } 58 | 59 | public void cancelGetStatusChange() throws PCSCException { 60 | } 61 | 62 | @Override 63 | public IPCSCConnection connect(String id, String readerName, int shareMode, int protocol) throws PCSCException { 64 | return null; 65 | } 66 | 67 | @Override 68 | public void dispose() { 69 | synchronized (this) { 70 | if (disposed) { 71 | return; 72 | } 73 | disposed = true; 74 | } 75 | for (IPCSCContext context : contexts) { 76 | try { 77 | context.dispose(); 78 | } catch (PCSCException e) { 79 | // ignore ? 80 | } 81 | } 82 | } 83 | 84 | @Override 85 | public IPCSCContext establishContext() throws PCSCException { 86 | return system.establishContext(); 87 | } 88 | 89 | @Override 90 | public PCSCCardReaderState getStatusChange(String readerName, 91 | PCSCCardReaderState currentState, int millisecTimeout) 92 | throws PCSCException, TimeoutException { 93 | return null; 94 | } 95 | 96 | @Override 97 | public boolean isDisposed() { 98 | synchronized (this) { 99 | return disposed; 100 | } 101 | } 102 | 103 | @Override 104 | public List listReaders() throws PCSCException { 105 | List readers = new ArrayList(); 106 | for (IPCSCContext context : contexts) { 107 | readers.addAll(context.listReaders()); 108 | } 109 | return readers; 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PCSCSharingViolation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | /** 33 | * Signal a PCSC level card sharing violation 34 | * 35 | */ 36 | public class PCSCSharingViolation extends PCSCException { 37 | 38 | public PCSCSharingViolation(int errorCode) { 39 | super(errorCode); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/PCSCTools.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc; 31 | 32 | import java.util.function.BiFunction; 33 | 34 | import de.intarsys.nativec.api.INativeHandle; 35 | import de.intarsys.nativec.type.NativeBuffer; 36 | import de.intarsys.nativec.type.NativeBufferType; 37 | import de.intarsys.nativec.type.NativeObject; 38 | import de.intarsys.nativec.type.NativeVoid; 39 | import de.intarsys.security.smartcard.pcsc.nativec.NativePcscDword; 40 | import de.intarsys.security.smartcard.pcsc.nativec._IPCSC; 41 | import de.intarsys.security.smartcard.pcsc.nativec._PCSC_RETURN_CODES; 42 | import de.intarsys.tools.string.StringTools; 43 | 44 | /** 45 | * Some tools for handling PC/SC. 46 | * 47 | */ 48 | public final class PCSCTools { 49 | 50 | /** 51 | * Variant of IBufferHelper that will when called call the provided function 52 | * in turn with the needed input to have the native code autoallocate memory 53 | * for the buffer. We also avoid clogging the finalize queue with native 54 | * objects because allocate and free is done in native code. 55 | */ 56 | private static class Autoallocate implements IBufferHelper { 57 | 58 | private NativePcscDword bufferSize = new NativePcscDword(); 59 | private NativeBuffer buffer = new NativeBuffer(NativeObject.SIZE_PTR); 60 | 61 | @Override 62 | public synchronized byte[] call(CommonPCSCContext context, 63 | BiFunction function) throws PCSCException { 64 | bufferSize.setValue(_IPCSC.SCARD_AUTOALLOCATE); 65 | int rc = function.apply(buffer, bufferSize); 66 | PCSCException.checkReturnCode(rc); 67 | INativeHandle handle = buffer.getNativeHandle(0); 68 | try { 69 | return ((NativeBuffer) NativeBufferType.create(bufferSize.intValue()).createNative(handle)).getBytes(); 70 | } finally { 71 | context.getPcsc().SCardFreeMemory(context.getHContext(), NativeVoid.META.createNative(handle)); 72 | } 73 | } 74 | } 75 | 76 | /** 77 | * Helper interface for PCSC functions that have a (single) byte buffer 78 | * output parameter. 79 | */ 80 | static interface IBufferHelper { 81 | 82 | /** 83 | * Allocate the necessary bufferSize and buffer input variables, use 84 | * them as input for the given function, and return the buffer's output 85 | * bytes. What is allocated and how function is called might vary with 86 | * what the underlying platform supports. 87 | */ 88 | byte[] call(CommonPCSCContext context, BiFunction function) 89 | throws PCSCException; 90 | } 91 | 92 | /** 93 | * Variant of IBufferHelper that will when called call the provided function 94 | * in turn with a buffer allocated with a fixed size of memory and try again 95 | * with a larger buffer in case of an "insufficient buffer" error code. The 96 | * buffer object is reused and its size will always increase if needed but 97 | * never made smaller again. We assume that we won't encounter any insane 98 | * buffer requirements. 99 | */ 100 | private static class Preallocate implements IBufferHelper { 101 | 102 | NativePcscDword bufferSize = new NativePcscDword(0); 103 | // arbitrary size 104 | NativeBuffer buffer = new NativeBuffer(256); 105 | 106 | @Override 107 | public synchronized byte[] call(CommonPCSCContext context, 108 | BiFunction function) throws PCSCException { 109 | while (true) { 110 | bufferSize.setValue(buffer.getSize()); 111 | int rc = function.apply(buffer, bufferSize); 112 | if (rc == _PCSC_RETURN_CODES.SCARD_E_INSUFFICIENT_BUFFER) { 113 | buffer = new NativeBuffer(bufferSize.intValue()); 114 | continue; 115 | } 116 | PCSCException.checkReturnCode(rc); 117 | return buffer.getByteArray(0, bufferSize.intValue()); 118 | } 119 | } 120 | } 121 | 122 | public static IBufferHelper BufferHelper = _IPCSC.SupportsAutoallocate ? new Autoallocate() : new Preallocate(); 123 | public static int DirectConnectProtocol = _IPCSC.SupportsProtocolUndefined ? _IPCSC.SCARD_PROTOCOL_UNDEFINED 124 | : _IPCSC.SCARD_PROTOCOL_Tx; 125 | 126 | /** 127 | * Convert the resuilt of an {@link IPCSCConnection#getAttrib(int)} to a 128 | * String. You must be prepared to get a zero terminated byte array. 129 | * 130 | * @param buffer 131 | * @return 132 | */ 133 | public static String toString(byte[] buffer) { 134 | if (buffer == null || buffer.length == 0) { 135 | return StringTools.EMPTY; 136 | } 137 | int length = buffer.length; 138 | while (length > 0 && buffer[length - 1] == 0) { 139 | // remove terminating 0 byte 140 | length--; 141 | } 142 | return new String(buffer, 0, length); 143 | } 144 | 145 | private PCSCTools() { 146 | // tool class 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/messages.properties: -------------------------------------------------------------------------------- 1 | ########################################################################## 2 | # 3 | # o_ 4 | # in|tarsys GmbH (c) 5 | # 6 | # NLS information 7 | # 8 | 9 | PCSCException.error_default=PC/SC error ({0}){1} 10 | PCSCException.error.SCARD_E_READER_UNAVAILABLE=Can''t access card terminal -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/messages_de.properties: -------------------------------------------------------------------------------- 1 | ########################################################################## 2 | # 3 | # o_ 4 | # in|tarsys GmbH (c) 5 | # 6 | # NLS information 7 | # 8 | 9 | PCSCException.error_default=PC/SC Fehler ({0}){1} 10 | PCSCException.error.SCARD_E_READER_UNAVAILABLE=Auf den Kartenleser konnte nicht zugegriffen werden. -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/nativec/NativePcscDword.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc.nativec; 31 | 32 | import de.intarsys.nativec.api.INativeHandle; 33 | import de.intarsys.nativec.type.INativeType; 34 | import de.intarsys.nativec.type.NativeNumber; 35 | import de.intarsys.nativec.type.NativeType; 36 | import de.intarsys.tools.system.SystemTools; 37 | 38 | /** 39 | * For some reason the DWord in PC/SC Lite header files is declared as 8 byte in 40 | * 64 bit Linux. 41 | * 42 | * On all other platforms in this universe a DWord is 4 byte. 43 | * 44 | */ 45 | public class NativePcscDword extends NativeNumber { 46 | 47 | /** The meta class instance */ 48 | public static final NativePcscDwordType META = new NativePcscDwordType(); 49 | 50 | static { 51 | NativeType.register(NativePcscDword.class, META); 52 | } 53 | 54 | public NativePcscDword() { 55 | allocate(); 56 | } 57 | 58 | protected NativePcscDword(INativeHandle handle) { 59 | super(handle); 60 | } 61 | 62 | public NativePcscDword(long value) { 63 | allocate(); 64 | setValue(value); 65 | } 66 | 67 | @Override 68 | public byte byteValue() { 69 | return (byte) longValue(); 70 | } 71 | 72 | @Override 73 | public float floatValue() { 74 | return longValue(); 75 | } 76 | 77 | @Override 78 | public INativeType getNativeType() { 79 | return META; 80 | } 81 | 82 | @Override 83 | public Object getValue() { 84 | return Long.valueOf(longValue()); 85 | } 86 | 87 | @Override 88 | public int intValue() { 89 | return (int) longValue(); 90 | } 91 | 92 | @Override 93 | public long longValue() { 94 | if (SystemTools.isLinux()) { 95 | return handle.getCLong(0); 96 | } 97 | return handle.getInt(0); 98 | } 99 | 100 | public void setValue(long value) { 101 | if (SystemTools.isLinux()) { 102 | handle.setCLong(0, value); 103 | return; 104 | } 105 | handle.setInt(0, (int) value); 106 | } 107 | 108 | @Override 109 | public void setValue(Object value) { 110 | setValue(((Number) value).longValue()); 111 | } 112 | 113 | @Override 114 | public short shortValue() { 115 | return (short) longValue(); 116 | } 117 | 118 | @Override 119 | public String toString() { 120 | if (getNativeHandle().getAddress() == 0) { 121 | return "nope - null pointer"; //$NON-NLS-1$ 122 | } 123 | return String.valueOf(longValue()); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/nativec/NativePcscDwordType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc.nativec; 31 | 32 | import de.intarsys.nativec.api.CLong; 33 | import de.intarsys.nativec.api.INativeHandle; 34 | import de.intarsys.nativec.type.INativeObject; 35 | import de.intarsys.nativec.type.NativeNumberType; 36 | import de.intarsys.nativec.type.NativeObject; 37 | import de.intarsys.tools.system.SystemTools; 38 | 39 | /** 40 | * For some reason the DWord in PC/SC Lite header files is declared as 8 byte in 41 | * 64 bit Linux. 42 | * 43 | * On all other platforms in this universe a DWord is 4 byte. 44 | * 45 | */ 46 | public class NativePcscDwordType extends NativeNumberType { 47 | 48 | /** 49 | * Utility method: return the given number as another number object with 50 | * compatible byte size 51 | */ 52 | public static Object coerce(Number value) { 53 | if (SystemTools.isLinux()) { 54 | return new CLong(value.longValue()); 55 | } 56 | return value.intValue(); 57 | } 58 | 59 | /** 60 | * Utility method: return the java class whose instances have compatible 61 | * byte size 62 | */ 63 | public static Class primitiveClass() { 64 | if (SystemTools.isLinux()) { 65 | return CLong.class; 66 | } 67 | return Integer.class; 68 | } 69 | 70 | @Override 71 | public INativeObject createNative(INativeHandle handle) { 72 | return new NativePcscDword(handle); 73 | } 74 | 75 | @Override 76 | public INativeObject createNative(Object value) { 77 | return new NativePcscDword(((Number) value).longValue()); 78 | } 79 | 80 | @Override 81 | public int getByteCount() { 82 | if (SystemTools.isLinux()) { 83 | return NativeObject.SIZE_LONG; 84 | } 85 | return NativeObject.SIZE_INT; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/nativec/SCARDCONTEXT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc.nativec; 31 | 32 | /** 33 | * The iconified handle to a PC/SC card context 34 | * 35 | */ 36 | public class SCARDCONTEXT { 37 | 38 | private long value; 39 | 40 | public SCARDCONTEXT(long pValue) { 41 | value = pValue; 42 | } 43 | 44 | public long longValue() { 45 | return value; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/nativec/SCARDHANDLE.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc.nativec; 31 | 32 | /** 33 | * The iconified handle to a PC/SC connection 34 | * 35 | */ 36 | public class SCARDHANDLE { 37 | 38 | private long value; 39 | 40 | public SCARDHANDLE(long pValue) { 41 | value = pValue; 42 | } 43 | 44 | public long longValue() { 45 | return value; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/nativec/SCARD_READERSTATE.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, intarsys GmbH 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions are met: 6 | * 7 | * - Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * - Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 14 | * - Neither the name of intarsys nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without specific 16 | * prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package de.intarsys.security.smartcard.pcsc.nativec; 31 | 32 | import de.intarsys.nativec.api.INativeHandle; 33 | import de.intarsys.nativec.type.INativeObject; 34 | import de.intarsys.nativec.type.INativeType; 35 | import de.intarsys.nativec.type.NativeArray; 36 | import de.intarsys.nativec.type.NativeByte; 37 | import de.intarsys.nativec.type.NativeStaticStruct; 38 | import de.intarsys.nativec.type.NativeString; 39 | import de.intarsys.nativec.type.NativeStructType; 40 | import de.intarsys.nativec.type.NativeVoid; 41 | import de.intarsys.nativec.type.StructMember; 42 | 43 | /** 44 | *

 45 |  * 
 46 |  *    typedef struct {
 47 |  *    LPCSTR      szReader;       // reader name
 48 |  *    LPVOID      pvUserData;     // user defined data
 49 |  *    DWORD       dwCurrentState; // current state of reader at time of call
 50 |  *    DWORD       dwEventState;   // state of reader after state change
 51 |  *    DWORD       cbAtr;          // Number of bytes in the returned ATR.
 52 |  *    BYTE        rgbAtr[36];     // ATR of inserted card, (extra alignment bytes)
 53 |  *    } SCARD_READERSTATE_A;
 54 |  * 
55 | */ 56 | public class SCARD_READERSTATE extends NativeStaticStruct { 57 | 58 | /** 59 | * The meta class implementation 60 | */ 61 | public static class MetaClass extends NativeStructType { 62 | protected MetaClass(Class instanceClass) { 63 | super(instanceClass); 64 | } 65 | 66 | @Override 67 | public INativeObject createNative(INativeHandle handle) { 68 | return new SCARD_READERSTATE(handle); 69 | } 70 | } 71 | 72 | /** The meta class instance */ 73 | public static final MetaClass META = new MetaClass(SCARD_READERSTATE.class); 74 | 75 | private static final StructMember cbAtr; 76 | 77 | private static final StructMember dwCurrentState; 78 | 79 | private static final StructMember dwEventState; 80 | 81 | private static final StructMember rgbAtr; 82 | 83 | private static final StructMember szReader; 84 | 85 | static { 86 | szReader = META.declare("szReader", NativeString.META.Ref()); //$NON-NLS-1$ 87 | META.declare("pvUserData", NativeVoid.META.Ref());//$NON-NLS-1$ 88 | dwCurrentState = META.declare("dwCurrentState", NativePcscDword.META);//$NON-NLS-1$ 89 | dwEventState = META.declare("dwEventState", NativePcscDword.META);//$NON-NLS-1$ 90 | cbAtr = META.declare("cbAtr", NativePcscDword.META);//$NON-NLS-1$ 91 | rgbAtr = META.declare("rgbAtr", NativeByte.META.Array(36));//$NON-NLS-1$ 92 | } 93 | 94 | public SCARD_READERSTATE() { 95 | super(); 96 | } 97 | 98 | protected SCARD_READERSTATE(INativeHandle nativeHandle) { 99 | super(nativeHandle); 100 | } 101 | 102 | public byte[] getATR() { 103 | int size = getATRSize(); 104 | if (size == 0) { 105 | return new byte[0]; 106 | } 107 | NativeArray array = (NativeArray) rgbAtr.getNativeObject(this); 108 | return array.getByteArray(0, size); 109 | } 110 | 111 | public int getATRSize() { 112 | int size = (int) cbAtr.getCLong(this, 0); 113 | return size < 0 ? 0 : size; 114 | } 115 | 116 | public int getCurrentState() { 117 | return (int) dwCurrentState.getCLong(this, 0); 118 | } 119 | 120 | public int getEventState() { 121 | return (int) dwEventState.getCLong(this, 0); 122 | } 123 | 124 | @Override 125 | public INativeType getNativeType() { 126 | return META; 127 | } 128 | 129 | public String getReader() { 130 | return ((NativeString) szReader.getValue(this)).stringValue(); 131 | } 132 | 133 | public void setATR(byte[] newAtr) { 134 | if (newAtr == null) { 135 | cbAtr.setInt(this, 0, 0); 136 | return; 137 | } 138 | int length = newAtr.length; 139 | if (length > 36) { 140 | throw new IllegalArgumentException( 141 | "ATR cannot be longer than 36 bytes"); //$NON-NLS-1$ 142 | } 143 | cbAtr.setInt(this, 0, newAtr.length); 144 | NativeArray array = (NativeArray) rgbAtr.getNativeObject(this); 145 | array.setByteArray(0, newAtr, 0, length); 146 | } 147 | 148 | public void setCurrentState(int state) { 149 | dwCurrentState.setValue(this, state); 150 | } 151 | 152 | public void setEventState(int state) { 153 | dwEventState.setValue(this, state); 154 | } 155 | 156 | public void setReader(NativeString name) { 157 | szReader.setValue(this, name); 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/nativec/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the PC/SC native library wrapper part. 3 | * 4 | * Based on intarsys native-c all relevant functions and structures for accessing PC/SC on Windows 5 | * and pcsc-lite based platforms are provided. 6 | * 7 | * The functions/structs/types defined and used here should be stable on all known 32 / 64 bit versions 8 | * of Win*, Linux and Mac. 9 | */ 10 | package de.intarsys.security.smartcard.pcsc.nativec; 11 | 12 | -------------------------------------------------------------------------------- /intarsys-security-smartcard-io/src/main/java/de/intarsys/security/smartcard/pcsc/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This is the high level PC/SC wrapper. 3 | * 4 | * Based on intarsys native-c all relevant functions and structures for accessing PC/SC on Windows 5 | * and pcsc-lite based platforms are provided. 6 | * 7 | */ 8 | package de.intarsys.security.smartcard.pcsc; 9 | 10 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'is-lib-security-smartcard-io' 2 | 3 | include 'intarsys-security-smartcard-io' 4 | 5 | apply from: 'dependencies.gradle' 6 | --------------------------------------------------------------------------------