Skip to content

Commit 0c942d4

Browse files
authored
Add files via upload
Adding the function of getting information about the device
1 parent b62a216 commit 0c942d4

14 files changed

+1614
-143
lines changed

src/main/java/pl/mlodawski/security/example/PKCS11Example.java

Lines changed: 213 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,236 @@
11
package pl.mlodawski.security.example;
22

33
import pl.mlodawski.security.pkcs11.*;
4-
import pl.mlodawski.security.pkcs11.model.SupportedAlgorithm;
5-
import pl.mlodawski.security.pkcs11.model.KeyCertificatePair;
6-
import pl.mlodawski.security.pkcs11.model.CertificateInfo;
4+
import pl.mlodawski.security.pkcs11.model.*;
75

86
import java.nio.file.Path;
97
import java.nio.file.Paths;
108
import java.util.List;
119
import java.util.Base64;
10+
import java.util.Map;
1211
import java.util.Scanner;
1312

1413
class PKCS11 {
15-
1614
private final Path PKCS11_WRAPPER_PATH;
17-
private final String PIN;
18-
PKCS11Utils utils = new PKCS11Utils();
15+
private String PIN;
16+
private final PKCS11Utils utils = new PKCS11Utils();
17+
private PKCS11Device selectedDevice;
1918

20-
public PKCS11(Path pkcs11WrapperPath, String pin) {
19+
public PKCS11(Path pkcs11WrapperPath) {
2120
this.PKCS11_WRAPPER_PATH = pkcs11WrapperPath;
22-
this.PIN = pin;
2321
}
2422

2523
public void run() {
26-
PKCS11Manager manager = new PKCS11Manager(PKCS11_WRAPPER_PATH, PIN);
24+
try (PKCS11Manager manager = new PKCS11Manager(PKCS11_WRAPPER_PATH)) {
25+
manager.registerDeviceChangeListener(new DeviceChangeListener() {
26+
@Override
27+
public void onDeviceConnected(PKCS11Device device) {
28+
System.out.println("\nNew device connected: " + device.getLabel());
29+
}
30+
31+
@Override
32+
public void onDeviceDisconnected(PKCS11Device device) {
33+
System.out.println("\nDevice disconnected: " + device.getLabel());
34+
if (device.equals(selectedDevice)) {
35+
selectedDevice = null;
36+
System.out.println("Selected device was disconnected. Please select a new device.");
37+
}
38+
}
39+
40+
@Override
41+
public void onDeviceStateChanged(PKCS11Device device, DeviceState oldState) {
42+
System.out.printf("\nDevice %s state changed from %s to %s%n",
43+
device.getLabel(), oldState, device.getState());
44+
}
45+
46+
@Override
47+
public void onDeviceError(PKCS11Device device, Exception error) {
48+
System.out.printf("\nError occurred with device %s: %s%n",
49+
device.getLabel(), error.getMessage());
50+
}
51+
});
2752

28-
try (PKCS11Session session = manager.openSession(0)) {
2953
while (true) {
3054
try {
31-
displayMenu();
32-
int choice = getUserChoice();
33-
34-
switch (choice) {
35-
case 1:
36-
listCertificates(manager, session);
37-
break;
38-
case 2:
39-
signMessage(manager, session);
40-
break;
41-
case 3:
42-
encryptDecryptData(manager, session);
43-
break;
44-
case 4:
45-
listSupportedAlgorithms(manager, session);
46-
break;
47-
case 5:
48-
System.out.println("Exiting...");
49-
return;
50-
default:
51-
System.out.println("Invalid choice. Please try again.");
55+
if (selectedDevice == null || !selectedDevice.isReady()) {
56+
if (!selectDevice(manager)) {
57+
System.out.println("No devices available. Please connect a device and try again.");
58+
Thread.sleep(2000);
59+
continue;
60+
}
61+
if (!getPINFromUser()) {
62+
continue;
63+
}
64+
}
65+
66+
try (PKCS11Session session = manager.openSession(selectedDevice, PIN)) {
67+
while (selectedDevice != null && selectedDevice.isReady()) {
68+
displayMenu();
69+
int choice = getUserChoice();
70+
71+
switch (choice) {
72+
case 1:
73+
listCertificates(manager, session);
74+
break;
75+
case 2:
76+
signMessage(manager, session);
77+
break;
78+
case 3:
79+
encryptDecryptData(manager, session);
80+
break;
81+
case 4:
82+
listSupportedAlgorithms(manager, session);
83+
break;
84+
case 5:
85+
selectedDevice = null;
86+
return;
87+
case 6:
88+
session.close();
89+
selectedDevice = null;
90+
PIN = null;
91+
if (!handleDeviceChange(manager)) {
92+
System.out.println("Returning to main menu...");
93+
}
94+
break;
95+
default:
96+
System.out.println("Invalid choice. Please try again.");
97+
}
98+
99+
if (choice == 6) {
100+
break;
101+
}
102+
}
103+
} catch (Exception e) {
104+
System.out.println("Session error: " + e.getMessage());
105+
selectedDevice = null;
106+
PIN = null; // Czyścimy PIN w przypadku błędu sesji
52107
}
53108
} catch (Exception e) {
54109
System.out.println("An error occurred: " + e.getMessage());
55-
} finally {
56-
session.resetSession();
110+
Thread.sleep(1000);
57111
}
58112
}
59113
} catch (Exception e) {
60-
throw new RuntimeException(e);
114+
throw new RuntimeException("Fatal error: " + e.getMessage(), e);
115+
}
116+
}
117+
118+
119+
private boolean handleDeviceChange(PKCS11Manager manager) {
120+
int maxRetries = 3;
121+
int retryCount = 0;
122+
123+
while (retryCount < maxRetries) {
124+
try {
125+
manager.prepareForDeviceChange();
126+
System.out.println("Device selection refreshed. Please select a new device.");
127+
128+
if (!selectDevice(manager)) {
129+
retryCount++;
130+
continue;
131+
}
132+
133+
// Dodajemy wymuszenie podania PIN-u po zmianie urządzenia
134+
if (!getPINFromUser()) {
135+
retryCount++;
136+
continue;
137+
}
138+
139+
return true;
140+
} catch (Exception e) {
141+
System.err.println("Error during device change"+ e);
142+
retryCount++;
143+
if (retryCount < maxRetries) {
144+
System.out.println("Error occurred, retrying... (" + (maxRetries - retryCount) + " attempts remaining)");
145+
try {
146+
Thread.sleep(1000);
147+
} catch (InterruptedException ie) {
148+
Thread.currentThread().interrupt();
149+
return false;
150+
}
151+
}
152+
}
61153
}
154+
155+
System.out.println("Failed to change device after " + maxRetries + " attempts.");
156+
return false;
157+
}
158+
159+
private boolean selectDevice(PKCS11Manager manager) {
160+
List<PKCS11Device> devices = manager.listDevices();
161+
if (devices.isEmpty()) {
162+
return false;
163+
}
164+
165+
System.out.println("\n--- Available Devices ---");
166+
for (int i = 0; i < devices.size(); i++) {
167+
PKCS11Device device = devices.get(i);
168+
System.out.printf("%d: %s (Manufacturer: %s, Model: %s, Serial: %s)%n",
169+
i + 1,
170+
device.getLabel(),
171+
device.getManufacturer(),
172+
device.getModel(),
173+
device.getSerialNumber());
174+
175+
Map<String, String> info = device.getDetailedInfo();
176+
System.out.printf(" State: %s%n", device.getState());
177+
System.out.printf(" Rest of the information about key: %s", info.toString());
178+
System.out.println();
179+
}
180+
181+
System.out.print("Select device (1-" + devices.size() + "): ");
182+
int choice = getUserChoice();
183+
184+
if (choice < 1 || choice > devices.size()) {
185+
System.out.println("Invalid device selection.");
186+
return false;
187+
}
188+
189+
selectedDevice = devices.get(choice - 1);
190+
if (!selectedDevice.isReady()) {
191+
System.out.println("Selected device is not ready. State: " + selectedDevice.getState());
192+
selectedDevice = null;
193+
return false;
194+
}
195+
196+
return true;
197+
}
198+
199+
private boolean getPINFromUser() {
200+
if (selectedDevice == null) {
201+
return false;
202+
}
203+
204+
Map<String, Long> pinRequirements = selectedDevice.getPinLengthRequirements();
205+
System.out.print("Enter PIN for " + selectedDevice.getLabel() + ": ");
206+
Scanner scanner = new Scanner(System.in);
207+
PIN = scanner.nextLine();
208+
209+
if (PIN.length() < pinRequirements.get("minLength") ||
210+
PIN.length() > pinRequirements.get("maxLength")) {
211+
System.out.printf("Invalid PIN length. Must be between %d and %d characters.%n",
212+
pinRequirements.get("minLength"),
213+
pinRequirements.get("maxLength"));
214+
PIN = null;
215+
return false;
216+
}
217+
218+
return true;
62219
}
63220

64221
private void displayMenu() {
65222
System.out.println("\n--- PKCS#11 Operations Menu ---");
223+
System.out.println("Current device: " + selectedDevice.getLabel());
66224
System.out.println("1. List Available Certificates");
67225
System.out.println("2. Sign a Message");
68226
System.out.println("3. Encrypt and Decrypt Data");
69227
System.out.println("4. List Supported Algorithms");
70228
System.out.println("5. Exit");
229+
System.out.println("6. Change Device");
71230
System.out.print("Enter your choice: ");
72231
}
73232

233+
74234
private int getUserChoice() {
75235
Scanner scanner = new Scanner(System.in);
76236
return scanner.nextInt();
@@ -157,10 +317,24 @@ private void encryptDecryptData(PKCS11Manager manager, PKCS11Session session) {
157317
}
158318

159319
private void listSupportedAlgorithms(PKCS11Manager manager, PKCS11Session session) {
160-
List<SupportedAlgorithm> algorithms = utils.listSupportedAlgorithms(manager.getPkcs11(), session.getSession(), 0);
161-
System.out.println("\nSupported algorithms:");
162-
for (SupportedAlgorithm algo : algorithms) {
163-
System.out.println(algo);
320+
try {
321+
List<SupportedAlgorithm> algorithms = utils.listSupportedAlgorithms(
322+
manager.getPkcs11(),
323+
session.getSession(),
324+
selectedDevice.getSlotId().intValue()
325+
);
326+
327+
if (algorithms.isEmpty()) {
328+
System.out.println("\nNo supported algorithms found for this device.");
329+
return;
330+
}
331+
332+
System.out.println("\nSupported algorithms:");
333+
for (SupportedAlgorithm algo : algorithms) {
334+
System.out.println(algo);
335+
}
336+
} catch (Exception e) {
337+
System.out.println("Error listing algorithms: " + e.getMessage());
164338
}
165339
}
166340
}
@@ -169,8 +343,7 @@ public class PKCS11Example {
169343
public static void main(String[] args) {
170344
String userDir = System.getProperty("user.dir");
171345
PKCS11 example = new PKCS11(
172-
Paths.get(userDir, "lib", "opensc-pkcs11.dll"),
173-
"123456"
346+
Paths.get(userDir, "lib", "opensc-pkcs11.dll")
174347
);
175348
example.run();
176349
}

0 commit comments

Comments
 (0)