diff --git a/README.md b/README.md index 27277a2..764dc02 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ git clone https://github.com/v-bodnar/ocpp-server.git **Build:** ``` cd ocpp-server -gradle clean build +gradle build ``` **Usage:** @@ -41,8 +41,15 @@ java -jar ocpp-server-0.1.jar combination with -nogui - -ocppPort,--ocppPort port on which OCPP server will accept connections, default:8887, works in combination with -nogui - - --restPort port on which REST server will accept connections, default:9090, works in combination with -nogui - + - --restPort port on which REST server will accept connections, default:9090, works in combination with -nogui + - -keystoreUUID,--keystoreUUID run ssl server with keystore for defined keystore + uuid + - -clientAuthenticationNeeded,--clientAuthenticationNeeded should server needed for client certificate + - -keystoreCiphers,--keystoreCiphers list of keystore ciphers separated by comma + - -createKeystoreCertificate Create new keystore certificate + - -deleteKeystoreCertificate Delete keystore certificate + - -showKeystoreConfig Show keystore config file content + ## Changing server behavior using Groovy **$GROOVY_PATH = $LITHOS_HOME/ocpp/groovy/** Groovy files will be created under path: **$GROOVY_PATH** @@ -55,28 +62,53 @@ you can change responses that ocpp server sends to clients. Using GUI reload tho Also you can upload .groovy files using REST API, it will replace files with the same names and automatically load classes to classloader +## Secure connection using ssl +**SSL_PATH = $LITHOS_HOME/ocpp/ssl** +During startup Lithos will create trust store SSL_PATH/trust-store.jks which is used for storing clients certificates +During startup Lithos will create file SSL_PATH/keystore-certificates.config which is used for storing information +about key-stores that contain server certificate, each server certificate will be stored in the separate key-store. +Information about trust-store is also stored in this file. -## Setting up ssl configuration -Create file **$LITHOS_HOME\ocpp\ssl\ssl.properties** with content: +If you want to use manually generated server certificate just add key-store that contains it to SSL_PATH and add +information to keystore-certificates.config file. Example: ``` -keystore.password=yourKeystorePassword -keystore.protocol=TLSv1.1|TLSv1.2 -client.authentication.needed=false|true -keystore.ciphers=define encryption +{ + "keystoreCertificatesConfig": [ + { + "uuid": "b1ca37d9-3ee9-4b22-95d3-e976f02ff3fd", + "keystorePassword": "f9a42ef7-7ce5-4dc3-8b15-d139f4dcd737", + "keystorePath": "C:\\Work\\Shared\\LITHOS_HOME\\ocpp\\ssl\\b1ca37d9-3ee9-4b22-95d3-e976f02ff3fd.jks", + "keystoreProtocol": "TLSv1.2" + } + ] +} ``` -If file ssl.properties not exists Server run without any ssl context +**GUI mode:** +1. Go to tab "Server Certificates" click button "Generate certificate", this will generate new server certificate, +table above will show information about new certificate, there you also can download it or delete. +2. If client validation is needed go to tab "Client Certificates", click button "Upload certificate" and specify +clients certificate. It will be added to the trust-store and table will be refreshed showing clients certificates in +the trust store +3. Go to tab "General", select server certificate that you want to use, check "Validate client certificate" if needed. + +**NO GUI mode:** +* To create server certificate +``` +java -jar ocpp-server-0.1.jar -createKeystoreCertificate +``` +* To list server certificates ids +``` +java -jar ocpp-server-0.1.jar -showKeystoreConfig +``` +* To run using one of certificates +``` +-jar ocpp-server-0.1.jar -nogui -keystoreUUID uuid-shown-by-previous-command -clientAuthenticationNeeded +``` + +REST API also exposes CRUD methods for managing server and client certificates. In NO GUI mode client certificates can +only be uploaded using REST API or by manually adding certificate to SSL_PATH/trust-store.jks. -Server will generate self-signed certificate during startup, you can download it using GUI or REST API. Client have to - import this certificate to truststore or allow untrusted certificates. - -If **client.authentication.needed** was set to **true**, clients certificate has to be added to truststore. This can be -done -using **JDK keytool**. GUI or REST API also support clients certificate upload with the limit that only single -certificate -can -be uploaded. - ## REST API ``` @Produces(MediaType.APPLICATION_JSON) @@ -135,15 +167,27 @@ be uploaded. @Path("upload-confirmation-supplier") public Response uploadConfirmationSupplier(@FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail) - + + @GET + @Path("list-trust-store-aliases") + public Response listClientCertificate() + @POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Path("upload-client-cert") public Response uploadClientCertificate(@FormDataParam("file") InputStream uploadedInputStream, @FormDataParam("file") FormDataContentDisposition fileDetail) - + + @POST + @Path("generate-server-cert") + public Response generateServerCertificate() + @GET - @Path("download-server-cert") - public Response downloadServerCertificate() + @Path("get-keystore-config") + public Response getKeyStoreConfig() + + @DELETE + @Path("delete-server-cert") + public Response deleteServerCertificate(@QueryParam("uuid") String uuid) ``` diff --git a/src/main/java/com/omb/ocpp/gui/Application.java b/src/main/java/com/omb/ocpp/gui/Application.java index 466928c..64ab06c 100644 --- a/src/main/java/com/omb/ocpp/gui/Application.java +++ b/src/main/java/com/omb/ocpp/gui/Application.java @@ -82,18 +82,18 @@ public static void main(String[] args) { } private static void invokeCommand(Options options, CommandLine cmd, String[] args) throws Exception { - Map, Action> COMMANDS = new LinkedHashMap<>(); - COMMANDS.put(line -> line.hasOption(HELP), () -> printHelp(options)); - COMMANDS.put(line -> line.hasOption(SHOW_KEYSTORE_CONFIG), APPLICATION::showKeystoreCertificatesConfig); - COMMANDS.put(line -> line.hasOption(CREATE_KEYSTORE_CERTIFICATE), APPLICATION::createKeystoreCertificate); - COMMANDS.put(line -> line.hasOption(DELETE_KEYSTORE_CERTIFICATE), () -> APPLICATION.deleteKeystoreCertificate(cmd)); - COMMANDS.put(line -> line.hasOption(NO_GUI_ID), () -> APPLICATION.startNoGui(cmd)); - - Action action = COMMANDS. + Map, Action> commands = new LinkedHashMap<>(); + commands.put(line -> line.hasOption(HELP), () -> printHelp(options)); + commands.put(line -> line.hasOption(SHOW_KEYSTORE_CONFIG), APPLICATION::showKeystoreCertificatesConfig); + commands.put(line -> line.hasOption(CREATE_KEYSTORE_CERTIFICATE), APPLICATION::createKeystoreCertificate); + commands.put(line -> line.hasOption(DELETE_KEYSTORE_CERTIFICATE), () -> APPLICATION.deleteKeystoreCertificate(cmd)); + commands.put(line -> line.hasOption(NO_GUI_ID), () -> APPLICATION.startNoGui(cmd)); + + Action action = commands. entrySet(). stream(). filter(e -> e.getKey().test(cmd)). - map(e -> e.getValue()). + map(Map.Entry::getValue). findFirst(). orElseGet(() -> () -> GuiApplication.main(args)); @@ -148,6 +148,7 @@ private static Options getOptions() { private static void printHelp(Options options) { HelpFormatter formatter = new HelpFormatter(); + formatter.setWidth(150); formatter.printHelp("ocpp-server", options); } diff --git a/src/main/java/com/omb/ocpp/gui/GeneralTab.java b/src/main/java/com/omb/ocpp/gui/GeneralTab.java index 40eda80..9e49eb3 100644 --- a/src/main/java/com/omb/ocpp/gui/GeneralTab.java +++ b/src/main/java/com/omb/ocpp/gui/GeneralTab.java @@ -5,7 +5,9 @@ import com.omb.ocpp.server.OcppServerService; import com.omb.ocpp.server.SslContextConfig; import javafx.application.Platform; +import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; +import javafx.event.Event; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; @@ -43,7 +45,12 @@ class GeneralTab { private static final Logger LOGGER = LoggerFactory.getLogger(GeneralTab.class); private static final Pattern IP_ADDRESS_PATTERN = Pattern.compile("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\\.|$)){4}"); private static final int DEFAULT_OCPP_PORT = 8887; + private static final String STOPPED_IMAGE = "/images/ev_stopped.png"; + private static final String PENDING_IMAGE = "/images/ev_pending.png"; + private static final String STARTED_IMAGE = "/images/ev_started.png"; + private static final String CERTIFICATE_ERROR = "Could not retrieve certificates data"; + private final Tab tab = new Tab(); private final ComboBox ipCombobox = new ComboBox<>(); private final ComboBox certificateCombo = new ComboBox<>(); private final CheckBox validateClientCertCheckBox = new CheckBox("Validate client certificate"); @@ -51,14 +58,9 @@ class GeneralTab { private final Button serverButton = new Button("Start"); private final HBox hBox = new HBox(); - private final ImageView statusStopped = new ImageView(new Image(getClass().getResourceAsStream("/images" + - "/ev_stopped.png"))); - private final ImageView statusPending = new ImageView(new Image(getClass().getResourceAsStream("/images" + - "/ev_pending.png"))); - private final ImageView statusStarted = new ImageView(new Image(getClass().getResourceAsStream("/images" + - "/ev_started.png"))); - - private Status status = Status.STOPPED; + private final ImageView statusStoppedImage = new ImageView(new Image(getClass().getResourceAsStream(STOPPED_IMAGE))); + private final ImageView statusPendingImage = new ImageView(new Image(getClass().getResourceAsStream(PENDING_IMAGE))); + private final ImageView statusStartedImage = new ImageView(new Image(getClass().getResourceAsStream(STARTED_IMAGE))); private final OcppServerService ocppServerService; private final WebServer webServer; @@ -71,19 +73,9 @@ class GeneralTab { } Tab constructTab(SplitPane splitPane) { - Tab tab = new Tab(); tab.setText("General"); tab.setClosable(false); - tab.setOnSelectionChanged(event -> { - if (event.getTarget().equals(tab)) { - try { - certificateCombo.setItems(FXCollections.observableArrayList(keystoreApi.getAllServerCertificates())); - certificateCombo.getItems().add(null); - } catch (Exception e) { - LOGGER.error("Could not retrieve certificates data", e); - } - } - }); + tab.setOnSelectionChanged(this::tabChangeEventHandler); validateClientCertCheckBox.selectedProperty().addListener((observable, oldValue, newValue) -> { if (ocppServerService.getSslContextConfig() != null) { @@ -92,52 +84,9 @@ Tab constructTab(SplitPane splitPane) { }); - certificateCombo.setConverter(new StringConverter<>() { - @Override - public String toString(X509Certificate certificate) { - if (certificate == null) { - return "Select Server Certificate"; - } else { - return String.format("%s - %s", certificate.getIssuerDN(), certificate.getNotBefore()); - } - } - - @Override - public X509Certificate fromString(String string) { - try { - Optional certificate = keystoreApi.getAllServerCertificates().stream() - .filter(x509Certificate -> x509Certificate.getIssuerDN().toString().equals(string.split(" ")[0])) - .findFirst(); - if (certificate.isPresent()) { - return certificate.get(); - } else { - LOGGER.error("Could not retrieve certificates data"); - return null; - } - } catch (Exception e) { - LOGGER.error("Could not retrieve certificates data", e); - return null; - } - } - }); - - certificateCombo.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { - if (newValue == null) { - ocppServerService.setSslContextConfig(null); - } else { - try { - UUID keystoreUUID = keystoreApi.getKeyStoreUUIDByCertificate(newValue); - SslContextConfig sslContextConfig = new SslContextConfig(). - setSslContext(keystoreApi.initializeSslContext(keystoreUUID)). - setClientAuthenticationNeeded(validateClientCertCheckBox.isSelected()). - setClientAuthenticationNeeded(false); - ocppServerService.setSslContextConfig(sslContextConfig); - } catch (Exception e) { - LOGGER.error("Could not retrieve certificates data"); - } + certificateCombo.setConverter(certificateConverter); - } - }); + certificateCombo.getSelectionModel().selectedItemProperty().addListener(this::certificatesComboValueChanged); serverButton.setPrefWidth(100); @@ -156,12 +105,12 @@ public X509Certificate fromString(String string) { vBox.setPadding(new Insets(5)); vBox.setAlignment(Pos.TOP_CENTER); - statusStarted.setPreserveRatio(true); - statusStopped.setPreserveRatio(true); - statusPending.setPreserveRatio(true); - statusStopped.fitWidthProperty().bind(splitPane.widthProperty().divide(2).subtract(100)); - statusPending.fitWidthProperty().bind(splitPane.widthProperty().divide(2).subtract(100)); - statusStarted.fitWidthProperty().bind(splitPane.widthProperty().divide(2).subtract(100)); + statusStartedImage.setPreserveRatio(true); + statusStoppedImage.setPreserveRatio(true); + statusPendingImage.setPreserveRatio(true); + statusStoppedImage.fitWidthProperty().bind(splitPane.widthProperty().divide(2).subtract(100)); + statusPendingImage.fitWidthProperty().bind(splitPane.widthProperty().divide(2).subtract(100)); + statusStartedImage.fitWidthProperty().bind(splitPane.widthProperty().divide(2).subtract(100)); ipCombobox.prefWidthProperty().bind(splitPane.widthProperty()); portTextField.prefWidthProperty().bind(splitPane.widthProperty()); @@ -173,7 +122,7 @@ public X509Certificate fromString(String string) { VBox.setVgrow(serverButton, Priority.ALWAYS); HBox.setHgrow(vBox, Priority.ALWAYS); - hBox.getChildren().addAll(vBox, statusStopped); + hBox.getChildren().addAll(vBox, statusStoppedImage); tab.setContent(hBox); startStateChecker(); @@ -189,9 +138,9 @@ private void checkAndSetServerStateColor() { validateClientCertCheckBox.setDisable(true); certificateCombo.setDisable(true); changeStatusImage(Status.STARED); - if (!hBox.getChildren().contains(statusStarted)) { - hBox.getChildren().remove(statusPending); - hBox.getChildren().add(statusStarted); + if (!hBox.getChildren().contains(statusStartedImage)) { + hBox.getChildren().remove(statusPendingImage); + hBox.getChildren().add(statusStartedImage); } serverButton.setOnAction(event -> { changeStatusImage(Status.PENDING); @@ -235,20 +184,20 @@ private void changeStatusImage(Status status) { private ImageView determineImage(Status status) { switch (status) { case STARED: - return statusStarted; + return statusStartedImage; case PENDING: - return statusPending; + return statusPendingImage; case STOPPED: - return statusStopped; + return statusStoppedImage; default: - return statusStopped; + return statusStoppedImage; } } enum Status { STARED, PENDING, - STOPPED; + STOPPED } private void startStateChecker() { @@ -281,4 +230,64 @@ private Set getIpAddresses() { } return availableIpAddresses; } + + private StringConverter certificateConverter = new StringConverter<>() { + @Override + public String toString(X509Certificate certificate) { + if (certificate == null) { + return "Select Server Certificate"; + } else { + return String.format("%s - %s", certificate.getIssuerDN(), certificate.getNotBefore()); + } + } + + @Override + public X509Certificate fromString(String string) { + try { + Optional certificate = keystoreApi.getAllServerCertificates().stream() + .filter(x509Certificate -> x509Certificate.getIssuerDN().toString().equals(string.split(" ")[0])) + .findFirst(); + if (certificate.isPresent()) { + return certificate.get(); + } else { + LOGGER.error(CERTIFICATE_ERROR); + return null; + } + } catch (Exception e) { + LOGGER.error(CERTIFICATE_ERROR, e); + return null; + } + } + }; + + + private void tabChangeEventHandler(Event event) { + if (event.getTarget().equals(tab)) { + try { + certificateCombo.setItems(FXCollections.observableArrayList(keystoreApi.getAllServerCertificates())); + certificateCombo.getItems().add(null); + } catch (Exception e) { + LOGGER.error("Could not retrieve certificates data", e); + } + } + } + + private void certificatesComboValueChanged(ObservableValue observable, + X509Certificate oldValue, + X509Certificate newValue) { + if (newValue == null) { + ocppServerService.setSslContextConfig(null); + } else { + try { + UUID keystoreUUID = keystoreApi.getKeyStoreUUIDByCertificate(newValue); + SslContextConfig sslContextConfig = new SslContextConfig(). + setSslContext(keystoreApi.initializeSslContext(keystoreUUID)). + setClientAuthenticationNeeded(validateClientCertCheckBox.isSelected()). + setClientAuthenticationNeeded(false); + ocppServerService.setSslContextConfig(sslContextConfig); + } catch (Exception e) { + LOGGER.error("Could not retrieve certificates data"); + } + } + } } diff --git a/src/main/java/com/omb/ocpp/gui/ServerTab.java b/src/main/java/com/omb/ocpp/gui/ServerTab.java index d02b1e5..84839d0 100644 --- a/src/main/java/com/omb/ocpp/gui/ServerTab.java +++ b/src/main/java/com/omb/ocpp/gui/ServerTab.java @@ -4,7 +4,6 @@ import com.omb.ocpp.groovy.GroovyService; import javafx.beans.property.ReadOnlyStringWrapper; import javafx.collections.FXCollections; -import javafx.geometry.Insets; import javafx.scene.control.Button; import javafx.scene.control.Tab; import javafx.scene.control.TableColumn; diff --git a/src/main/java/com/omb/ocpp/security/certificate/KeystoreConstants.java b/src/main/java/com/omb/ocpp/security/certificate/KeystoreConstants.java index 6633d30..67311bc 100644 --- a/src/main/java/com/omb/ocpp/security/certificate/KeystoreConstants.java +++ b/src/main/java/com/omb/ocpp/security/certificate/KeystoreConstants.java @@ -12,4 +12,6 @@ public class KeystoreConstants { public static final String TRUST_STORE_UUID = "c3b9ddc3-5fd9-4875-a536-366d8490c096"; public static final String OCPP_SERVER_PRIVATE_KEY = "OCPP_SERVER_PRIVATE_KEY"; public static final String OCPP_SERVER_CERT = "OCPP_SERVER_CERT"; + + private KeystoreConstants() {} } diff --git a/src/main/java/com/omb/ocpp/security/certificate/config/KeystoreConfigRegistry.java b/src/main/java/com/omb/ocpp/security/certificate/config/KeystoreConfigRegistry.java index ec495e7..574fafc 100644 --- a/src/main/java/com/omb/ocpp/security/certificate/config/KeystoreConfigRegistry.java +++ b/src/main/java/com/omb/ocpp/security/certificate/config/KeystoreConfigRegistry.java @@ -12,7 +12,6 @@ import java.util.Objects; import java.util.Optional; import java.util.UUID; -import java.util.stream.Collectors; import static com.omb.ocpp.security.certificate.KeystoreConstants.TRUST_STORE_UUID; diff --git a/src/main/java/com/omb/ocpp/security/certificate/service/CreateKeystoreCertificateService.java b/src/main/java/com/omb/ocpp/security/certificate/service/CreateKeystoreCertificateService.java index fa91dbd..9dd9ccf 100644 --- a/src/main/java/com/omb/ocpp/security/certificate/service/CreateKeystoreCertificateService.java +++ b/src/main/java/com/omb/ocpp/security/certificate/service/CreateKeystoreCertificateService.java @@ -19,22 +19,36 @@ import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; +import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcRSAContentSignerBuilder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.OutputStream; import java.math.BigInteger; import java.net.InetAddress; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.*; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.Security; +import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.time.ZonedDateTime; -import java.util.*; +import java.util.Collections; +import java.util.Date; +import java.util.Objects; +import java.util.Random; +import java.util.UUID; import static com.omb.ocpp.security.certificate.KeystoreConstants.OCPP_SERVER_CERT; import static com.omb.ocpp.security.certificate.KeystoreConstants.OCPP_SERVER_PRIVATE_KEY; @@ -73,12 +87,14 @@ private KeystoreCertificateConfig randomDataForConfig() { build(); } - private void createJavaKeyStoreWithCertificate(KeystoreCertificateConfig keystoreCertificateConfig) throws Exception { + private void createJavaKeyStoreWithCertificate(KeystoreCertificateConfig keystoreCertificateConfig) throws CertificateException, + NoSuchAlgorithmException, KeyStoreException, IOException, NoSuchProviderException, OperatorCreationException { KeyStore keyStoreLocal = createJavaKeyStore(keystoreCertificateConfig); generateCertificate(keyStoreLocal, keystoreCertificateConfig.getKeystorePassword().toCharArray(), keystoreCertificateConfig.getKeystorePath()); } - private KeyStore createJavaKeyStore(KeystoreCertificateConfig keystoreCertificateConfig) throws Exception { + private KeyStore createJavaKeyStore(KeystoreCertificateConfig keystoreCertificateConfig) throws IOException, + KeyStoreException, CertificateException, NoSuchAlgorithmException { Files.createFile(keystoreCertificateConfig.getKeystorePath()); KeyStore keyStoreLocal = KeyStore.getInstance("JKS"); keyStoreLocal.load(null, null); @@ -88,7 +104,8 @@ private KeyStore createJavaKeyStore(KeystoreCertificateConfig keystoreCertificat return keyStoreLocal; } - private void generateCertificate(KeyStore keyStore, char[] password, Path keyStorePath) throws Exception { + private void generateCertificate(KeyStore keyStore, char[] password, Path keyStorePath) throws IOException, + NoSuchAlgorithmException, OperatorCreationException, CertificateException, NoSuchProviderException, KeyStoreException { Security.setProperty("crypto.policy", "unlimited"); Security.addProvider(new BouncyCastleProvider()); @@ -144,7 +161,7 @@ private void generateCertificate(KeyStore keyStore, char[] password, Path keySto } } - private KeyPair generateKeyPair() throws Exception { + private KeyPair generateKeyPair() throws NoSuchAlgorithmException { KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA"); rsa.initialize(2048, new SecureRandom()); return rsa.genKeyPair(); diff --git a/src/main/java/com/omb/ocpp/security/certificate/service/CreateOrGetKeystoreCertificatesConfigService.java b/src/main/java/com/omb/ocpp/security/certificate/service/CreateOrGetKeystoreCertificatesConfigService.java index 32182ed..7536be3 100644 --- a/src/main/java/com/omb/ocpp/security/certificate/service/CreateOrGetKeystoreCertificatesConfigService.java +++ b/src/main/java/com/omb/ocpp/security/certificate/service/CreateOrGetKeystoreCertificatesConfigService.java @@ -5,17 +5,18 @@ import com.omb.ocpp.security.certificate.KeystoreConstants; import com.omb.ocpp.security.certificate.config.KeystoreConfigRegistry; +import java.io.IOException; import java.nio.file.Files; public class CreateOrGetKeystoreCertificatesConfigService { - public KeystoreConfigRegistry execute() throws Exception { + public KeystoreConfigRegistry execute() throws IOException { Gson gson = new GsonBuilder().setPrettyPrinting().create(); - createConfigIfNotExists(gson); + createConfigIfNotExists(); return gson.fromJson(Files.readString(KeystoreConstants.KEYSTORE_CERTIFICATE_CONFIG_PATH), KeystoreConfigRegistry.class); } - private void createConfigIfNotExists(Gson gson) throws Exception { + private void createConfigIfNotExists() throws IOException { if (Files.notExists(KeystoreConstants.KEYSTORE_CERTIFICATE_CONFIG_PATH)) { KeystoreConfigRegistry keystoreConfigRegistry = new KeystoreConfigRegistry(); keystoreConfigRegistry.persist(); diff --git a/src/main/java/com/omb/ocpp/security/certificate/service/DeleteKeystoreCertificateConfigService.java b/src/main/java/com/omb/ocpp/security/certificate/service/DeleteKeystoreCertificateConfigService.java index c094557..f908fce 100644 --- a/src/main/java/com/omb/ocpp/security/certificate/service/DeleteKeystoreCertificateConfigService.java +++ b/src/main/java/com/omb/ocpp/security/certificate/service/DeleteKeystoreCertificateConfigService.java @@ -7,6 +7,7 @@ import com.omb.ocpp.security.certificate.config.KeystoreCertificateConfig; import com.omb.ocpp.security.certificate.config.KeystoreConfigRegistry; +import java.io.IOException; import java.nio.file.Files; import java.util.Objects; import java.util.UUID; @@ -29,7 +30,7 @@ public void execute() throws Exception { Files.delete(keystoreCertificateConfig.getKeystorePath()); } - private void writeConfigToFile(KeystoreConfigRegistry keystoreConfigRegistry) throws Exception { + private void writeConfigToFile(KeystoreConfigRegistry keystoreConfigRegistry) throws IOException { Gson gson = new GsonBuilder().setPrettyPrinting().create(); String configAsJson = gson.toJson(keystoreConfigRegistry); Files.writeString(KeystoreConstants.KEYSTORE_CERTIFICATE_CONFIG_PATH, configAsJson); diff --git a/src/main/java/com/omb/ocpp/security/certificate/service/GetKeyStoreDetailsService.java b/src/main/java/com/omb/ocpp/security/certificate/service/GetKeyStoreDetailsService.java index d379c42..ed013a3 100644 --- a/src/main/java/com/omb/ocpp/security/certificate/service/GetKeyStoreDetailsService.java +++ b/src/main/java/com/omb/ocpp/security/certificate/service/GetKeyStoreDetailsService.java @@ -3,10 +3,18 @@ import com.omb.ocpp.security.certificate.api.KeystoreApi; import com.omb.ocpp.security.certificate.config.KeystoreCertificateConfig; +import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.security.KeyStore; -import java.util.*; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.UUID; import java.util.stream.Collectors; import static com.omb.ocpp.security.certificate.KeystoreConstants.TRUST_STORE_UUID; @@ -25,7 +33,7 @@ public List getKeyStores() throws Exception { getKeystoreCertificatesConfig(). stream(). filter(keystoreCertificateConfig -> !keystoreCertificateConfig.getUuid().equals(UUID.fromString(TRUST_STORE_UUID))). - map(config -> config.getUuid()). + map(KeystoreCertificateConfig::getUuid). collect(Collectors.toList()); return getKeyStores(keystoreUUIDs); @@ -49,7 +57,8 @@ public KeyStore getTrustStore() throws Exception { return loadKeyStore(keystoreCertificateConfig); } - private KeyStore loadKeyStore(KeystoreCertificateConfig config) throws Exception { + private KeyStore loadKeyStore(KeystoreCertificateConfig config) throws KeyStoreException, IOException, + CertificateException, NoSuchAlgorithmException { KeyStore keyStoreLocal = KeyStore.getInstance("JKS"); try (InputStream is = Files.newInputStream(config.getKeystorePath())) { keyStoreLocal.load(is, config.getKeystorePassword().toCharArray()); diff --git a/src/main/java/com/omb/ocpp/security/certificate/service/TrustStoreService.java b/src/main/java/com/omb/ocpp/security/certificate/service/TrustStoreService.java index a8950ca..6871d9d 100644 --- a/src/main/java/com/omb/ocpp/security/certificate/service/TrustStoreService.java +++ b/src/main/java/com/omb/ocpp/security/certificate/service/TrustStoreService.java @@ -37,6 +37,7 @@ @Service public class TrustStoreService { private static final Logger LOGGER = LoggerFactory.getLogger(TrustStoreService.class); + private static final String TRUST_STORE_ERROR_MESSAGE = "Could not get certificate from TrustStore"; private final KeystoreApi keystoreApi; private KeystoreCertificateConfig trustStoreConfig; @@ -107,7 +108,7 @@ public String getCertificateAsPem(X509Certificate certificate) { pemWriter.flush(); return writer.toString(); } catch (IOException e) { - LOGGER.error("Could not get certificate from TrustStore"); + LOGGER.error(TRUST_STORE_ERROR_MESSAGE); return ""; } } @@ -123,16 +124,16 @@ public Set getClientCertificates() { } } } catch (KeyStoreException e) { - LOGGER.error("Could not get certificate from TrustStore"); + LOGGER.error(TRUST_STORE_ERROR_MESSAGE); } return certificates; } public Optional> listAliasses() { try { - return Optional.ofNullable(Collections.list(trustStore.aliases())); + return Optional.of(Collections.list(trustStore.aliases())); } catch (KeyStoreException e) { - LOGGER.error("Could not get certificate from TrustStore"); + LOGGER.error(TRUST_STORE_ERROR_MESSAGE); return Optional.empty(); } }