Skip to content

Commit

Permalink
Merge pull request #342 from solver-it-sro/support-different-pins
Browse files Browse the repository at this point in the history
Support different PINs, forced batch signing and live settings updates
  • Loading branch information
jsuchal authored Nov 30, 2023
2 parents df600b5 + 0cd189b commit ec54852
Show file tree
Hide file tree
Showing 33 changed files with 698 additions and 510 deletions.
49 changes: 22 additions & 27 deletions src/main/java/digital/slovensko/autogram/core/Autogram.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,15 @@

public class Autogram {
private final UI ui;
private final UserSettings settings;
/** Current batch, should be null if no batch was started yet */
private Batch batch = null;
private final DriverDetector driverDetector;
private final boolean shouldDisplayVisualizationError;
private final Integer slotId;
private final TSPSource tspSource;
private final PasswordManager passwordManager;

public Autogram(UI ui, boolean shouldDisplayVisualizationError , DriverDetector driverDetector, TSPSource tspSource) {
this(ui, shouldDisplayVisualizationError, driverDetector, -1, tspSource);
}

public Autogram(UI ui, boolean shouldDisplayVisualizationError , DriverDetector driverDetector, Integer slotId, TSPSource tspSource) {
public Autogram(UI ui, UserSettings settings) {
this.ui = ui;
this.driverDetector = driverDetector;
this.slotId = slotId;
this.shouldDisplayVisualizationError = shouldDisplayVisualizationError;
this.tspSource = tspSource;
this.settings = settings;
this.passwordManager = new PasswordManager(ui, this.settings);
}

public void sign(SigningJob job) {
Expand Down Expand Up @@ -87,7 +79,7 @@ public void startVisualization(SigningJob job) {
} catch (Exception e) {
Runnable onContinue = () -> ui.showVisualization(new UnsupportedVisualization(job), this);

if (shouldDisplayVisualizationError) {
if (settings.isCorrectDocumentDisplay()) {
ui.onUIThreadDo(
() -> ui.showIgnorableExceptionDialog(new FailedVisualizationException(e, job, onContinue)));
} else {
Expand All @@ -101,9 +93,12 @@ public void sign(SigningJob job, SigningKey signingKey) {
ui.onWorkThreadDo(() -> {
try {
job.signWithKeyAndRespond(signingKey);
if (batch == null || batch.isEnded()) passwordManager.reset();
ui.onUIThreadDo(() -> ui.onSigningSuccess(job));
} catch (ResponseNetworkErrorException e) {
onSigningFailed(e, job);
} catch (PINIncorrectException e) {
passwordManager.reset();
} catch (AutogramException e) {
onSigningFailed(e);
} catch (DSSException e) {
Expand Down Expand Up @@ -148,7 +143,7 @@ public void batchSign(SigningJob job, String batchId) {
ui.onWorkThreadDo(() -> {
try {
ui.signBatch(job, batch.getSigningKey());
} catch (KeyPinDifferentFromTokenPinException e) {
} catch (PINIncorrectException e) {
ui.onUIThreadDo(() -> {
ui.cancelBatch(batch);
});
Expand Down Expand Up @@ -179,23 +174,23 @@ public Batch getBatch(String batchId) {
}

public void pickSigningKeyAndThen(Consumer<SigningKey> callback) {
var drivers = driverDetector.getAvailableDrivers();
var drivers = settings.getDriverDetector().getAvailableDrivers();
ui.pickTokenDriverAndThen(drivers,
(driver) -> requestPasswordAndThen(driver, callback));
}

public void requestPasswordAndThen(TokenDriver driver, Consumer<SigningKey> callback) {
ui.requestPasswordAndThen(driver, (password) -> ui.onWorkThreadDo(
() -> fetchKeysAndThen(driver, password, callback)));
(driver) -> {
ui.onWorkThreadDo(() -> {
fetchKeysAndThen(driver, callback);
});
}
);
}

private void fetchKeysAndThen(TokenDriver driver, char[] password, Consumer<SigningKey> callback) {
private void fetchKeysAndThen(TokenDriver driver, Consumer<SigningKey> callback) {
try {
var token = driver.createTokenWithPassword(slotId, password);
var token = driver.createToken(passwordManager, settings);
var keys = token.getKeys();

ui.onUIThreadDo(
() -> ui.pickKeyAndThen(keys, (privateKey) -> callback.accept(new SigningKey(token, privateKey))));
() -> ui.pickKeyAndThen(keys, driver, (privateKey) -> callback.accept(new SigningKey(token, privateKey))));
} catch (DSSException e) {
ui.onUIThreadDo(() -> ui.onPickSigningKeyFailed(AutogramException.createFromDSSException(e)));
}
Expand Down Expand Up @@ -235,10 +230,10 @@ public void initializeSignatureValidator(ScheduledExecutorService scheduledExecu
});

scheduledExecutorService.scheduleAtFixedRate(() -> SignatureValidator.getInstance().refresh(),
480, 480, java.util.concurrent.TimeUnit.MINUTES);
480, 480, java.util.concurrent.TimeUnit.MINUTES);
}

public TSPSource getTspSource() {
return tspSource;
return settings.getTspSource();
}
}
132 changes: 0 additions & 132 deletions src/main/java/digital/slovensko/autogram/core/CliParameters.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import java.util.List;

public class DefaultDriverDetector implements DriverDetector {
private final DriverDetectorSettings settings;

public static class TokenDriverShortnames {
public static final String EID = "eid";
public static final String SECURE_STORE = "secure_store";
Expand All @@ -19,45 +21,48 @@ public static class TokenDriverShortnames {
public static final String KEYSTORE = "keystore";
}

private final String customKeystorePath;
private final boolean customKeystorePasswordPrompt;
private final String HELPER_TEXT_EID = "\n\nV prípade nového občianskeho preukazu to môže znamenať, že si potrebujete certifikáty na podpisovanie cez občiansky preukaz vydať. Robí sa to pomocou obslužného softvéru eID klient.";
private final String HELPER_TEXT_SECURE_STORE = "";
private final String HELPER_TEXT_MONET = "";
private final String HELPER_TEXT_GEMALTO = "\n\nV prípade kvalifikovaných certifikátov na karte Gemalto ID Prime 940 môže byť potrebné nastaviť slot index 8. Skúste nastavenia -> Iné -> Slot index";
private final String HELPER_TEXT_FAKE = "";
private final String HELPER_TEXT_KEYSTORE = "";

public DefaultDriverDetector(String customKeystorePath, boolean customKeystorePasswordPrompt) {
this.customKeystorePath = customKeystorePath;
this.customKeystorePasswordPrompt = customKeystorePasswordPrompt;
public DefaultDriverDetector(DriverDetectorSettings settings) {
this.settings = settings;
}

private final List<TokenDriver> getLinuxDrivers(){
private List<TokenDriver> getLinuxDrivers(){
return List.of(
new PKCS11TokenDriver("Občiansky preukaz (eID klient)", Path.of("/usr/lib/eID_klient/libpkcs11_x64.so"), false, TokenDriverShortnames.EID),
new PKCS11TokenDriver("Občiansky preukaz (starý eID klient)", Path.of("/usr/lib/eac_mw_klient/libpkcs11_x64.so"), false, TokenDriverShortnames.EID),
new PKCS11TokenDriver("I.CA SecureStore", Path.of("/usr/lib/pkcs11/libICASecureStorePkcs11.so"), true, TokenDriverShortnames.SECURE_STORE),
new PKCS11TokenDriver("MONET+ ProID+Q", Path.of("/usr/lib/x86_64-linux-gnu/libproidqcm11.so"), true, TokenDriverShortnames.MONET),
new PKCS11TokenDriver("Gemalto IDPrime 940", Path.of("/usr/lib/libIDPrimePKCS11.so"), true, TokenDriverShortnames.GEMALTO),
new PKCS12KeystoreTokenDriver("Zo súboru", Path.of(customKeystorePath), customKeystorePasswordPrompt, TokenDriverShortnames.KEYSTORE),
new FakeTokenDriver("Fake token driver", Path.of("fakeTokenDriver"), false, TokenDriverShortnames.FAKE)
new PKCS11TokenDriver("Občiansky preukaz (eID klient)", Path.of("/usr/lib/eID_klient/libpkcs11_x64.so"), TokenDriverShortnames.EID, HELPER_TEXT_EID),
new PKCS11TokenDriver("Občiansky preukaz (starý eID klient)", Path.of("/usr/lib/eac_mw_klient/libpkcs11_x64.so"), TokenDriverShortnames.EID, HELPER_TEXT_EID),
new PKCS11TokenDriver("I.CA SecureStore", Path.of("/usr/lib/pkcs11/libICASecureStorePkcs11.so"), TokenDriverShortnames.SECURE_STORE, HELPER_TEXT_SECURE_STORE),
new PKCS11TokenDriver("MONET+ ProID+Q", Path.of("/usr/lib/x86_64-linux-gnu/libproidqcm11.so"), TokenDriverShortnames.MONET, HELPER_TEXT_MONET),
new PKCS11TokenDriver("Gemalto IDPrime 940", Path.of("/usr/lib/libIDPrimePKCS11.so"), TokenDriverShortnames.GEMALTO, HELPER_TEXT_GEMALTO),
new PKCS12KeystoreTokenDriver("Zo súboru", Path.of(settings.getCustomKeystorePath()), TokenDriverShortnames.KEYSTORE, HELPER_TEXT_KEYSTORE),
new FakeTokenDriver("Fake token driver", Path.of("fakeTokenDriver"), TokenDriverShortnames.FAKE, HELPER_TEXT_FAKE)
);
}

private final List<TokenDriver> getWindowsDrivers() {
private List<TokenDriver> getWindowsDrivers() {
return List.of(
new PKCS11TokenDriver("Občiansky preukaz (eID klient)", Path.of("C:\\Program Files (x86)\\eID_klient\\pkcs11_x64.dll"), false, TokenDriverShortnames.EID),
new PKCS11TokenDriver("I.CA SecureStore", Path.of("C:\\Windows\\System32\\SecureStorePkcs11.dll"), true, TokenDriverShortnames.SECURE_STORE),
new PKCS11TokenDriver("MONET+ ProID+Q", Path.of( "C:\\Windows\\system32\\proidqcm11.dll"), true, TokenDriverShortnames.MONET),
new PKCS11TokenDriver("Gemalto IDPrime 940", Path.of("C:\\Windows\\System32\\eTPKCS11.dll"), true, TokenDriverShortnames.GEMALTO),
new PKCS12KeystoreTokenDriver("Zo súboru", Path.of(customKeystorePath), customKeystorePasswordPrompt, TokenDriverShortnames.KEYSTORE),
new FakeTokenDriver("Fake token driver", Path.of("fakeTokenDriver"), false, TokenDriverShortnames.FAKE)
new PKCS11TokenDriver("Občiansky preukaz (eID klient)", Path.of("C:\\Program Files (x86)\\eID_klient\\pkcs11_x64.dll"), TokenDriverShortnames.EID, HELPER_TEXT_EID),
new PKCS11TokenDriver("I.CA SecureStore", Path.of("C:\\Windows\\System32\\SecureStorePkcs11.dll"), TokenDriverShortnames.SECURE_STORE, HELPER_TEXT_SECURE_STORE),
new PKCS11TokenDriver("MONET+ ProID+Q", Path.of( "C:\\Windows\\system32\\proidqcm11.dll"), TokenDriverShortnames.MONET, HELPER_TEXT_MONET),
new PKCS11TokenDriver("Gemalto IDPrime 940", Path.of("C:\\Windows\\System32\\eTPKCS11.dll"), TokenDriverShortnames.GEMALTO, HELPER_TEXT_GEMALTO),
new PKCS12KeystoreTokenDriver("Zo súboru", Path.of(settings.getCustomKeystorePath()), TokenDriverShortnames.KEYSTORE, HELPER_TEXT_KEYSTORE),
new FakeTokenDriver("Fake token driver", Path.of("fakeTokenDriver"), TokenDriverShortnames.FAKE, HELPER_TEXT_FAKE)
);
}

private final List<TokenDriver> getMacDrivers() {
private List<TokenDriver> getMacDrivers() {
return List.of(
new PKCS11TokenDriver("Občiansky preukaz (eID klient)", Path.of("/Applications/eID_klient.app/Contents/Frameworks/libPkcs11.dylib"), false, TokenDriverShortnames.EID),
new PKCS11TokenDriver("I.CA SecureStore", Path.of("/usr/local/lib/pkcs11/libICASecureStorePkcs11.dylib"), true, TokenDriverShortnames.SECURE_STORE),
new PKCS11TokenDriver("MONET+ ProID+Q", Path.of("/usr/local/lib/ProIDPlus/libproidqcm11.dylib"), true, TokenDriverShortnames.MONET),
new PKCS11TokenDriver("Gemalto IDPrime 940", Path.of("/usr/local/lib/libIDPrimePKCS11.dylib"), true, TokenDriverShortnames.GEMALTO),
new PKCS12KeystoreTokenDriver("Zo súboru", Path.of(customKeystorePath), customKeystorePasswordPrompt, TokenDriverShortnames.KEYSTORE),
new FakeTokenDriver("Fake token driver", Path.of("fakeTokenDriver"), false, TokenDriverShortnames.FAKE)
new PKCS11TokenDriver("Občiansky preukaz (eID klient)", Path.of("/Applications/eID_klient.app/Contents/Frameworks/libPkcs11.dylib"), TokenDriverShortnames.EID, HELPER_TEXT_EID),
new PKCS11TokenDriver("I.CA SecureStore", Path.of("/usr/local/lib/pkcs11/libICASecureStorePkcs11.dylib"), TokenDriverShortnames.SECURE_STORE, HELPER_TEXT_SECURE_STORE),
new PKCS11TokenDriver("MONET+ ProID+Q", Path.of("/usr/local/lib/ProIDPlus/libproidqcm11.dylib"), TokenDriverShortnames.MONET, HELPER_TEXT_MONET),
new PKCS11TokenDriver("Gemalto IDPrime 940", Path.of("/usr/local/lib/libIDPrimePKCS11.dylib"), TokenDriverShortnames.GEMALTO, HELPER_TEXT_GEMALTO),
new PKCS12KeystoreTokenDriver("Zo súboru", Path.of(settings.getCustomKeystorePath()), TokenDriverShortnames.KEYSTORE, HELPER_TEXT_KEYSTORE),
new FakeTokenDriver("Fake token driver", Path.of("fakeTokenDriver"), TokenDriverShortnames.FAKE, HELPER_TEXT_FAKE)
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package digital.slovensko.autogram.core;

public interface DriverDetectorSettings {
String getCustomKeystorePath();
}
38 changes: 38 additions & 0 deletions src/main/java/digital/slovensko/autogram/core/PasswordManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package digital.slovensko.autogram.core;

import digital.slovensko.autogram.ui.UI;
import eu.europa.esig.dss.token.PasswordInputCallback;

import java.util.Arrays;

public class PasswordManager implements PasswordInputCallback {
private final UI ui;
private final PasswordManagerSettings settings;
private char[] cachedPassword;

public PasswordManager(UI ui, PasswordManagerSettings settings) {
this.ui = ui;
this.settings = settings;
}

public char[] getContextSpecificPassword() {
if (settings.getCacheContextSpecificPasswordEnabled()) {
if (cachedPassword == null) {
cachedPassword = ui.getContextSpecificPassword();
}
return cachedPassword;
} else {
return ui.getContextSpecificPassword();
}
}

public void reset() {
if (cachedPassword != null)
Arrays.fill(cachedPassword, '\0');
}

@Override
public char[] getPassword() {
return ui.getKeystorePassword();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package digital.slovensko.autogram.core;

public interface PasswordManagerSettings {
boolean getCacheContextSpecificPasswordEnabled();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package digital.slovensko.autogram.core;

public interface SignatureTokenSettings {
boolean getForceContextSpecificLoginEnabled();
int getSlotIndex();
}
Loading

0 comments on commit ec54852

Please sign in to comment.