Skip to content

Commit

Permalink
Merge branch 'main' into AG-67/configurable-xdc-parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
celuchmarek committed Nov 14, 2023
2 parents 1bdaf15 + d2e729c commit 8c66c2a
Show file tree
Hide file tree
Showing 17 changed files with 190 additions and 55 deletions.
3 changes: 1 addition & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<dss.version>5.12.1</dss.version>
<gson.version>2.10.1</gson.version>
<apache.httpcomponents.version>4.5.14</apache.httpcomponents.version>
<pdfjs.version>2.16.105</pdfjs.version>
<pdfjs.version>2.10.377</pdfjs.version>
<saxon.version>12.3</saxon.version>
<xerces.version>2.12.1</xerces.version>
<slf4j.version>2.0.9</slf4j.version>
Expand Down Expand Up @@ -336,7 +336,6 @@
<fromDir>cmaps</fromDir>
<toDir>
${project.resources[0].directory}/digital/slovensko/autogram/ui/gui/vendor/pdfjs/cmaps</toDir>
<skipIfExists>true</skipIfExists>
</configuration>
</execution>
</executions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ public class AppStarter {
addOption("f", "force", false, "Overwrite existing file(s).").
addOption(null, "pdfa", false, "Check PDF/A compliance before signing.").
addOption(null, "parents", false, "Create all parent directories for target if needed.").
addOption("d", "driver", true, "PCKS driver name for signing. Supported values: eid, secure_store, monet, gemalto.").
addOption("d", "driver", true, "PCKS driver name for signing. Supported values: eid, secure_store, monet, gemalto, keystore.").
addOption(null, "keystore", true, "Absolute path to a keystore file that can be used for signing.").
addOption(null, "slot-id", true, "Slot ID for PKCS11 driver. If not specified, first available slot is used.").
addOption(null, "pdf-level", true, "PDF signature level. Supported values: PAdES_BASELINE_B (default), XAdES_BASELINE_B, CAdES_BASELINE_B.").
addOption(null, "en319132", false, "Sign according to EN 319 132 or EN 319 122.");
Expand Down
8 changes: 0 additions & 8 deletions src/main/java/digital/slovensko/autogram/core/Autogram.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,10 @@ public class Autogram {
private final boolean shouldDisplayVisualizationError;
private final Integer slotId;

public Autogram(UI ui, boolean shouldDisplayVisualizationError) {
this(ui, shouldDisplayVisualizationError, new DefaultDriverDetector(), -1);
}

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

public Autogram(UI ui, boolean shouldDisplayVisualizationError , Integer slotId) {
this(ui, shouldDisplayVisualizationError, new DefaultDriverDetector(), slotId);
}

public Autogram(UI ui, boolean shouldDisplayVisualizationError , DriverDetector driverDetector, Integer slotId) {
this.ui = ui;
this.driverDetector = driverDetector;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public CliParameters(CommandLine cmd) throws SourceDoesNotExistException, TokenD
SlotIdIsNotANumberException, PDFSignatureLevelIsNotValidException {
source = getValidSource(cmd.getOptionValue("s"));
target = cmd.getOptionValue("t");
driver = getValidTokenDriver(cmd.getOptionValue("d"));
driver = getValidTokenDriver(cmd.getOptionValue("d"), cmd.getOptionValue("keystore", ""));
slotId = getValidSlotId(cmd.getOptionValue("slot-id"));
force = cmd.hasOption("f");
checkPDFACompliance = cmd.hasOption("pdfa");
Expand Down Expand Up @@ -91,11 +91,11 @@ private static File getValidSource(String sourcePath) throws SourceDoesNotExistE
return sourcePath == null ? null : new File(sourcePath);
}

private static TokenDriver getValidTokenDriver(String driverName) throws TokenDriverDoesNotExistException {
private static TokenDriver getValidTokenDriver(String driverName, String customKeystorePath) throws TokenDriverDoesNotExistException {
if (driverName == null)
return null;

Optional<TokenDriver> tokenDriver = new DefaultDriverDetector()
Optional<TokenDriver> tokenDriver = new DefaultDriverDetector(customKeystorePath, true)
.getAvailableDrivers()
.stream()
.filter(d -> d.getShortname().equals(driverName))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package digital.slovensko.autogram.core;

import digital.slovensko.autogram.drivers.FakeTokenDriver;
import digital.slovensko.autogram.drivers.PKCS11TokenDriver;
import digital.slovensko.autogram.drivers.TokenDriver;
import digital.slovensko.autogram.drivers.FakeTokenDriver;
import digital.slovensko.autogram.drivers.PKCS12KeystoreTokenDriver;
import digital.slovensko.autogram.util.OperatingSystem;

import java.nio.file.Path;
Expand All @@ -15,32 +16,50 @@ public static class TokenDriverShortnames {
public static final String MONET = "monet";
public static final String GEMALTO = "gemalto";
public static final String FAKE = "fake";
public static final String KEYSTORE = "keystore";
}

private final String customKeystorePath;
private final boolean customKeystorePasswordPrompt;

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

public static final List<TokenDriver> LINUX_DRIVERS = 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 FakeTokenDriver("Fake token driver", Path.of("fakeTokenDriver"), false, TokenDriverShortnames.FAKE)
);

public static final List<TokenDriver> WINDOWS_DRIVERS = 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 FakeTokenDriver("Fake token driver", Path.of("fakeTokenDriver"), false, TokenDriverShortnames.FAKE)
);

public static final List<TokenDriver> MAC_DRIVERS = 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 FakeTokenDriver("Fake token driver", Path.of("fakeTokenDriver"), false, TokenDriverShortnames.FAKE)
);
private final 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)
);
}

private final 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)
);
}

private final 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)
);
}

public List<TokenDriver> getAvailableDrivers() {
return getAllDrivers().stream().filter(TokenDriver::isInstalled).toList();
Expand All @@ -49,13 +68,13 @@ public List<TokenDriver> getAvailableDrivers() {
private List<TokenDriver> getAllDrivers() {
switch (OperatingSystem.current()) {
case WINDOWS -> {
return WINDOWS_DRIVERS;
return getWindowsDrivers();
}
case LINUX -> {
return LINUX_DRIVERS;
return getLinuxDrivers();
}
case MAC -> {
return MAC_DRIVERS;
return getMacDrivers();
}
default -> throw new IllegalStateException("Unexpected value: " + OperatingSystem.current());
}
Expand Down
33 changes: 31 additions & 2 deletions src/main/java/digital/slovensko/autogram/core/UserSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ public class UserSettings {
private boolean serverEnabled;
private boolean expiredCertsEnabled;
private List<String> trustedList;
private String customKeystorePath;
private boolean customKeystorePasswordPrompt;

private UserSettings(SignatureLevel signatureLevel, String driver, boolean en319132,
boolean signIndividually, boolean correctDocumentDisplay,
boolean signaturesValidity, boolean pdfaCompliance,
boolean serverEnabled, boolean expiredCertsEnabled, List<String> trustedList) {
boolean serverEnabled, boolean expiredCertsEnabled, List<String> trustedList,
String customKeystorePath, boolean customKeystorePassword) {
this.signatureLevel = signatureLevel;
this.driver = driver;
this.en319132 = en319132;
Expand All @@ -35,6 +38,8 @@ private UserSettings(SignatureLevel signatureLevel, String driver, boolean en319
this.serverEnabled = serverEnabled;
this.expiredCertsEnabled = expiredCertsEnabled;
this.trustedList = trustedList;
this.customKeystorePath = customKeystorePath;
this.customKeystorePasswordPrompt = customKeystorePassword;
}

public static UserSettings load() {
Expand All @@ -50,6 +55,8 @@ public static UserSettings load() {
var serverEnabled = prefs.getBoolean("SERVER_ENABLED", true);
var expiredCertsEnabled = prefs.getBoolean("EXPIRED_CERTS_ENABLED", false);
var trustedList = prefs.get("TRUSTED_LIST", "SK,CZ,AT,PL,HU");
var customKeystorePath = prefs.get("CUSTOM_KEYSTORE_PATH", "");
var customKeystorePasswordPrompt = prefs.getBoolean("CUSTOM_KEYSTORE_PASSWORD_PROMPT", false);

var signatureLevelStringConverter = new SignatureLevelStringConverter();
var signatureLevel = Arrays
Expand All @@ -69,7 +76,9 @@ public static UserSettings load() {
pdfaCompliance,
serverEnabled,
expiredCertsEnabled,
trustedList == null ? new ArrayList<>() : new ArrayList<>(List.of(trustedList.split(","))));
trustedList == null ? new ArrayList<>() : new ArrayList<>(List.of(trustedList.split(","))),
customKeystorePath,
customKeystorePasswordPrompt);
}

public SignatureLevel getSignatureLevel() {
Expand Down Expand Up @@ -171,6 +180,24 @@ public void removeFromTrustedList(String country) {
save();
}

public String getCustomKeystorePath() {
return customKeystorePath;
}

public void setCustomKeystorePath(String value) {
customKeystorePath = value;
save();
}

public boolean getCustomKeystorePasswordPrompt() {
return customKeystorePasswordPrompt;
}

public void setCustomKeystorePasswordPrompt(boolean value) {
customKeystorePasswordPrompt = value;
save();
}

private void save() {
var prefs = Preferences.userNodeForPackage(UserSettings.class);

Expand All @@ -184,5 +211,7 @@ private void save() {
prefs.putBoolean("SERVER_ENABLED", serverEnabled);
prefs.putBoolean("EXPIRED_CERTS_ENABLED", expiredCertsEnabled);
prefs.put("TRUSTED_LIST", trustedList.stream().collect(Collectors.joining(",")));
prefs.put("CUSTOM_KEYSTORE_PATH", customKeystorePath);
prefs.putBoolean("CUSTOM_KEYSTORE_PASSWORD_PROMPT", customKeystorePasswordPrompt);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

public class NoValidKeysDetectedException extends AutogramException {
public NoValidKeysDetectedException() {
super("Nastala chyba", "Nenašli sa žiadne platné podpisové certifikáty", "V úložisku certifikátov sa pravdepodobne nenachádzajú žiadne platné podpisové certifikáty, ktoré by sa dali použiť na podpisovanie. Boli však nájdené ekspirované certifikáty, ktorými je možné podpisovať až po zmene v nastaveniach.\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.", null);
super("Nastala chyba", "Nenašli sa žiadne platné podpisové certifikáty", "V úložisku certifikátov sa pravdepodobne nenachádzajú žiadne platné podpisové certifikáty, ktoré by sa dali použiť na podpisovanie. Boli však nájdené exspirované certifikáty, ktorými je možné podpisovať až po zmene v nastaveniach.\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.", null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package digital.slovensko.autogram.drivers;

import java.io.IOException;
import java.nio.file.Path;
import java.security.KeyStore;

import eu.europa.esig.dss.token.AbstractKeyStoreTokenConnection;
import eu.europa.esig.dss.token.Pkcs12SignatureToken;

public class PKCS12KeystoreTokenDriver extends TokenDriver {
public PKCS12KeystoreTokenDriver(String name, Path path, boolean needsPassword, String shortname) {
super(name, path, needsPassword, shortname);
}


@Override
public AbstractKeyStoreTokenConnection createTokenWithPassword(Integer slotId, char[] password) {
try {
return new Pkcs12SignatureToken(getPath().toString(), new KeyStore.PasswordProtection(password));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
7 changes: 5 additions & 2 deletions src/main/java/digital/slovensko/autogram/ui/cli/CliApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import digital.slovensko.autogram.core.Autogram;
import digital.slovensko.autogram.core.CliParameters;
import digital.slovensko.autogram.core.DefaultDriverDetector;
import digital.slovensko.autogram.core.SigningJob;
import digital.slovensko.autogram.core.errors.SourceNotDefindedException;
import digital.slovensko.autogram.core.TargetPath;
Expand All @@ -21,8 +22,10 @@ public static void start(CommandLine cmd) {

try {
var params = new CliParameters(cmd);
var autogram = params.getDriver() == null ? new Autogram(ui, false, params.getSlotId())
: new Autogram(ui, false, () -> Collections.singletonList(params.getDriver()), params.getSlotId());
var autogram = new Autogram(ui, false, params.getDriver() != null ?
() -> Collections.singletonList(params.getDriver())
: new DefaultDriverDetector("", false),
params.getSlotId());

if (params.getSource() == null)
throw new SourceNotDefindedException();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/digital/slovensko/autogram/ui/gui/GUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public void pickTokenDriverAndThen(List<TokenDriver> drivers, Consumer<TokenDriv
@Override
public void requestPasswordAndThen(TokenDriver driver, Consumer<char[]> callback) {
if (!driver.needsPassword()) {
callback.accept(null);
callback.accept("".toCharArray());
return;
}

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/digital/slovensko/autogram/ui/gui/GUIApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.concurrent.ScheduledExecutorService;

import digital.slovensko.autogram.core.Autogram;
import digital.slovensko.autogram.core.DefaultDriverDetector;
import digital.slovensko.autogram.core.LaunchParameters;
import digital.slovensko.autogram.core.UserSettings;
import digital.slovensko.autogram.server.AutogramServer;
Expand All @@ -21,7 +22,8 @@ public class GUIApp extends Application {
public void start(Stage windowStage) throws Exception {
var userSettings = UserSettings.load();
var ui = new GUI(getHostServices(), userSettings);
var autogram = new Autogram(ui, userSettings.isCorrectDocumentDisplay());
var autogram = new Autogram(ui, userSettings.isCorrectDocumentDisplay(), new DefaultDriverDetector(
userSettings.getCustomKeystorePath(), userSettings.getCustomKeystorePasswordPrompt()));

Platform.setImplicitExit(false);
autogram.checkForUpdate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void initialize() {
for (var key : keys) {
Node badge = new HBox();
if (!key.getCertificate().isValidOn(new java.util.Date())) {
badge = SignatureBadgeFactory.createInfoBadge("Ekspirovaný certifikát");
badge = SignatureBadgeFactory.createInfoBadge("Exspirovaný certifikát");

if (!expiredCertsEnabled)
continue;
Expand Down
Loading

0 comments on commit 8c66c2a

Please sign in to comment.