This guide is intended to help a user of a previous version of Keyple Java to upgrade his application to a new version of the library.
Upgrade from:
Upgrade from “2.+” to “3.+”
This major release follows the adoption of Keypop APIs in place of CNA Terminal APIs.
We recommend that you follow the steps below in the order suggested:
- Update the project dependencies management
- Perform a global text search & replace across the entire project
- Apply the changes to the card/SAM selection manager
- Apply the changes to the card transaction manager
- Apply the changes to the signatures management (PSO or basic) during card transactions
- Apply the changes to the SAM resource service
Dependencies management
Replace the legacy Keyple dependencies with the latest versions. To do this, use the configuration wizard to correctly import the new artifacts into your project.
Renaming
Search and replace (in “case-sensitive” and “whole-word” mode) in the following order the following strings when present:
org.calypsonet.terminal.calypso
=>org.eclipse.keypop.calypso.card
org.calypsonet.terminal
=>org.eclipse.keypop
card.sam
=>crypto.legacysam.sam
Reader
=>CardReader
ObservableReader
=>ObservableCardReader
ReaderEvent
=>CardCardReader
CalypsoSam
=>LegacySam
CardSelection
=>CardSelectionExtension
CalypsoApiProperties
=>CalypsoCardApiProperties
SamIOException
=>CryptoIOException
CalypsoCardSelection
=>CalypsoCardSelectionExtension
GenericCardSelection
=>GenericCardSelectionExtension
CardSecuritySetting
=>SymmetricCryptoSecuritySetting
createCardSecuritySetting
=>createSymmetricCryptoSecuritySetting
processCommands(true)
=>processCommands(ChannelControl.CLOSE_AFTER)
processCommands(false)
=>processCommands(ChannelControl.KEEP_OPEN)
processApdusToByteArrays(true)
=>processApdusToByteArrays(ChannelControl.CLOSE_AFTER)
processApdusToByteArrays(false)
=>processApdusToByteArrays(ChannelControl.KEEP_OPEN)
processApdusToHexStrings(true)
=>processApdusToHexStrings(ChannelControl.CLOSE_AFTER)
processApdusToHexStrings(false)
=>processApdusToHexStrings(ChannelControl.KEEP_OPEN)
createCardSelectionManager()
=>getReaderApiFactory().createCardSelectionManager()
createCardSelection()
=>- Calypso card extension:
getCalypsoCardApiFactory().createCalypsoCardSelectionExtension()
- Generic card extension:
createGenericCardSelectionExtension()
- Calypso card extension:
createCardTransactionWithoutSecurity
=>getCalypsoCardApiFactory().createFreeTransactionManager
createSearchCommandData
=>getCalypsoCardApiFactory().createSearchCommandData
prepareComputeSignature
=>getCryptoExtension(CardTransactionLegacySamExtension.class).prepareComputeSignature
prepareVerifySignature
=>getCryptoExtension(CardTransactionLegacySamExtension.class).prepareVerifySignature
Card selection
Prepare a Calypso card selection case
- 2.+
CalypsoCardSelection calypsoCardSelection =
CalypsoExtensionService.getInstance().createCardSelection()
.filterByDfName(...)
.setFileOccurrence(...)
.setFileControlInformation(...);
cardSelectionManager.prepareSelection(calypsoCardSelection);
- 3.+
IsoCardSelector isoCardSelector =
SmartCardServiceProvider.getService().getReaderApiFactory().createIsoCardSelector()
.filterByDfName(...)
.setFileOccurrence(...)
.setFileControlInformation(...);
CalypsoCardSelectionExtension calypsoCardSelectionExtension =
CalypsoExtensionService.getInstance().getCalypsoCardApiFactory().createCalypsoCardSelectionExtension();
cardSelectionManager.prepareSelection(isoCardSelector, calypsoCardSelectionExtension);
Prepare a Calypso SAM selection case
- 2.+
CalypsoSamSelection CalypsoSamSelection =
CalypsoExtensionService.getInstance().createSamSelection()
.filterByProductType(productType)
.filterBySerialNumber(serialNumber);
cardSelectionManager.prepareSelection(CalypsoSamSelection);
- 3.+
String powerOnDataFilter = LegacySamUtil.buildPowerOnDataFilter(productType, serialNumber);
BasicCardSelector basicCardSelector =
SmartCardServiceProvider.getService().getReaderApiFactory().createBasicCardSelector()
.filterByPowerOnData(powerOnDataFilter);
LegacySamSelectionExtension legacySamSelectionExtension =
LegacySamExtensionService.getInstance().getLegacySamApiFactory().createLegacySamSelectionExtension();
cardSelectionManager.prepareSelection(basicCardSelector, legacySamSelectionExtension);
Prepare a Generic card selection case
- 2.+
GenericCardSelection genericCardSelection =
GenericExtensionService.getInstance().createCardSelection()
.filterByDfName(...)
.setFileOccurrence(...)
.setFileControlInformation(...);
cardSelectionManager.prepareSelection(genericCardSelection);
- 3.+
IsoCardSelector isoCardSelector =
SmartCardServiceProvider.getService().getReaderApiFactory().createIsoCardSelector()
.filterByDfName(...)
.setFileOccurrence(...)
.setFileControlInformation(...);
GenericCardSelectionExtension genericCardSelectionExtension =
GenericExtensionService.getInstance().createGenericCardSelectionExtension();
cardSelectionManager.prepareSelection(isoCardSelector, genericCardSelectionExtension);
Schedule a card selection scenario
- 2.+
cardSelectionManager.scheduleCardSelectionScenario(
observableCardReader,
detectionMode,
notificationMode);
- 3.+
cardSelectionManager.scheduleCardSelectionScenario(
observableCardReader,
notificationMode);
Card Transaction
Create a card transaction manager without security
- 2.+
CardTransactionManager cardTransactionManager =
CalypsoExtensionService.getInstance()
.createCardTransactionWithoutSecurity(cardReader, card);
- 3.+
FreeTransactionManager cardTransactionManager =
CalypsoExtensionService.getInstance()
.getCalypsoCardApiFactory().createFreeTransactionManager(cardReader, card);
Create a card transaction manager with security (regular mode)
- 2.+
CardSecuritySetting securitySetting =
CalypsoExtensionService.getInstance().createCardSecuritySetting()
.setControlSamResource(samReader, sam);
CardTransactionManager cardTransactionManager =
CalypsoExtensionService.getInstance()
.createCardTransaction(cardReader, card, securitySetting)
- 3.+
SymmetricCryptoCardTransactionManagerFactory cryptoCardTransactionManagerFactory =
LegacySamExtensionService.getInstance().getLegacySamApiFactory()
.createSymmetricCryptoCardTransactionManagerFactory(samReader, sam);
SymmetricCryptoSecuritySetting securitySetting =
CalypsoExtensionService.getInstance().getCalypsoCardApiFactory()
.createSymmetricCryptoSecuritySetting(cryptoCardTransactionManagerFactory);
SecureRegularModeTransactionManager cardTransactionManager =
CalypsoExtensionService.getInstance().getCalypsoCardApiFactory()
.createSecureRegularModeTransactionManager(cardReader, card, securitySetting);
Create a card transaction manager with security (extended mode)
- 2.+
CardSecuritySetting securitySetting =
CalypsoExtensionService.getInstance().createCardSecuritySetting()
.setControlSamResource(samReader, sam);
CardTransactionManager cardTransactionManager =
CalypsoExtensionService.getInstance()
.createCardTransaction(cardReader, card, securitySetting)
- 3.+
SymmetricCryptoCardTransactionManagerFactory cryptoCardTransactionManagerFactory =
LegacySamExtensionService.getInstance().getLegacySamApiFactory()
.createSymmetricCryptoCardTransactionManagerFactory(samReader, sam);
SymmetricCryptoSecuritySetting securitySetting =
CalypsoExtensionService.getInstance().getCalypsoCardApiFactory()
.createSymmetricCryptoSecuritySetting(cryptoCardTransactionManagerFactory);
SecureExtendedModeTransactionManager cardTransactionManager =
CalypsoExtensionService.getInstance().getCalypsoCardApiFactory()
.createSecureExtendedModeTransactionManager(cardReader, card, securitySetting);
PSO signature management (computation/verification)
- 2.+
TraceableSignatureComputationData signatureComputationData =
CalypsoExtensionService.getInstance()
.createTraceableSignatureComputationData();
cardTransactionManager.prepareComputeSignature(signatureComputationData);
- 3.+
TraceableSignatureComputationData signatureComputationData =
LegacySamExtensionService.getInstance()
.getLegacySamApiFactory().createTraceableSignatureComputationData();
cardTransactionManager.getCryptoExtension(CardTransactionLegacySamExtension.class)
.prepareComputeSignature(signatureComputationData);
SAM resource service
- 2.+
CardResourceProfileExtension samResourceProfileExtension =
CalypsoExtensionService.getInstance()
.createSamResourceProfileExtension(
CalypsoExtensionService.getInstance()
.createSamSelection()
.filterByProductType(CalypsoSam.ProductType.SAM_C1));
- 3.+
CardResourceProfileExtension samResourceProfileExtension =
LegacySamExtensionService.getInstance()
.createLegacySamResourceProfileExtension(
LegacySamExtensionService.getInstance()
.getLegacySamApiFactory()
.createLegacySamSelectionExtension(),
LegacySamUtil.buildPowerOnDataFilter(LegacySam.ProductType.SAM_C1, null));
Miscellaneous
Contact reader payload capacity management
- 2.+
ContextSetting contextSetting =
CalypsoExtensionService.getInstance().getContextSetting().setContactReaderPayloadCapacity(...);
- 3.+
ContextSetting contextSetting =
LegacySamExtensionService.getInstance().getContextSetting().setContactReaderPayloadCapacity(...);
Upgrade from “1.+” to “2.+”
Here is a comparative review of the main API changes between Keyple 1.+ and 2.+:
Dependency management
Use the configuration wizard to correctly import the new artifacts into your project.
Initial configuration
Use of a provider to access the smart card service
- 1.+
SmartCardService smartCardService = SmartCardService.getInstance();
- 2.+
SmartCardService smartCardService = SmartCardServiceProvider.getService();
Use of builders to instantiate plugin factories
- 1.+
Plugin plugin = smartCardService.registerPlugin(new PcscPluginFactory(null, new ExceptionHandlerImpl()));
...
((ObservableReader) reader).addObserver(new CardReaderObserver());
- 2.+
Plugin plugin = smartCardService.registerPlugin(PcscPluginFactoryBuilder.builder().build());
...
((ObservableCardReader) reader).setReaderObservationExceptionHandler(new ExceptionHandlerImpl());
((ObservableCardReader) reader).addObserver(new CardReaderObserver());
Use of a new interface dedicated to the management of protocols
- 1.+
reader.activateProtocol(
PcscSupportedContactlessProtocols.ISO_14443_4.name(),
ContactlessCardCommonProtocols.ISO_14443_4.name());
- 2.+
((ConfigurableCardReader) reader).activateProtocol(
PcscSupportedContactlessProtocols.ISO_14443_4.name(),
CARD_ISO_14443_4);
Use of plugin and reader extensions for specific configurations
- 1.+
reader
.setContactless(true)
.setIsoProtocol(PcscReader.IsoProtocol.T1);
- 2.+
plugin.getReaderExtension(PcscReader.class, reader.getName())
.setContactless(true)
.setIsoProtocol(PcscReader.IsoProtocol.T1);
Card selection
Use a manager instead of service for card selection
- 1.+
CardSelectionsService cardSelectionsService = new CardSelectionsService();
- 2.+
CardSelectionManager cardSelectionManager = smartCardService.createCardSelectionManager();
Use of a card extension to create a card selection
- 1.+
GenericCardSelectionRequest genericCardSelectionRequest =
new GenericCardSelectionRequest(
CardSelector.builder()
.aidSelector(CardSelector.AidSelector.builder().aidToSelect(cardAid).build())
.build());
- 2.+
CardSelection cardSelection = GenericExtensionService.getInstance()
.createCardSelection()
.filterByDfName(cardAid);
- The
CardSelector
class does not exist anymore. - A generic card extension is now available.
- The card extension service is used to configure the card selection.
Explicit card selection
- 1.+
CardSelectionsResult selectionResult = cardSelectionsService.processExplicitSelections(reader);
- 2.+
CardSelectionResult selectionResult = cardSelectionManager.processCardSelectionScenario(reader);
CardSelectionResult
.Scheduled card selection
- 1.+
((ObservableReader) reader)
.setDefaultSelectionRequest(
defaultSelectionsRequest,
ObservableReader.NotificationMode.MATCHED_ONLY,
ObservableReader.PollingMode.REPEATING);
((ObservableReader) reader).addObserver(new CardReaderObserver());
- 2.+
cardSelectionManager.scheduleCardSelectionScenario(
(ObservableCardReader) reader,
ObservableCardReader.DetectionMode.REPEATING,
ObservableCardReader.NotificationMode.MATCHED_ONLY);
((ObservableCardReader) reader).setReaderObservationExceptionHandler(new ExceptionHandlerImpl());
((ObservableCardReader) reader).addObserver(new CardReaderObserver());
The processing of the result of the selection response has changed
- 1.+
AbstractSmartCard smartCard =
defaultSelection
.processDefaultSelectionsResponse(event.getDefaultSelectionsResponse())
.getActiveSmartCard();
- 2.+
SmartCard smartCard =
cardSelectionManager
.parseScheduledCardSelectionsResponse(event.getScheduledCardSelectionsResponse())
.getActiveSmartCard();
AbstractSmartCard
was changed to the SmartCard
interface.Calypso Card Extension
Vocabulary
PO
has been replaced byCard
.
SAM management
The SAM resource manager has been replaced by a generic Card Resource Service.
Card transaction
Access to the card transaction manager has changed. It is now done through the card extension service.
- 1.+
PoTransaction poTransaction =
new PoTransaction(
new CardResource<CalypsoPo>(poReader, calypsoPo),
CalypsoUtils.getSecuritySettings(samResource));
- 2.+
CardTransactionManager transactionManager = CalypsoExtensionService.getInstance()
.createCardTransaction(cardReader, calypsoCard, cardSecuritySetting);
Distributed systems
Remote plugin registration
- 1.+
// Init the remote plugin factory.
RemotePluginServerFactory factory =
RemotePluginServerFactory.builder()
.withDefaultPluginName()
.withSyncNode()
.withPluginObserver(new RemotePluginServerObserver())
.usingEventNotificationPool(
Executors.newCachedThreadPool(r -> new Thread(r, "server-pool")))
.build();
// Register the remote plugin to the smart card service using the factory.
SmartCardService.getInstance().registerPlugin(factory);
- 2.+
RemotePluginServerFactory factory =
RemotePluginServerFactoryBuilder.builder(REMOTE_PLUGIN_NAME)
.withSyncNode()
.build();
// Register the remote plugin to the smart card service using the factory.
ObservablePlugin plugin =
(ObservablePlugin) SmartCardServiceProvider.getService().registerPlugin(factory);
// Init the remote plugin observer.
plugin.setPluginObservationExceptionHandler(new ExceptionHandlerImpl());
plugin.addObserver(new RemotePluginServerObserver());
- You have to specify the name of the plugin.
- It is no longer necessary to provide a thread pool.
- The exception handler must be provided as for any observable plugin before adding an observer.
Local service registration
- 1.+
// Init the local service using the associated factory.
LocalServiceClientFactory.builder()
.withDefaultServiceName()
.withSyncNode(endpointClient)
.withoutReaderObservation()
.getService();
- 2.+
// Init the local service factory.
LocalServiceClientFactory factory =
LocalServiceClientFactoryBuilder.builder(LOCAL_SERVICE_NAME)
.withSyncNode(endpointClient)
.build();
// Init the local service using the associated factory.
SmartCardServiceProvider.getService().registerDistributedLocalService(factory);
- You have to specify the name of the local service.
- The local service must be registered with the smart card service.
- It behaves like a plugin or reader and also provides an extension to access specific settings.