Bulletin Board Server configuration support.
Bulletin Board Server signature testing.Bulletin_Board_Server_phase_1
parent
cbe3b5c765
commit
2ff34355e4
|
@ -1,6 +1,5 @@
|
||||||
package meerkat.bulletinboard.httpserver;
|
package meerkat.bulletinboard.httpserver;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.servlet.ServletConfig;
|
import javax.servlet.ServletConfig;
|
||||||
|
@ -16,7 +15,7 @@ import meerkat.protobuf.BulletinBoardAPI.*;
|
||||||
|
|
||||||
public class BulletinBoardHttpServer extends HttpServlet {
|
public class BulletinBoardHttpServer extends HttpServlet {
|
||||||
|
|
||||||
public final static File DEFAULT_MEERKAT_DB = new File("local-instances/meerkat.db");
|
public final static String DEFAULT_MEERKAT_DB = "local-instances/meerkat.db";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auto-generated UID.
|
* Auto-generated UID.
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package meerkat.bulletinboard.sqlserver;
|
package meerkat.bulletinboard.sqlserver;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ public abstract class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
* 2. Call this procedure
|
* 2. Call this procedure
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void init(File meerkatDB) throws CommunicationException {
|
public void init(String meerkatDB) throws CommunicationException {
|
||||||
// TODO write signature reading part.
|
// TODO write signature reading part.
|
||||||
|
|
||||||
digest = new SHA256Digest();
|
digest = new SHA256Digest();
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package meerkat.bulletinboard.sqlserver;
|
package meerkat.bulletinboard.sqlserver;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
@ -41,10 +40,10 @@ public class SQLiteBulletinBoardServer extends BulletinBoardSQLServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(File meerkatDB) throws CommunicationException {
|
public void init(String meerkatDB) throws CommunicationException {
|
||||||
|
|
||||||
try{
|
try{
|
||||||
String dbString = "jdbc:sqlite:" + meerkatDB.getPath();
|
String dbString = "jdbc:sqlite:" + meerkatDB;
|
||||||
connection = DriverManager.getConnection(dbString);
|
connection = DriverManager.getConnection(dbString);
|
||||||
createSchema();
|
createSchema();
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package meerkat.bulletinboard.webapp;
|
package meerkat.bulletinboard.webapp;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.servlet.ServletContext;
|
||||||
import javax.annotation.PreDestroy;
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import meerkat.bulletinboard.BulletinBoardServer;
|
import meerkat.bulletinboard.BulletinBoardServer;
|
||||||
|
@ -18,26 +20,55 @@ import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessageList;
|
||||||
import meerkat.protobuf.BulletinBoardAPI.MessageFilterList;
|
import meerkat.protobuf.BulletinBoardAPI.MessageFilterList;
|
||||||
import meerkat.rest.Constants;
|
import meerkat.rest.Constants;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
@Path("/sqlserver")
|
@Path("/sqlserver")
|
||||||
public class BulletinBoardWebApp implements BulletinBoardServer {
|
public class BulletinBoardWebApp implements BulletinBoardServer, ServletContextListener{
|
||||||
|
|
||||||
|
private static final String BULLETIN_BOARD_ATTRIBUTE_NAME = "bulletinBoard";
|
||||||
|
|
||||||
|
@Context ServletContext servletContext;
|
||||||
|
|
||||||
BulletinBoardServer bulletinBoard;
|
BulletinBoardServer bulletinBoard;
|
||||||
|
|
||||||
@PostConstruct
|
/**
|
||||||
|
* This is the servlet init method.
|
||||||
|
*/
|
||||||
|
public void init(){
|
||||||
|
bulletinBoard = (BulletinBoardServer) servletContext.getAttribute(BULLETIN_BOARD_ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the BulletinBoard init method.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void init(File meerkatDB) throws CommunicationException {
|
public void init(String meerkatDB) throws CommunicationException {
|
||||||
bulletinBoard = new SQLiteBulletinBoardServer();
|
|
||||||
bulletinBoard.init(meerkatDB);
|
bulletinBoard.init(meerkatDB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||||
|
ServletContext servletContext = servletContextEvent.getServletContext();
|
||||||
|
String meerkatDB = servletContext.getInitParameter("meerkatdb");
|
||||||
|
String dbType = servletContext.getInitParameter("dbtype");
|
||||||
|
|
||||||
|
if (dbType.compareTo("SQLite") == 0){
|
||||||
|
bulletinBoard = new SQLiteBulletinBoardServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
init(meerkatDB);
|
||||||
|
servletContext.setAttribute(BULLETIN_BOARD_ATTRIBUTE_NAME, bulletinBoard);
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Path("postmessage")
|
@Path("postmessage")
|
||||||
@POST
|
@POST
|
||||||
@Consumes(Constants.MEDIATYPE_PROTOBUF)
|
@Consumes(Constants.MEDIATYPE_PROTOBUF)
|
||||||
@Produces(Constants.MEDIATYPE_PROTOBUF)
|
@Produces(Constants.MEDIATYPE_PROTOBUF)
|
||||||
@Override
|
@Override
|
||||||
public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException {
|
public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException {
|
||||||
|
init();
|
||||||
return bulletinBoard.postMessage(msg);
|
return bulletinBoard.postMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,13 +78,17 @@ public class BulletinBoardWebApp implements BulletinBoardServer {
|
||||||
@Produces(Constants.MEDIATYPE_PROTOBUF)
|
@Produces(Constants.MEDIATYPE_PROTOBUF)
|
||||||
@Override
|
@Override
|
||||||
public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException {
|
public BulletinBoardMessageList readMessages(MessageFilterList filterList) throws CommunicationException {
|
||||||
|
init();
|
||||||
return bulletinBoard.readMessages(filterList);
|
return bulletinBoard.readMessages(filterList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PreDestroy
|
public void close(){
|
||||||
public void close() throws CommunicationException {
|
try {
|
||||||
bulletinBoard.close();
|
bulletinBoard.close();
|
||||||
|
} catch (CommunicationException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@ -62,4 +97,11 @@ public class BulletinBoardWebApp implements BulletinBoardServer {
|
||||||
return "This BulletinBoard is up and running!\n Please consult the API documents to perform queries.";
|
return "This BulletinBoard is up and running!\n Please consult the API documents to perform queries.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||||
|
ServletContext servletContext = servletContextEvent.getServletContext();
|
||||||
|
bulletinBoard = (BulletinBoardServer) servletContext.getAttribute(BULLETIN_BOARD_ATTRIBUTE_NAME);
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,4 +14,13 @@
|
||||||
<servlet-name>Jersey Hello World</servlet-name>
|
<servlet-name>Jersey Hello World</servlet-name>
|
||||||
<url-pattern>/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
<context-param>
|
||||||
|
<param-name>meerkatdb</param-name>
|
||||||
|
<param-value>meerkatdb</param-value></context-param>
|
||||||
|
<context-param>
|
||||||
|
<param-name>dbtype</param-name>
|
||||||
|
<param-value>SQLite</param-value></context-param>
|
||||||
|
<listener>
|
||||||
|
<listener-class>meerkat.bulletinboard.webapp.BulletinBoardWebApp</listener-class>
|
||||||
|
</listener>
|
||||||
</web-app>
|
</web-app>
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package meerkat.bulletinboard;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.NoSuchFileException;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import meerkat.bulletinboard.sqlserver.SQLiteBulletinBoardServer;
|
|
||||||
|
|
||||||
public class BulletinBoardServerTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAllServers() throws Exception {
|
|
||||||
GenericBulletinBoardServerTest bbst = new GenericBulletinBoardServerTest();
|
|
||||||
|
|
||||||
bbst.init(SQLiteBulletinBoardServer.class);
|
|
||||||
bbst.bulkTest();
|
|
||||||
bbst.close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
package meerkat.bulletinboard;
|
package meerkat.bulletinboard;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
@ -8,7 +7,6 @@ import java.security.InvalidKeyException;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.security.UnrecoverableKeyException;
|
import java.security.UnrecoverableKeyException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
@ -28,36 +26,57 @@ import meerkat.protobuf.BulletinBoardAPI.UnsignedBulletinBoardMessage;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
|
||||||
public class GenericBulletinBoardServerTest {
|
public abstract class GenericBulletinBoardServerTest {
|
||||||
private BulletinBoardServer bulletinBoardServer;
|
protected BulletinBoardServer bulletinBoardServer;
|
||||||
private ECDSASignature signers[];
|
private ECDSASignature signers[];
|
||||||
|
|
||||||
private Random random;
|
private Random random;
|
||||||
|
|
||||||
private static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12";
|
private static String KEYFILE_EXAMPLE = "/certs/enduser-certs/user1-key-with-password-secret.p12";
|
||||||
private static String KEYFILE_PASSWORD = "secret";
|
private static String KEYFILE_EXAMPLE3 = "/certs/enduser-certs/user3-key-with-password-shh.p12";
|
||||||
|
|
||||||
|
private static String KEYFILE_PASSWORD1 = "secret";
|
||||||
|
private static String KEYFILE_PASSWORD3 = "shh";
|
||||||
|
|
||||||
public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt";
|
public static String CERT1_PEM_EXAMPLE = "/certs/enduser-certs/user1.crt";
|
||||||
|
public static String CERT3_PEM_EXAMPLE = "/certs/enduser-certs/user3.crt";
|
||||||
|
|
||||||
// private static String KEYFILE_EXAMPLE2 = "/certs/enduser-certs/user2-key.pem";
|
/**
|
||||||
|
*
|
||||||
public void init(Class<?> cls) throws InstantiationException, IllegalAccessException, CertificateException, KeyStoreException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, CommunicationException{
|
* @param cls
|
||||||
bulletinBoardServer = (BulletinBoardServer) cls.newInstance();
|
* @throws InstantiationException
|
||||||
|
* @throws IllegalAccessException
|
||||||
bulletinBoardServer.init(File.createTempFile("meerkat-test", "db"));
|
* @throws CertificateException
|
||||||
|
* @throws KeyStoreException
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws UnrecoverableKeyException
|
||||||
|
* @throws CommunicationException
|
||||||
|
*/
|
||||||
|
public void init(String meerkatDB) throws InstantiationException, IllegalAccessException, CertificateException, KeyStoreException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, CommunicationException{
|
||||||
|
|
||||||
|
bulletinBoardServer.init(meerkatDB);
|
||||||
|
|
||||||
signers = new ECDSASignature[2];
|
signers = new ECDSASignature[2];
|
||||||
signers[0] = new ECDSASignature();
|
signers[0] = new ECDSASignature();
|
||||||
signers[1] = new ECDSASignature();
|
signers[1] = new ECDSASignature();
|
||||||
|
|
||||||
InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE);
|
InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE);
|
||||||
char[] password = KEYFILE_PASSWORD.toCharArray();
|
char[] password = KEYFILE_PASSWORD1.toCharArray();
|
||||||
|
|
||||||
KeyStore.Builder keyStore = signers[0].getPKCS12KeyStoreBuilder(keyStream, password);
|
KeyStore.Builder keyStoreBuilder = signers[0].getPKCS12KeyStoreBuilder(keyStream, password);
|
||||||
signers[0].loadSigningCertificate(keyStore);
|
signers[0].loadSigningCertificate(keyStoreBuilder);
|
||||||
|
|
||||||
signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE));
|
signers[0].loadVerificationCertificates(getClass().getResourceAsStream(CERT1_PEM_EXAMPLE));
|
||||||
|
|
||||||
|
keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE3);
|
||||||
|
password = KEYFILE_PASSWORD3.toCharArray();
|
||||||
|
|
||||||
|
keyStoreBuilder = signers[1].getPKCS12KeyStoreBuilder(keyStream, password);
|
||||||
|
signers[1].loadSigningCertificate(keyStoreBuilder);
|
||||||
|
|
||||||
|
signers[1].loadVerificationCertificates(getClass().getResourceAsStream(CERT3_PEM_EXAMPLE));
|
||||||
|
|
||||||
random = new Random(0); // We use insecure randomness in tests for repeatability
|
random = new Random(0); // We use insecure randomness in tests for repeatability
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +141,11 @@ public class GenericBulletinBoardServerTest {
|
||||||
if (i % 2 == 1){
|
if (i % 2 == 1){
|
||||||
signers[0].updateContent(msgBuilder.getMsg());
|
signers[0].updateContent(msgBuilder.getMsg());
|
||||||
msgBuilder.addSig(signers[0].sign());
|
msgBuilder.addSig(signers[0].sign());
|
||||||
|
|
||||||
|
if (i % 4 == 1){
|
||||||
|
signers[1].updateContent(msgBuilder.getMsg());
|
||||||
|
msgBuilder.addSig(signers[1].sign());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post message.
|
// Post message.
|
||||||
|
@ -166,6 +190,20 @@ public class GenericBulletinBoardServerTest {
|
||||||
signers[0].initVerify(msg.getSig(0));
|
signers[0].initVerify(msg.getSig(0));
|
||||||
signers[0].updateContent(msg.getMsg());
|
signers[0].updateContent(msg.getMsg());
|
||||||
assertTrue("Signature did not verify!", signers[0].verify());
|
assertTrue("Signature did not verify!", signers[0].verify());
|
||||||
|
|
||||||
|
if (msg.getEntryNum() % 4 == 1){
|
||||||
|
signers[1].initVerify(msg.getSig(1));
|
||||||
|
signers[1].updateContent(msg.getMsg());
|
||||||
|
assertTrue("Signature did not verify!", signers[1].verify());
|
||||||
|
|
||||||
|
assertThat(msg.getSigCount(), is(2));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
assertThat(msg.getSigCount(), is(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
assertThat(msg.getSigCount(), is(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ import javax.ws.rs.core.Response;
|
||||||
public class SQLiteServerIntegrationTest {
|
public class SQLiteServerIntegrationTest {
|
||||||
|
|
||||||
private static String PROP_GETTY_URL = "gretty.httpBaseURI";
|
private static String PROP_GETTY_URL = "gretty.httpBaseURI";
|
||||||
private static String DEFAULT_BASE_URL = "localhost:8081";
|
private static String DEFAULT_BASE_URL = "http://localhost:8081";
|
||||||
private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL);
|
private static String BASE_URL = System.getProperty(PROP_GETTY_URL, DEFAULT_BASE_URL);
|
||||||
private static String SQL_SERVER_POST = "sqlserver/postmessage";
|
private static String SQL_SERVER_POST = "sqlserver/postmessage";
|
||||||
private static String SQL_SERVER_GET = "sqlserver/readmessages";
|
private static String SQL_SERVER_GET = "sqlserver/readmessages";
|
||||||
|
@ -32,6 +32,7 @@ public class SQLiteServerIntegrationTest {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
|
System.err.println("Registering client");
|
||||||
client = ClientBuilder.newClient();
|
client = ClientBuilder.newClient();
|
||||||
client.register(ProtobufMessageBodyReader.class);
|
client.register(ProtobufMessageBodyReader.class);
|
||||||
client.register(ProtobufMessageBodyWriter.class);
|
client.register(ProtobufMessageBodyWriter.class);
|
||||||
|
@ -64,7 +65,11 @@ public class SQLiteServerIntegrationTest {
|
||||||
// Test writing mechanism
|
// Test writing mechanism
|
||||||
|
|
||||||
System.err.println("******** Testing: " + SQL_SERVER_POST);
|
System.err.println("******** Testing: " + SQL_SERVER_POST);
|
||||||
|
System.err.println(BASE_URL);
|
||||||
|
System.err.println(SQL_SERVER_POST);
|
||||||
|
System.err.println(client.getConfiguration());
|
||||||
webTarget = client.target(BASE_URL).path(SQL_SERVER_POST);
|
webTarget = client.target(BASE_URL).path(SQL_SERVER_POST);
|
||||||
|
System.err.println(webTarget.getUri());
|
||||||
|
|
||||||
msg = BulletinBoardMessage.newBuilder()
|
msg = BulletinBoardMessage.newBuilder()
|
||||||
.setMsg(UnsignedBulletinBoardMessage.newBuilder()
|
.setMsg(UnsignedBulletinBoardMessage.newBuilder()
|
||||||
|
|
|
@ -3,8 +3,6 @@ package meerkat.bulletinboard;
|
||||||
import meerkat.comm.CommunicationException;
|
import meerkat.comm.CommunicationException;
|
||||||
import meerkat.protobuf.BulletinBoardAPI.*;
|
import meerkat.protobuf.BulletinBoardAPI.*;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Arbel on 07/11/15.
|
* Created by Arbel on 07/11/15.
|
||||||
*
|
*
|
||||||
|
@ -19,7 +17,7 @@ public interface BulletinBoardServer{
|
||||||
* It also establishes the connection to the DB.
|
* It also establishes the connection to the DB.
|
||||||
* @throws CommunicationException on DB connection error.
|
* @throws CommunicationException on DB connection error.
|
||||||
*/
|
*/
|
||||||
public void init(File meerkatDB) throws CommunicationException;
|
public void init(String meerkatDB) throws CommunicationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post a message to bulletin board.
|
* Post a message to bulletin board.
|
||||||
|
|
Loading…
Reference in New Issue