Skip to content

Commit

Permalink
Merge pull request #3 from cne/develop
Browse files Browse the repository at this point in the history
KeyServer v0.2.3
  • Loading branch information
oscargdd committed Apr 15, 2016
2 parents 550fa2b + 24f0ed4 commit d7a7576
Show file tree
Hide file tree
Showing 23 changed files with 953 additions and 214 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
# KeyServer Change Log

v0.2.3
--------------------------------------------------------------------------------
Features:
- Multiple JSON processing on same TLS session.
- Improved security with IP access control.
- Support more cipher suites on https server.
- KeyServer Configuration more parametric.
- Include KeyServer Private Key provider tool.

v0.1.3
--------------------------------------------------------------------------------
Features:
- KeyServer accepts multiples connections (system default limited).
- KeyServer log to a file.
- KeyServer log to a file.
94 changes: 56 additions & 38 deletions KeyServer/pom.xml
Original file line number Diff line number Diff line change
@@ -1,46 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<name>KeyServer</name>
<url>https://pdihub.hi.inet/cne/cne-keyserver</url>
<modelVersion>4.0.0</modelVersion>
<!-- The Basics -->
<groupId>es.tid.keyserver</groupId>
<artifactId>keyserver</artifactId>
<version>v0.1.3</version>
<artifactId>KeyServer</artifactId>
<version>v0.2.3</version>
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

<developers>
<developer>
<id>jgm221</id>
<name>Javier Gusano Martinez</name>
<email>[email protected]</email>
<properties>
<active>true</active>
</properties>
</developer>
<developer>
<id>jgm1986</id>
<name>Javier Gusano Martinez</name>
<email>[email protected]</email>
<properties>
<active>true</active>
</properties>
</developer>
<developer>
<id>oscargdd</id>
<name>Oscar Gonzalez de Dios</name>
<email>[email protected]</email>
<properties>
<active>true</active>
</properties>
</developer>
</developers>

<dependencies>
<dependency>
<groupId>redis.clients</groupId>
Expand All @@ -62,7 +28,7 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
Expand All @@ -76,6 +42,13 @@
</dependency>
</dependencies>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<!-- Build Settings -->
<build>
<plugins>
<plugin>
Expand All @@ -90,8 +63,13 @@
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.8.1</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>package</phase>
Expand Down Expand Up @@ -120,4 +98,44 @@
</resource>
</resources>
</build>

<!-- More Project Information -->
<name>KeyServer</name>
<description>This tool is a Key Server software that implements the collaborative Solution API. It is intended to run in the Content Provider network. It is used to storage private keys from the Content Provider and reply to queries from the MSP Collaborative API.</description>
<url>https://github.com/mami-project/KeyServer</url>
<inceptionYear>2016</inceptionYear>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>manual</distribution>
<comments>License pending to determine.</comments>
</license>
</licenses>
<developers>
<developer>
<id>jgm1986</id>
<name>Javier Gusano Martinez</name>
<email>[email protected]</email>
<organization>Hewlett-Packard Enterprise</organization>
<organizationUrl>https://www.hpe.com</organizationUrl>
<timezone>(UTC+01:00) Brussels, Copenhagen, Madrid, Paris</timezone>
</developer>
</developers>

<contributors>
<contributor>
<name>Oscar Gonzalez de Dios</name>
<email>[email protected]</email>
<organization>Telefonica</organization>
<organizationUrl>http://www.tid.com</organizationUrl>
<timezone>(UTC+01:00) Brussels, Copenhagen, Madrid, Paris</timezone>
</contributor>
</contributors>

<!-- Environment Settings -->
<issueManagement>
<system>GitHub</system>
<url>https://github.com/mami-project/KeyServer/issues</url>
</issueManagement>
</project>
48 changes: 39 additions & 9 deletions KeyServer/src/main/java/es/tid/keyserver/config/ConfigFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,31 @@ public class ConfigFile implements CheckObject{
/**
* Flag for check if the object is correctly initialized.
*/
boolean isInitializated = false;
private boolean isInitializated = false;

/**
* Default class constructor.
* @param fileRoute Contains the name and route to the external
* configuration file.
* @param requiredFields Fields required inside configuration file.
*/
public ConfigFile(String fileRoute){
public ConfigFile(String fileRoute, String [] requiredFields){
File propertiesFile = new File(fileRoute);
String fileLocation;
if((propertiesFile.exists() && propertiesFile.canRead())){
fileLocation = fileRoute;
} else {
logger.warn("Can't access to the specified config file or "
+ "doesn't exists: {}", fileRoute);
System.out.print(" - New config file on default location...");
logger.info("New config file on default location...");
fileLocation = "general.properties";
newDefaultProperties(fileLocation);
}
configFile = new Properties();
// Load the config file parammeters.
// Load the configuration file parameters.
try {
configFile.load(new FileInputStream(fileLocation));
this.isInitializated = true;
this.isInitializated = checkFieldsPresent(requiredFields);
} catch (IOException ex) {
logger.error("Cannot load the configuration file for KeyServer.");
logger.trace("Exceiption message: {}", ex.toString());
Expand Down Expand Up @@ -92,17 +93,22 @@ private void newDefaultProperties(String fileLocation) {
try {
FileOutputStream newConfigFile = new FileOutputStream(fileLocation);
Properties defaultParameters = new Properties();
// Default parammeters:
defaultParameters.setProperty("serverAddress", "127.0.0.1");
// Default parameters:
defaultParameters.setProperty("serverAddress", "0.0.0.0");
defaultParameters.setProperty("serverPort", "443");
defaultParameters.setProperty("serverBacklog", "0");
defaultParameters.setProperty("serverSSLContext", "TLSv1.2");
defaultParameters.setProperty("serverKeyFile","HTTPS_keystore.ks");
defaultParameters.setProperty("serverKeyPass","123456");
defaultParameters.setProperty("serverBacklog", "0");
defaultParameters.setProperty("serverKeyManagerFactory", "SunX509");
defaultParameters.setProperty("serverTrustManagerFactory", "SunX509");
defaultParameters.setProperty("serverKeyStore", "JKS");
defaultParameters.setProperty("dbAddress","127.0.0.1");
defaultParameters.setProperty("dbPort", "6379");
defaultParameters.setProperty("whiteList", "IP_whitelist.txt");
// Save parameters on file
defaultParameters.store(newConfigFile, null);
// Close config file.
// Close configuration file.
newConfigFile.close();
} catch (FileNotFoundException ex) {
logger.error("Cannot create a new config file with default parameters.");
Expand All @@ -123,4 +129,28 @@ private void newDefaultProperties(String fileLocation) {
public boolean isCorrectlyInitialized() {
return isInitializated;
}

/**
* Checks if the required fields inside KeyServer configuration file are present.
* @param fields Array with the fields name.
* @return True if all is present, false if not.
*/
private boolean checkFieldsPresent(String [] fields){
for (String field : fields) {
if (!configFile.containsKey(field)) {
logger.error("Necessary config field is not present: {}", field);
return false;
}
}
return true;
}

/**
* Check if the specified label is present inside configuration file.
* @param label Label as string.
* @return True if exists, false if not.
*/
public boolean containsKey(String label){
return configFile.containsKey(label);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ public class DataBase implements CheckObject{
/**
* REDIS Database Connection Object
*/
Jedis dataBaseObj;
private Jedis dataBaseObj;

/**
* Flag for check if the object is correctly initialization.
*/
boolean isInitializated;
private boolean isInitializated;

/**
* Logging object.
Expand All @@ -51,9 +51,10 @@ public class DataBase implements CheckObject{
public DataBase(ConfigFile parameters){
JedisPool pool = new JedisPool(parameters.getParameter("dbAddress"), Integer.parseInt(parameters.getParameter("dbPort")));
try {
// Reddis connected.
// Redis connected.
dataBaseObj = pool.getResource();
isInitializated = true;
pool.close();
} catch (JedisConnectionException e) {
logger.debug("Database initialization failed.");
logger.trace("Database exception: {}", e.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.sun.net.httpserver.HttpsServer;
import es.tid.keyserver.config.ConfigFile;
import es.tid.keyserver.database.DataBase;
import es.tid.keyserver.httpkeyserver.whitelist.WhiteList;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
Expand All @@ -30,6 +31,9 @@
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
Expand All @@ -55,14 +59,14 @@ public class HttpKeyServer implements CheckObject{
/**
* Flag for check if the object is correctly initialized.
*/
boolean isInitializated = false;
private boolean isInitializated = false;
/**
* Main constructor for the HTTPS Server class.
* @param parameters Object with program parameters.
* @param objDB REDIS database Object.
* @see <a href="http://stackoverflow.com/questions/2308479/simple-java-https-server">More info about HttpsServer</a>
*/
public HttpKeyServer(ConfigFile parameters, DataBase objDB){
public HttpKeyServer(final ConfigFile parameters, DataBase objDB){
try {
// Getting the Server parameters from properties file.
int port = Integer.parseInt(parameters.getParameter("serverPort"));
Expand All @@ -71,16 +75,16 @@ public HttpKeyServer(ConfigFile parameters, DataBase objDB){
InetSocketAddress address = new InetSocketAddress ( ipaddress, port );
// Create basic Server object
server = HttpsServer.create();
SSLContext sslContext = SSLContext.getInstance("TLS");
// initialise the keystore
SSLContext sslContext = SSLContext.getInstance(parameters.getParameter("serverSSLContext"));
// Initialize the key store object
char[] keystorePassword = parameters.getParameter("serverKeyPass").toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ks = KeyStore.getInstance(parameters.getParameter("serverKeyStore"));
ks.load(new FileInputStream(parameters.getParameter("serverKeyFile")), keystorePassword);
// setup the key manager factory
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(parameters.getParameter("serverKeyManagerFactory"));
kmf.init(ks, keystorePassword);
// setup the trust manager factory
TrustManagerFactory tmf = TrustManagerFactory.getInstance ( "SunX509" );
TrustManagerFactory tmf = TrustManagerFactory.getInstance (parameters.getParameter("serverTrustManagerFactory"));
tmf.init ( ks );
// Setup the HTTPs context and parameters.
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
Expand All @@ -97,27 +101,62 @@ public HttpKeyServer(ConfigFile parameters, DataBase objDB){
@Override
public void configure(HttpsParameters params){
try {
// Initialise the SSL context
// Initialize the SSL context
SSLContext c = SSLContext.getDefault();
SSLEngine engine = c.createSSLEngine();
params.setNeedClientAuth(false);
params.setCipherSuites(engine.getEnabledCipherSuites());
params.setProtocols(engine.getEnabledProtocols());
// Get the default parameters
SSLParameters defaultSSLParameters = c.getDefaultSSLParameters();

if(parameters.containsKey("serverCiphersSuites") && getCiphers(parameters)!=null){
String [] ciphersuites = getCiphers(parameters);
defaultSSLParameters.setCipherSuites(ciphersuites);
}
params.setSSLParameters(defaultSSLParameters);
} catch (NoSuchAlgorithmException ex) {
logger.error("Problem with SSL context parameters.");
logger.trace("Exceiption message: {}", ex.toString());
}
}
/**
* This method parse the field string to array of values with
* the ciphers names. If the configuration label is not present
* inside configuration file. This, will use all available
* ciphers by default.
* @param parameters Configuration file object.
* @return Array of strings with the ciphers name.
*/
private String[] getCiphers(ConfigFile parameters) {
String [] returnValue = null;
String cipString = parameters.getParameter("serverCiphersSuites");
if(!cipString.equalsIgnoreCase("")){
List<String> items = Arrays.asList(cipString.split("\\s*,\\s*"));
returnValue = (String[]) items.toArray();
}
//logger.trace("List {} of ciphers inside KeyServer configuration file: {}", returnValue.length, returnValue);
return returnValue;
}
});
// Setting config for the server and accepting only BACKLOG variable
// as maximum input conection (0 = System default).
// Setting configuration for the server and accepting only BACKLOG variable
// as maximum input connection (0 = System default).
server.bind(address, backlog);
IncomingRequestProcess processor =new IncomingRequestProcess(objDB);
WhiteList allowedIPs = new WhiteList(parameters.getParameter("whiteList"));
IncomingRequestProcess processor =new IncomingRequestProcess(objDB, allowedIPs);
server.createContext("/", processor);
server.setExecutor(processor);
server.setExecutor(new Executor(){
/**
* Launch the runner for the incoming HTTP request. This method
* call to the handle method to process the incoming HTTP proxy
* request.
* @param r Runnable object for the incoming petition.
*/
@Override
public void execute(Runnable r) {
r.run();
}
});
// Starting server
server.start();
isInitializated = true;
Expand Down
Loading

0 comments on commit d7a7576

Please sign in to comment.