Skip to content
This repository was archived by the owner on Jun 10, 2025. It is now read-only.

Commit 823b20f

Browse files
feat: simplify the transaction API by using a unique "process" method (#52)
Co-authored-by: Jean-Pierre Fortune <[email protected]>
1 parent bf02416 commit 823b20f

File tree

7 files changed

+268
-27
lines changed

7 files changed

+268
-27
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Added
9+
- `CommonTransactionManager.processCommands(boolean)` method.
10+
- `CardTransactionManager.prepareVerifyPin` method.
11+
- `CardTransactionManager.prepareChangePin` method.
12+
- `CardTransactionManager.prepareChangeKey` method.
13+
- `CardTransactionManager.prepareOpenSecureSession` method.
14+
- `CardTransactionManager.prepareCloseSecureSession` method.
15+
- `CardTransactionManager.prepareCancelSecureSession` method.
16+
- `CardSecuritySetting.disableReadOnSessionOpening` method.
17+
### Deprecated
18+
- `CommonTransactionManager.processCommands()` method.
19+
- `CardTransactionManager.prepareReleaseCardChannel` method.
20+
- `CardTransactionManager.processVerifyPin` method.
21+
- `CardTransactionManager.processChangePin` method.
22+
- `CardTransactionManager.processChangeKey` method.
23+
- `CardTransactionManager.processOpening` method.
24+
- `CardTransactionManager.processClosing` method.
25+
- `CardTransactionManager.processCancel` method.
826

927
## [1.5.0] - 2022-12-22
1028
### Added

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
group = org.calypsonet.terminal
22
title = Calypsonet Terminal Calypso API
33
description = API defining the needed interfaces to manage Calypso cards
4-
version = 1.5.1
4+
version = 1.6.0
55

66
javaSourceLevel = 1.6
77
javaTargetLevel = 1.6

src/main/java/org/calypsonet/terminal/calypso/CalypsoApiProperties.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class CalypsoApiProperties {
2323
*
2424
* @since 1.0.0
2525
*/
26-
public static final String VERSION = "1.5";
26+
public static final String VERSION = "1.6";
2727

2828
/** Private constructor */
2929
private CalypsoApiProperties() {}

src/main/java/org/calypsonet/terminal/calypso/card/CalypsoCardSelection.java

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,22 @@ public interface CalypsoCardSelection extends CardSelection {
190190
*/
191191
CalypsoCardSelection prepareSelectFile(SelectFileControl selectControl);
192192

193+
/**
194+
* Adds a command APDU to retrieve the data indicated by the provided tag.
195+
*
196+
* <p>This method can be used to obtain FCI information when it is not provided directly by the
197+
* select application (e.g. OMAPI case).
198+
*
199+
* <p>Caution: the resulting APDU command must be compliant with PRIME revision 3 cards.
200+
* Therefore, the command may be rejected by some earlier revision cards.
201+
*
202+
* @param tag The tag to use.
203+
* @return The object instance.
204+
* @throws IllegalArgumentException If tag is null.
205+
* @since 1.0.0
206+
*/
207+
CalypsoCardSelection prepareGetData(GetDataTag tag);
208+
193209
/**
194210
* Adds a command APDU to read a single record from the indicated EF.
195211
*
@@ -226,21 +242,40 @@ public interface CalypsoCardSelection extends CardSelection {
226242
*/
227243
CalypsoCardSelection prepareReadRecord(byte sfi, int recordNumber);
228244

229-
/**
230-
* Adds a command APDU to retrieve the data indicated by the provided tag.
231-
*
232-
* <p>This method can be used to obtain FCI information when it is not provided directly by the
233-
* select application (e.g. OMAPI case).
234-
*
235-
* <p>Caution: the resulting APDU command must be compliant with PRIME revision 3 cards.
236-
* Therefore, the command may be rejected by some earlier revision cards.
237-
*
238-
* @param tag The tag to use.
239-
* @return The object instance.
240-
* @throws IllegalArgumentException If tag is null.
241-
* @since 1.0.0
242-
*/
243-
CalypsoCardSelection prepareGetData(GetDataTag tag);
245+
// /**
246+
// * Adds an APDU command to attempt a secure session pre-opening. For cards that support this
247+
// * feature, this optimizes exchanges with the card in the case of deterministic secure
248+
// sessions
249+
// * that can be executed in a single step.
250+
// *
251+
// * <p>The use of this method or one of the following methods is a prerequisite for the use of
252+
// the
253+
// * {@link CardTransactionManager#processPreOpenedSecureSession()} method:
254+
// *
255+
// * <ul>
256+
// * <li>{@link #preparePreOpenSecureSession(WriteAccessLevel, byte, int)}
257+
// * <li>{@link CardTransactionManager#preparePreOpenSecureSession(WriteAccessLevel)}
258+
// * <li>{@link CardTransactionManager#preparePreOpenSecureSession(WriteAccessLevel, byte,
259+
// int)}
260+
// * </ul>
261+
// *
262+
// * It is not advised to use it in other cases.
263+
// *
264+
// * <p>The secure session opening which will be done by {@link
265+
// * CardTransactionManager#processPreOpenedSecureSession()} will use the same parameters (same
266+
// * {@link WriteAccessLevel}, no record reading).
267+
// *
268+
// * @param writeAccessLevel The write access level.
269+
// * @return The object instance.
270+
// * @throws IllegalArgumentException If writeAccessLevel is null.
271+
// * @throws IllegalStateException If "Pre-Open" command is already prepared.
272+
// * @see #preparePreOpenSecureSession(WriteAccessLevel, byte, int)
273+
// * @see CardTransactionManager#preparePreOpenSecureSession(WriteAccessLevel)
274+
// * @see CardTransactionManager#preparePreOpenSecureSession(WriteAccessLevel, byte, int)
275+
// * @see CardTransactionManager#processPreOpenedSecureSession()
276+
// * @since 1.6.0
277+
// */
278+
// CalypsoCardSelection preparePreOpenSecureSession(WriteAccessLevel writeAccessLevel);
244279

245280
/**
246281
* Navigation options through the different applications contained in the card according to the

src/main/java/org/calypsonet/terminal/calypso/transaction/CardSecuritySetting.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,20 @@ public interface CardSecuritySetting extends CommonSecuritySetting<CardSecurityS
8484
*/
8585
CardSecuritySetting authorizeSvNegativeBalance();
8686

87+
/**
88+
* Disables the automatic merging of the "Open Secure Session" command with a possible "Read
89+
* Record" command.
90+
*
91+
* <p>By default, this optimization is performed when the command that follows the session opening
92+
* is a "Read Record" command.
93+
*
94+
* <p>This mechanism may in some cases be incompatible with the security requirements.
95+
*
96+
* @return The current instance.
97+
* @since 1.6.0
98+
*/
99+
CardSecuritySetting disableReadOnSessionOpening();
100+
87101
/**
88102
* Defines for a given write access level the KIF value to use for cards that only provide KVC.
89103
*

src/main/java/org/calypsonet/terminal/calypso/transaction/CardTransactionManager.java

Lines changed: 145 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,9 @@ CardTransactionManager prepareDecreaseCounters(
890890
*
891891
* @return The current instance.
892892
* @since 1.0.0
893+
* @deprecated Use {@link #processCommands(boolean)} method instead.
893894
*/
895+
@Deprecated
894896
CardTransactionManager prepareReleaseCardChannel();
895897

896898
/**
@@ -1030,9 +1032,33 @@ CardTransactionManager prepareDecreaseCounters(
10301032
* @throws UnexpectedCommandStatusException If a command returns an unexpected status.
10311033
* @throws InconsistentDataException If inconsistent data have been detected.
10321034
* @since 1.0.0
1035+
* @deprecated Use {@link #prepareVerifyPin(byte[])} method instead.
10331036
*/
1037+
@Deprecated
10341038
CardTransactionManager processVerifyPin(byte[] pin);
10351039

1040+
/**
1041+
* Schedules the execution of a PIN verification command in order to authenticate the cardholder
1042+
* and/or unlock access to certain card files.
1043+
*
1044+
* <p>This command can be performed both in and out of a secure session. The PIN code can be
1045+
* transmitted in plain text or encrypted according to the parameter set in {@link
1046+
* CardSecuritySetting}. By default, the transmission is encrypted.
1047+
*
1048+
* <p>If the execution is done out of session but an encrypted transmission is requested, then
1049+
* CardTransactionManager must be constructed with {@link CardSecuritySetting}.
1050+
*
1051+
* <p>If CardTransactionManager is constructed without {@link CardSecuritySetting} the
1052+
* transmission in done in plain.
1053+
*
1054+
* @param pin The PIN code value (4-byte long byte array).
1055+
* @return The current instance.
1056+
* @throws UnsupportedOperationException If the PIN feature is not available for this card.
1057+
* @throws IllegalArgumentException If the provided argument is out of range.
1058+
* @since 1.6.0
1059+
*/
1060+
CardTransactionManager prepareVerifyPin(byte[] pin);
1061+
10361062
/**
10371063
* Replaces the current PIN with the new value provided.
10381064
*
@@ -1054,9 +1080,31 @@ CardTransactionManager prepareDecreaseCounters(
10541080
* @throws UnexpectedCommandStatusException If a command returns an unexpected status.
10551081
* @throws InconsistentDataException If inconsistent data have been detected.
10561082
* @since 1.0.0
1083+
* @deprecated Use {@link #prepareChangePin(byte[])} method instead.
10571084
*/
1085+
@Deprecated
10581086
CardTransactionManager processChangePin(byte[] newPin);
10591087

1088+
/**
1089+
* Schedules the execution of a PIN modification command to replace the current PIN with the new
1090+
* value provided.
1091+
*
1092+
* <p>This command can be performed only out of a secure session. The new PIN code can be
1093+
* transmitted in plain text or encrypted according to the parameter set in {@link
1094+
* CardSecuritySetting}. By default, the transmission is encrypted.
1095+
*
1096+
* <p>When the PIN is transmitted plain, this command must be preceded by a successful Verify PIN
1097+
* command (see {@link #prepareVerifyPin(byte[])}).
1098+
*
1099+
* @param newPin The new PIN code value (4-byte long byte array).
1100+
* @return The current instance.
1101+
* @throws UnsupportedOperationException If the PIN feature is not available for this card.
1102+
* @throws IllegalArgumentException If the provided argument is out of range.
1103+
* @throws IllegalStateException If the command is executed while a secure session is open.
1104+
* @since 1.6.0
1105+
*/
1106+
CardTransactionManager prepareChangePin(byte[] newPin);
1107+
10601108
/**
10611109
* Replaces one of the current card keys with another key present in the SAM.
10621110
*
@@ -1082,20 +1130,49 @@ CardTransactionManager prepareDecreaseCounters(
10821130
* @throws UnexpectedCommandStatusException If a command returns an unexpected status.
10831131
* @throws InconsistentDataException If inconsistent data have been detected.
10841132
* @since 1.1.0
1133+
* @deprecated Use {@link #prepareChangeKey(int, byte, byte, byte, byte)} method instead.
10851134
*/
1135+
@Deprecated
10861136
CardTransactionManager processChangeKey(
10871137
int keyIndex, byte newKif, byte newKvc, byte issuerKif, byte issuerKvc);
10881138

1139+
/**
1140+
* Schedules the execution of a key loading command to replace one of the current card keys with
1141+
* another key present in the SAM.
1142+
*
1143+
* <p>This command can be performed only out of a secure session.
1144+
*
1145+
* <p>The change key process transfers the key from the SAM to the card. The new key is
1146+
* diversified by the SAM from a primary key and encrypted using the indicated issuer key to
1147+
* secure the transfer to the card. All provided KIFs and KVCs must be present in the SAM.
1148+
*
1149+
* @param keyIndex The index of the key to be replaced (1 for the issuer key, 2 for the load key,
1150+
* 3 for the debit key).
1151+
* @param newKif The KIF of the new key.
1152+
* @param newKvc The KVC of the new key.
1153+
* @param issuerKif The KIF of the current card's issuer key.
1154+
* @param issuerKvc The KVC of the current card's issuer key.
1155+
* @return The current instance.
1156+
* @throws UnsupportedOperationException If the Change Key command is not available for this card.
1157+
* @throws IllegalArgumentException If the provided key index is out of range.
1158+
* @throws IllegalStateException If the command is executed while a secure session is open.
1159+
* @since 1.6.0
1160+
*/
1161+
CardTransactionManager prepareChangeKey(
1162+
int keyIndex, byte newKif, byte newKvc, byte issuerKif, byte issuerKvc);
1163+
10891164
/**
10901165
* Opens a Calypso Secure Session and then executes all previously prepared commands.
10911166
*
10921167
* <p>It is the starting point of the sequence:
10931168
*
10941169
* <ul>
10951170
* <li>{@code processOpening(WriteAccessLevel)}
1096-
* <li>[{@link #processCardCommands()}]
10971171
* <li>[...]
1098-
* <li>[{@link #processCardCommands()}]
1172+
* <li>[{@link #processCommands()}]
1173+
* <li>[...]
1174+
* <li>[{@link #processCommands()}]
1175+
* <li>[...]
10991176
* <li>{@link #processClosing()}
11001177
* </ul>
11011178
*
@@ -1142,14 +1219,6 @@ CardTransactionManager processChangeKey(
11421219
* <li>Receiving grouped responses and updating {@link CalypsoCard} with the collected data.
11431220
* </ul>
11441221
*
1145-
* For optimization purposes, if the first command prepared is the reading of a single record of a
1146-
* card file then this one is replaced by a setting of the session opening command allowing the
1147-
* retrieval of this data in response to this command.
1148-
*
1149-
* <p>Please note that the CAAD mechanism may require a file to be read before being modified. For
1150-
* this mechanism to work properly, this reading must not be placed in the first position of the
1151-
* prepared commands in order to be correctly taken into account by the SAM.
1152-
*
11531222
* <p><b>Other operations carried out</b>
11541223
*
11551224
* <ul>
@@ -1191,9 +1260,40 @@ CardTransactionManager processChangeKey(
11911260
* @throws SelectFileException If a "Select File" prepared card command indicated that the file
11921261
* was not found.
11931262
* @since 1.0.0
1263+
* @deprecated Use {@link #prepareOpenSecureSession(WriteAccessLevel)} method instead.
11941264
*/
1265+
@Deprecated
11951266
CardTransactionManager processOpening(WriteAccessLevel writeAccessLevel);
11961267

1268+
/**
1269+
* Schedules the execution of a secure session opening command.
1270+
*
1271+
* <p>This feature is only available for a transaction initialized in secure mode.
1272+
*
1273+
* <p>The secure session will be opened with the provided {@link WriteAccessLevel} depending on
1274+
* whether it is a personalization, reload or debit transaction profile.
1275+
*
1276+
* <p>Note that if the next prepared command is a "Read One Record" or "Read One Or More
1277+
* Counters", then it will by default be merged with the "Open Secure Session" command for
1278+
* optimization purposes.
1279+
*
1280+
* <p>This mechanism may in some cases be incompatible with the security constraints and can be
1281+
* disabled via the {@link CardSecuritySetting#disableReadOnSessionOpening()} method.
1282+
*
1283+
* @param writeAccessLevel The write access level to be used.
1284+
* @return The current instance.
1285+
* @throws IllegalArgumentException If the provided argument is null.
1286+
* @throws IllegalStateException In the following cases:
1287+
* <ul>
1288+
* <li>No {@link CardSecuritySetting} is available
1289+
* <li>A secure session opening is already prepared
1290+
* <li>A secure session is already opened
1291+
* </ul>
1292+
*
1293+
* @since 1.6.0
1294+
*/
1295+
CardTransactionManager prepareOpenSecureSession(WriteAccessLevel writeAccessLevel);
1296+
11971297
/**
11981298
* Terminates the Secure Session sequence started with {@link #processOpening(WriteAccessLevel)}.
11991299
*
@@ -1257,9 +1357,32 @@ CardTransactionManager processChangeKey(
12571357
* @throws InvalidCardSignatureException If session is correctly closed but the card signature is
12581358
* incorrect.
12591359
* @since 1.0.0
1360+
* @deprecated Use {@link #prepareCloseSecureSession()} method instead.
12601361
*/
1362+
@Deprecated
12611363
CardTransactionManager processClosing();
12621364

1365+
/**
1366+
* Schedules the execution of a secure session closing command.
1367+
*
1368+
* <p>The ratification mechanism is disabled by default but can be enabled via the {@link
1369+
* CardSecuritySetting#enableRatificationMechanism()} method.
1370+
*
1371+
* <p>In this case, a ratification command is added after the "Close Secure Session" command when
1372+
* the communication is done in contactless mode.
1373+
*
1374+
* @return The current instance.
1375+
* @throws IllegalStateException In the following cases:
1376+
* <ul>
1377+
* <li>No secure session is opened and no secure session opening is prepared
1378+
* <li>A secure session closing is already prepared
1379+
* <li>A secure session canceling is prepared
1380+
* </ul>
1381+
*
1382+
* @since 1.6.0
1383+
*/
1384+
CardTransactionManager prepareCloseSecureSession();
1385+
12631386
/**
12641387
* Aborts a Secure Session.
12651388
*
@@ -1273,6 +1396,18 @@ CardTransactionManager processChangeKey(
12731396
* @throws CardIOException If a communication error with the card occurs.
12741397
* @throws UnexpectedCommandStatusException If the command returns an unexpected status.
12751398
* @since 1.0.0
1399+
* @deprecated Use {@link #prepareCancelSecureSession()} method instead.
12761400
*/
1401+
@Deprecated
12771402
CardTransactionManager processCancel();
1403+
1404+
/**
1405+
* Schedules the execution of a secure session canceling command.
1406+
*
1407+
* <p>This command will be executed in safe mode and will not raise any exceptions.
1408+
*
1409+
* @return The current instance.
1410+
* @since 1.6.0
1411+
*/
1412+
CardTransactionManager prepareCancelSecureSession();
12781413
}

0 commit comments

Comments
 (0)