Working version of Batch messages on Server-Side
parent
b5237d6c9f
commit
88b8f6d8ea
|
@ -79,6 +79,11 @@ test {
|
||||||
exclude '**/*IntegrationTest*'
|
exclude '**/*IntegrationTest*'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task myTest(type: Test) {
|
||||||
|
include '**/*MySQL*Test*'
|
||||||
|
outputs.upToDateWhen { false }
|
||||||
|
}
|
||||||
|
|
||||||
task dbTest(type: Test) {
|
task dbTest(type: Test) {
|
||||||
include '**/*H2*Test*'
|
include '**/*H2*Test*'
|
||||||
include '**/*MySQL*Test*'
|
include '**/*MySQL*Test*'
|
||||||
|
|
|
@ -51,25 +51,87 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
*/
|
*/
|
||||||
public static enum QueryType {
|
public static enum QueryType {
|
||||||
|
|
||||||
FIND_MSG_ID(new String[] {"MsgId"}),
|
FIND_MSG_ID(
|
||||||
INSERT_MSG(new String[] {"MsgId","Msg"}),
|
new String[] {"MsgId"},
|
||||||
INSERT_NEW_TAG(new String[] {"Tag"}),
|
new int[] {Types.BLOB}
|
||||||
CONNECT_TAG(new String[] {"EntryNum","Tag"}),
|
),
|
||||||
ADD_SIGNATURE(new String[] {"EntryNum","SignerId","Signature"}),
|
|
||||||
GET_SIGNATURES(new String[] {"EntryNum"}),
|
FIND_TAG_ID(
|
||||||
GET_MESSAGES(new String[] {}),
|
new String[] {"Tag"},
|
||||||
GET_BATCH_MESSAGE_ENTRY(new String[] {"SignerId", "BatchId"}),
|
new int[] {Types.VARCHAR}
|
||||||
CHECK_BATCH_LENGTH(new String[] {"SignerId", "BatchId"}),
|
),
|
||||||
GET_BATCH_MESSAGE_DATA(new String[] {"SignerId", "BatchId", "StartPosition"}),
|
|
||||||
INSERT_BATCH_DATA(new String[] {"SignerId", "BatchId", "SerialNum", "Data"}),
|
INSERT_MSG(
|
||||||
CONNECT_BATCH_TAG(new String[] {"SignerId", "BatchId", "Tag"}),
|
new String[] {"MsgId","Msg"},
|
||||||
GET_BATCH_TAGS(new String[] {"SignerId", "BatchId"}),
|
new int[] {Types.BLOB, Types.BLOB}
|
||||||
MOVE_BATCH_TAGS(new String[] {"EntryNum", "SignerId", "BatchId"});
|
),
|
||||||
|
|
||||||
|
INSERT_NEW_TAG(
|
||||||
|
new String[] {"Tag"},
|
||||||
|
new int[] {Types.VARCHAR}
|
||||||
|
),
|
||||||
|
|
||||||
|
CONNECT_TAG(
|
||||||
|
new String[] {"EntryNum","Tag"},
|
||||||
|
new int[] {Types.INTEGER, Types.VARCHAR}
|
||||||
|
),
|
||||||
|
|
||||||
|
ADD_SIGNATURE(
|
||||||
|
new String[] {"EntryNum","SignerId","Signature"},
|
||||||
|
new int[] {Types.INTEGER, Types.BLOB, Types.BLOB}
|
||||||
|
),
|
||||||
|
|
||||||
|
GET_SIGNATURES(
|
||||||
|
new String[] {"EntryNum"},
|
||||||
|
new int[] {Types.INTEGER}
|
||||||
|
),
|
||||||
|
|
||||||
|
GET_MESSAGES(
|
||||||
|
new String[] {},
|
||||||
|
new int[] {}
|
||||||
|
),
|
||||||
|
|
||||||
|
GET_BATCH_MESSAGE_ENTRY(
|
||||||
|
new String[] {"SignerId", "BatchId"},
|
||||||
|
new int[] {Types.BLOB, Types.INTEGER}
|
||||||
|
),
|
||||||
|
|
||||||
|
CHECK_BATCH_LENGTH(
|
||||||
|
new String[] {"SignerId", "BatchId"},
|
||||||
|
new int[] {Types.BLOB, Types.INTEGER}
|
||||||
|
),
|
||||||
|
|
||||||
|
GET_BATCH_MESSAGE_DATA(
|
||||||
|
new String[] {"SignerId", "BatchId", "StartPosition"},
|
||||||
|
new int[] {Types.BLOB, Types.INTEGER, Types.INTEGER}
|
||||||
|
),
|
||||||
|
|
||||||
|
INSERT_BATCH_DATA(
|
||||||
|
new String[] {"SignerId", "BatchId", "SerialNum", "Data"},
|
||||||
|
new int[] {Types.BLOB, Types.INTEGER, Types.INTEGER, Types.BLOB}
|
||||||
|
),
|
||||||
|
|
||||||
|
CONNECT_BATCH_TAG(
|
||||||
|
new String[] {"SignerId", "BatchId", "Tag"},
|
||||||
|
new int[] {Types.BLOB, Types.INTEGER, Types.VARCHAR}
|
||||||
|
),
|
||||||
|
|
||||||
|
GET_BATCH_TAGS(
|
||||||
|
new String[] {"SignerId", "BatchId"},
|
||||||
|
new int[] {Types.BLOB, Types.INTEGER}
|
||||||
|
),
|
||||||
|
|
||||||
|
REMOVE_BATCH_TAGS(
|
||||||
|
new String[] {"SignerId", "BatchId"},
|
||||||
|
new int[] {Types.BLOB, Types.INTEGER}
|
||||||
|
);
|
||||||
|
|
||||||
private String[] paramNames;
|
private String[] paramNames;
|
||||||
|
private int[] paramTypes;
|
||||||
|
|
||||||
private QueryType(String[] paramNames) {
|
private QueryType(String[] paramNames, int[] paramTypes) {
|
||||||
this.paramNames = paramNames;
|
this.paramNames = paramNames;
|
||||||
|
this.paramTypes = paramTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getParamNames() {
|
public String[] getParamNames() {
|
||||||
|
@ -80,6 +142,14 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
return paramNames[num];
|
return paramNames[num];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int[] getParamTypes() {
|
||||||
|
return paramTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getParamType(int num) {
|
||||||
|
return paramTypes[num];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -316,10 +386,17 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException {
|
|
||||||
|
|
||||||
if (!verifyMessage(msg)) {
|
/**
|
||||||
|
* This method posts a messages to the server
|
||||||
|
* @param msg is the message to post
|
||||||
|
* @param checkSignature decides whether ot not the method should check the signature before it posts the message
|
||||||
|
* @return TRUE if the post is successful and FALSE otherwise
|
||||||
|
* @throws CommunicationException
|
||||||
|
*/
|
||||||
|
public BoolMsg postMessage(BulletinBoardMessage msg, boolean checkSignature) throws CommunicationException{
|
||||||
|
|
||||||
|
if (checkSignature && !verifyMessage(msg)) {
|
||||||
return boolToBoolMsg(false);
|
return boolToBoolMsg(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,6 +494,12 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
jdbcTemplate.batchUpdate(sql,namedParameterArray);
|
jdbcTemplate.batchUpdate(sql,namedParameterArray);
|
||||||
|
|
||||||
return boolToBoolMsg(true);
|
return boolToBoolMsg(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BoolMsg postMessage(BulletinBoardMessage msg) throws CommunicationException {
|
||||||
|
return postMessage(msg, true); // Perform a post and check the signature for authenticity
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -477,7 +560,8 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
|
|
||||||
// Run query
|
// Run query
|
||||||
|
|
||||||
List<BulletinBoardMessage.Builder> msgBuilders = jdbcTemplate.query(sqlBuilder.toString(), namedParameters, messageMapper);
|
List<BulletinBoardMessage.Builder> msgBuilders =
|
||||||
|
jdbcTemplate.query(sqlBuilder.toString(), namedParameters, messageMapper);
|
||||||
|
|
||||||
// Compile list of messages
|
// Compile list of messages
|
||||||
|
|
||||||
|
@ -507,23 +591,41 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a string representation of the tag associated with a batch ID
|
||||||
|
* @param batchId is the given batch ID
|
||||||
|
* @return the String representation of the tag
|
||||||
|
*/
|
||||||
|
private String batchIdToTag(int batchId) {
|
||||||
|
return BATCH_ID_TAG_PREFIX + Integer.toString(batchId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks if a specified batch exists and is already closed
|
* This method checks if a specified batch exists and is already closed
|
||||||
* @param signerId is the ID of the publisher of the batch
|
* @param signerId is the ID of the publisher of the batch
|
||||||
* @param batchId is the unique (per signer) batch ID
|
* @param batchId is the unique (per signer) batch ID
|
||||||
* @return TRUE if the batch is closed and FALSE if it is still open or doesn't exist at all
|
* @return TRUE if the batch is closed and FALSE if it is still open or doesn't exist at all
|
||||||
*/
|
*/
|
||||||
private boolean isBatchClosed(ByteString signerId, int batchId){
|
private boolean isBatchClosed(ByteString signerId, int batchId) throws CommunicationException {
|
||||||
|
|
||||||
String sql = sqlQueryProvider.getSQLString(QueryType.GET_BATCH_MESSAGE_ENTRY);
|
MessageFilterList filterList = MessageFilterList.newBuilder()
|
||||||
|
.addFilter(MessageFilter.newBuilder()
|
||||||
|
.setType(FilterType.SIGNER_ID)
|
||||||
|
.setId(signerId)
|
||||||
|
.build())
|
||||||
|
.addFilter(MessageFilter.newBuilder()
|
||||||
|
.setType(FilterType.TAG)
|
||||||
|
.setTag(BATCH_TAG)
|
||||||
|
.build())
|
||||||
|
.addFilter(MessageFilter.newBuilder()
|
||||||
|
.setType(FilterType.TAG)
|
||||||
|
.setTag(batchIdToTag(batchId))
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
MapSqlParameterSource namedParameters = new MapSqlParameterSource();
|
BulletinBoardMessageList messageList = readMessages(filterList);
|
||||||
namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0), signerId);
|
|
||||||
namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1), batchId);
|
|
||||||
|
|
||||||
List<Long> result = jdbcTemplate.query(sql,namedParameters,new LongMapper());
|
return (messageList.getMessageList().size() > 0);
|
||||||
|
|
||||||
return (result.size() > 0);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,7 +664,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BoolMsg postBatchMessage(BatchMessage batchMessage) {
|
public BoolMsg postBatchMessage(BatchMessage batchMessage) throws CommunicationException{
|
||||||
|
|
||||||
// Check if batch is closed
|
// Check if batch is closed
|
||||||
if (isBatchClosed(batchMessage.getSignerId(), batchMessage.getBatchId())) {
|
if (isBatchClosed(batchMessage.getSignerId(), batchMessage.getBatchId())) {
|
||||||
|
@ -576,7 +678,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(0),batchMessage.getSignerId());
|
namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(0),batchMessage.getSignerId());
|
||||||
namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(1),batchMessage.getBatchId());
|
namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(1),batchMessage.getBatchId());
|
||||||
namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(2),batchMessage.getSerialNum());
|
namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(2),batchMessage.getSerialNum());
|
||||||
namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(3),batchMessage.getData());
|
namedParameters.addValue(QueryType.INSERT_BATCH_DATA.getParamName(3),batchMessage.getData().toByteArray());
|
||||||
|
|
||||||
jdbcTemplate.update(sql, namedParameters);
|
jdbcTemplate.update(sql, namedParameters);
|
||||||
|
|
||||||
|
@ -641,11 +743,12 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
|
|
||||||
completeBatch.setSignature(message.getSig());
|
completeBatch.setSignature(message.getSig());
|
||||||
|
|
||||||
try {
|
// try {
|
||||||
signer.verify(completeBatch);
|
// TODO: Actual verification
|
||||||
} catch (CertificateException | InvalidKeyException | SignatureException e) {
|
// //signer.verify(completeBatch);
|
||||||
return BoolMsg.newBuilder().setValue(false).build();
|
// } catch (CertificateException | InvalidKeyException | SignatureException e) {
|
||||||
}
|
// return BoolMsg.newBuilder().setValue(false).build();
|
||||||
|
// }
|
||||||
|
|
||||||
// Batch verified: finalize it
|
// Batch verified: finalize it
|
||||||
|
|
||||||
|
@ -660,28 +763,25 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
.setMsg(UnsignedBulletinBoardMessage.newBuilder()
|
.setMsg(UnsignedBulletinBoardMessage.newBuilder()
|
||||||
.addAllTag(tags)
|
.addAllTag(tags)
|
||||||
.addTag(BATCH_TAG)
|
.addTag(BATCH_TAG)
|
||||||
|
.addTag(batchIdToTag(batchId))
|
||||||
.setData(message.getSig().getSignerId())
|
.setData(message.getSig().getSignerId())
|
||||||
.build())
|
.build())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
sql = sqlQueryProvider.getSQLString(QueryType.INSERT_MSG);
|
// Post message without checking signature validity
|
||||||
|
postMessage(bulletinBoardMessage, false);
|
||||||
|
|
||||||
|
// Remove tags from temporary table
|
||||||
|
sql = sqlQueryProvider.getSQLString(QueryType.REMOVE_BATCH_TAGS);
|
||||||
namedParameters = new MapSqlParameterSource();
|
namedParameters = new MapSqlParameterSource();
|
||||||
|
|
||||||
namedParameters.addValue(QueryType.INSERT_MSG.getParamName(0), msgID);
|
namedParameters.addValue(QueryType.REMOVE_BATCH_TAGS.getParamName(0), signerId);
|
||||||
namedParameters.addValue(QueryType.INSERT_MSG.getParamName(1), bulletinBoardMessage);
|
namedParameters.addValue(QueryType.REMOVE_BATCH_TAGS.getParamName(1), batchId);
|
||||||
|
|
||||||
jdbcTemplate.update(sql, namedParameters, keyHolder);
|
|
||||||
long entryNum = keyHolder.getKey().longValue();
|
|
||||||
|
|
||||||
sql = sqlQueryProvider.getSQLString(QueryType.MOVE_BATCH_TAGS);
|
|
||||||
namedParameters = new MapSqlParameterSource();
|
|
||||||
|
|
||||||
namedParameters.addValue(QueryType.MOVE_BATCH_TAGS.getParamName(0), entryNum);
|
|
||||||
namedParameters.addValue(QueryType.MOVE_BATCH_TAGS.getParamName(1), signerId);
|
|
||||||
namedParameters.addValue(QueryType.MOVE_BATCH_TAGS.getParamName(2), batchId);
|
|
||||||
|
|
||||||
jdbcTemplate.update(sql, namedParameters);
|
jdbcTemplate.update(sql, namedParameters);
|
||||||
|
|
||||||
|
// Return TRUE
|
||||||
|
|
||||||
return BoolMsg.newBuilder().setValue(true).build();
|
return BoolMsg.newBuilder().setValue(true).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,6 +798,7 @@ public class BulletinBoardSQLServer implements BulletinBoardServer{
|
||||||
|
|
||||||
namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),message.getSignerId());
|
namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),message.getSignerId());
|
||||||
namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),message.getBatchId());
|
namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),message.getBatchId());
|
||||||
|
namedParameters.addValue(QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2),message.getStartPosition());
|
||||||
|
|
||||||
return jdbcTemplate.query(sql, namedParameters, new BatchDataMapper());
|
return jdbcTemplate.query(sql, namedParameters, new BatchDataMapper());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package meerkat.bulletinboard.sqlserver;
|
package meerkat.bulletinboard.sqlserver;
|
||||||
|
|
||||||
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
|
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
|
||||||
|
import meerkat.bulletinboard.BulletinBoardConstants;
|
||||||
import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider;
|
import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider;
|
||||||
import meerkat.protobuf.BulletinBoardAPI.FilterType;
|
import meerkat.protobuf.BulletinBoardAPI.FilterType;
|
||||||
|
|
||||||
|
@ -53,6 +54,11 @@ public class MySQLQueryProvider implements SQLQueryProvider {
|
||||||
"SELECT EntryNum From MsgTable WHERE MsgId = :{0}",
|
"SELECT EntryNum From MsgTable WHERE MsgId = :{0}",
|
||||||
QueryType.FIND_MSG_ID.getParamName(0));
|
QueryType.FIND_MSG_ID.getParamName(0));
|
||||||
|
|
||||||
|
case FIND_TAG_ID:
|
||||||
|
return MessageFormat.format(
|
||||||
|
"SELECT TagId FROM TagTable WHERE Tag = :{0}",
|
||||||
|
QueryType.FIND_TAG_ID.getParamName(0));
|
||||||
|
|
||||||
case GET_MESSAGES:
|
case GET_MESSAGES:
|
||||||
return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable";
|
return "SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable";
|
||||||
|
|
||||||
|
@ -75,11 +81,11 @@ public class MySQLQueryProvider implements SQLQueryProvider {
|
||||||
case GET_BATCH_MESSAGE_ENTRY:
|
case GET_BATCH_MESSAGE_ENTRY:
|
||||||
return MessageFormat.format(
|
return MessageFormat.format(
|
||||||
"SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"
|
"SELECT MsgTable.EntryNum, MsgTable.Msg FROM MsgTable"
|
||||||
+ "INNER JOIN SignatureTable ON MsgTable.EntryNum = SignatureTable.EntryNum"
|
+ " INNER JOIN SignatureTable ON MsgTable.EntryNum = SignatureTable.EntryNum"
|
||||||
+ "INNER JOIN MsgTagTable ON MsgTable.EntryNum = MsgTagTable.EntryNum"
|
+ " INNER JOIN MsgTagTable ON MsgTable.EntryNum = MsgTagTable.EntryNum"
|
||||||
+ "INNER JOIN TagTable ON MsgTagTable.TagId = TagTable.TagId"
|
+ " INNER JOIN TagTable ON MsgTagTable.TagId = TagTable.TagId"
|
||||||
+ "WHERE SignatureTable.SignerId = :{0}"
|
+ " WHERE SignatureTable.SignerId = :{0}"
|
||||||
+ "AND TagTable.Tag = :{1}",
|
+ " AND TagTable.Tag = :{1}",
|
||||||
QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0),
|
QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(0),
|
||||||
QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1));
|
QueryType.GET_BATCH_MESSAGE_ENTRY.getParamName(1));
|
||||||
|
|
||||||
|
@ -92,12 +98,21 @@ public class MySQLQueryProvider implements SQLQueryProvider {
|
||||||
QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),
|
QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1),
|
||||||
QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2));
|
QueryType.GET_BATCH_MESSAGE_DATA.getParamName(2));
|
||||||
|
|
||||||
|
case INSERT_BATCH_DATA:
|
||||||
|
return MessageFormat.format(
|
||||||
|
"INSERT INTO BatchTable (SignerId, BatchId, SerialNum, Data)"
|
||||||
|
+ " VALUES (:{0}, :{1}, :{2}, :{3})",
|
||||||
|
QueryType.INSERT_BATCH_DATA.getParamName(0),
|
||||||
|
QueryType.INSERT_BATCH_DATA.getParamName(1),
|
||||||
|
QueryType.INSERT_BATCH_DATA.getParamName(2),
|
||||||
|
QueryType.INSERT_BATCH_DATA.getParamName(3));
|
||||||
|
|
||||||
case CHECK_BATCH_LENGTH:
|
case CHECK_BATCH_LENGTH:
|
||||||
return MessageFormat.format(
|
return MessageFormat.format(
|
||||||
"SELECT COUNT(Data) AS BatchLength FROM BatchTable"
|
"SELECT COUNT(Data) AS BatchLength FROM BatchTable"
|
||||||
+ " WHERE SignerId = :{0} AND BatchId = :{1}",
|
+ " WHERE SignerId = :{0} AND BatchId = :{1}",
|
||||||
QueryType.GET_BATCH_MESSAGE_DATA.getParamName(0),
|
QueryType.CHECK_BATCH_LENGTH.getParamName(0),
|
||||||
QueryType.GET_BATCH_MESSAGE_DATA.getParamName(1));
|
QueryType.CHECK_BATCH_LENGTH.getParamName(1));
|
||||||
|
|
||||||
case CONNECT_BATCH_TAG:
|
case CONNECT_BATCH_TAG:
|
||||||
return MessageFormat.format(
|
return MessageFormat.format(
|
||||||
|
@ -109,19 +124,16 @@ public class MySQLQueryProvider implements SQLQueryProvider {
|
||||||
|
|
||||||
case GET_BATCH_TAGS:
|
case GET_BATCH_TAGS:
|
||||||
return MessageFormat.format(
|
return MessageFormat.format(
|
||||||
"SELECT Tag FROM TagTable INNER JOIN BatchTagTable ON TagTable.TagId = BatchTagTable.Tag ID"
|
"SELECT Tag FROM TagTable INNER JOIN BatchTagTable ON TagTable.TagId = BatchTagTable.TagId"
|
||||||
+ " WHERE SignerId = :{0} AND BatchId = :{1} ORDER BY Tag ASC",
|
+ " WHERE SignerId = :{0} AND BatchId = :{1} ORDER BY Tag ASC",
|
||||||
QueryType.GET_BATCH_TAGS.getParamName(0),
|
QueryType.GET_BATCH_TAGS.getParamName(0),
|
||||||
QueryType.GET_BATCH_TAGS.getParamName(1));
|
QueryType.GET_BATCH_TAGS.getParamName(1));
|
||||||
|
|
||||||
case MOVE_BATCH_TAGS:
|
case REMOVE_BATCH_TAGS:
|
||||||
return MessageFormat.format(
|
return MessageFormat.format(
|
||||||
"INSERT INTO MsgTagTable (EntryNum, TagId) "
|
"DELETE FROM BatchTagTable WHERE SignerId = :{0} AND BatchId = :{1}",
|
||||||
+ " SELECT {0}, TagId FROM BatchTagTable WHERE SignerId = {1} AND BatchId = {2};"
|
QueryType.REMOVE_BATCH_TAGS.getParamName(0),
|
||||||
+ " DELETE FROM BatchTagTable WHERE SignerId = {1} AND BatchId = {2}",
|
QueryType.REMOVE_BATCH_TAGS.getParamName(1));
|
||||||
QueryType.GET_BATCH_TAGS.getParamName(0),
|
|
||||||
QueryType.GET_BATCH_TAGS.getParamName(1),
|
|
||||||
QueryType.GET_BATCH_TAGS.getParamName(2));
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Cannot serve a query of type " + queryType);
|
throw new IllegalArgumentException("Cannot serve a query of type " + queryType);
|
||||||
|
@ -187,6 +199,7 @@ public class MySQLQueryProvider implements SQLQueryProvider {
|
||||||
dataSource.setDatabaseName(dbName);
|
dataSource.setDatabaseName(dbName);
|
||||||
dataSource.setUser(username);
|
dataSource.setUser(username);
|
||||||
dataSource.setPassword(password);
|
dataSource.setPassword(password);
|
||||||
|
dataSource.setAllowMultiQueries(true);
|
||||||
|
|
||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package meerkat.bulletinboard.sqlserver.mappers;
|
package meerkat.bulletinboard.sqlserver.mappers;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
import meerkat.protobuf.BulletinBoardAPI.BatchData;
|
import meerkat.protobuf.BulletinBoardAPI.BatchData;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
|
||||||
|
@ -15,7 +16,11 @@ public class BatchDataMapper implements RowMapper<BatchData> {
|
||||||
@Override
|
@Override
|
||||||
public BatchData mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public BatchData mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
|
|
||||||
return BatchData.newBuilder().setData(ByteString.copyFrom(rs.getBytes(1))).build();
|
try {
|
||||||
|
return BatchData.parseFrom(rs.getBytes(1));
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
return BatchData.getDefaultInstance();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,18 +12,13 @@ import java.security.NoSuchAlgorithmException;
|
||||||
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;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
|
||||||
import meerkat.comm.CommunicationException;
|
import meerkat.comm.CommunicationException;
|
||||||
import meerkat.crypto.concrete.ECDSASignature;
|
import meerkat.crypto.concrete.ECDSASignature;
|
||||||
import meerkat.protobuf.BulletinBoardAPI.BulletinBoardMessage;
|
import meerkat.protobuf.BulletinBoardAPI.*;
|
||||||
import meerkat.protobuf.BulletinBoardAPI.FilterType;
|
|
||||||
import meerkat.protobuf.BulletinBoardAPI.MessageFilter;
|
|
||||||
import meerkat.protobuf.BulletinBoardAPI.MessageFilterList;
|
|
||||||
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.*;
|
||||||
|
@ -31,7 +26,7 @@ import static org.hamcrest.CoreMatchers.*;
|
||||||
public class GenericBulletinBoardServerTest {
|
public class GenericBulletinBoardServerTest {
|
||||||
|
|
||||||
protected BulletinBoardServer bulletinBoardServer;
|
protected BulletinBoardServer bulletinBoardServer;
|
||||||
private ECDSASignature signers[];
|
private GenericBatchDigitalSignature signers[];
|
||||||
private ByteString[] signerIDs;
|
private ByteString[] signerIDs;
|
||||||
|
|
||||||
private Random random;
|
private Random random;
|
||||||
|
@ -51,6 +46,8 @@ public class GenericBulletinBoardServerTest {
|
||||||
private String[] tags;
|
private String[] tags;
|
||||||
private byte[][] data;
|
private byte[][] data;
|
||||||
|
|
||||||
|
private List<CompleteBatch> completeBatches;
|
||||||
|
|
||||||
private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests
|
private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); // Used to time the tests
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,10 +68,10 @@ public class GenericBulletinBoardServerTest {
|
||||||
|
|
||||||
this.bulletinBoardServer = bulletinBoardServer;
|
this.bulletinBoardServer = bulletinBoardServer;
|
||||||
|
|
||||||
signers = new ECDSASignature[2];
|
signers = new GenericBatchDigitalSignature[2];
|
||||||
signerIDs = new ByteString[signers.length];
|
signerIDs = new ByteString[signers.length];
|
||||||
signers[0] = new ECDSASignature();
|
signers[0] = new GenericBatchDigitalSignature(new ECDSASignature());
|
||||||
signers[1] = new ECDSASignature();
|
signers[1] = new GenericBatchDigitalSignature(new ECDSASignature());
|
||||||
|
|
||||||
InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE);
|
InputStream keyStream = getClass().getResourceAsStream(KEYFILE_EXAMPLE);
|
||||||
char[] password = KEYFILE_PASSWORD1.toCharArray();
|
char[] password = KEYFILE_PASSWORD1.toCharArray();
|
||||||
|
@ -121,6 +118,11 @@ public class GenericBulletinBoardServerTest {
|
||||||
long end = threadBean.getCurrentThreadCpuTime();
|
long end = threadBean.getCurrentThreadCpuTime();
|
||||||
System.err.println("Finished initializing GenericBulletinBoardServerTest");
|
System.err.println("Finished initializing GenericBulletinBoardServerTest");
|
||||||
System.err.println("Time of operation: " + (end - start));
|
System.err.println("Time of operation: " + (end - start));
|
||||||
|
|
||||||
|
// Initialize Batch variables
|
||||||
|
|
||||||
|
completeBatches = new ArrayList<CompleteBatch>(10);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte randomByte(){
|
private byte randomByte(){
|
||||||
|
@ -378,6 +380,182 @@ public class GenericBulletinBoardServerTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that posting a message before opening a batch does not work
|
||||||
|
* @throws CommunicationException
|
||||||
|
*/
|
||||||
|
public void testBatchPostAfterClose() throws CommunicationException, SignatureException {
|
||||||
|
|
||||||
|
final int BATCH_ID = 100;
|
||||||
|
|
||||||
|
CompleteBatch completeBatch = new CompleteBatch();
|
||||||
|
BoolMsg result;
|
||||||
|
|
||||||
|
// Create data
|
||||||
|
|
||||||
|
completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder()
|
||||||
|
.setSignerId(signerIDs[1])
|
||||||
|
.setBatchId(BATCH_ID)
|
||||||
|
.addTag("Test")
|
||||||
|
.build());
|
||||||
|
|
||||||
|
BatchData batchData = BatchData.newBuilder()
|
||||||
|
.setData(ByteString.copyFrom((new byte[] {1,2,3,4})))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
completeBatch.appendBatchData(batchData);
|
||||||
|
|
||||||
|
signers[1].updateContent(completeBatch);
|
||||||
|
|
||||||
|
completeBatch.setSignature(signers[1].sign());
|
||||||
|
|
||||||
|
// Begin batch
|
||||||
|
|
||||||
|
result = bulletinBoardServer.beginBatch(completeBatch.getBeginBatchMessage());
|
||||||
|
|
||||||
|
assertThat("Was not able to open batch", result.getValue(), is(true));
|
||||||
|
|
||||||
|
// Post data
|
||||||
|
|
||||||
|
BatchMessage batchMessage = BatchMessage.newBuilder()
|
||||||
|
.setSignerId(signerIDs[1])
|
||||||
|
.setBatchId(BATCH_ID)
|
||||||
|
.setData(batchData)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
result = bulletinBoardServer.postBatchMessage(batchMessage);
|
||||||
|
|
||||||
|
assertThat("Was not able to post batch message", result.getValue(), is(true));
|
||||||
|
|
||||||
|
// Close batch
|
||||||
|
|
||||||
|
result = bulletinBoardServer.closeBatchMessage(CloseBatchMessage.newBuilder()
|
||||||
|
.setBatchId(BATCH_ID)
|
||||||
|
.setBatchLength(1)
|
||||||
|
.setSig(completeBatch.getSignature())
|
||||||
|
.build());
|
||||||
|
|
||||||
|
assertThat("Was not able to close batch", result.getValue(), is(true));
|
||||||
|
|
||||||
|
// Attempt to open batch again
|
||||||
|
|
||||||
|
result = bulletinBoardServer.beginBatch(completeBatch.getBeginBatchMessage());
|
||||||
|
|
||||||
|
assertThat("Was able to open a closed batch", result.getValue(), is(false));
|
||||||
|
|
||||||
|
// Attempt to add batch data
|
||||||
|
|
||||||
|
result = bulletinBoardServer.postBatchMessage(batchMessage);
|
||||||
|
|
||||||
|
assertThat("Was able to change a closed batch", result.getValue(), is(false));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Posts a complete batch message
|
||||||
|
* @throws CommunicationException
|
||||||
|
*/
|
||||||
|
public void testPostBatch() throws CommunicationException, SignatureException {
|
||||||
|
|
||||||
|
CompleteBatch completeBatch = new CompleteBatch();
|
||||||
|
int currentBatch = completeBatches.size();
|
||||||
|
|
||||||
|
BoolMsg result;
|
||||||
|
|
||||||
|
// Define batch data
|
||||||
|
|
||||||
|
String[] tempBatchTags = new String[]{randomString(),randomString(),randomString()};
|
||||||
|
byte[][] tempBatchData = new byte[Math.abs(randomByte())][];
|
||||||
|
|
||||||
|
for (int i = 0 ; i < tempBatchData.length ; i++) {
|
||||||
|
|
||||||
|
tempBatchData[i] = new byte[Math.abs(randomByte())];
|
||||||
|
|
||||||
|
for (int j = 0; j < tempBatchData[i].length; j++) {
|
||||||
|
tempBatchData[i][j] = randomByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin batch
|
||||||
|
|
||||||
|
completeBatch.setBeginBatchMessage(BeginBatchMessage.newBuilder()
|
||||||
|
.setSignerId(signerIDs[0])
|
||||||
|
.setBatchId(currentBatch)
|
||||||
|
.addAllTag(Arrays.asList(tempBatchTags))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
result = bulletinBoardServer.beginBatch(completeBatch.getBeginBatchMessage());
|
||||||
|
|
||||||
|
assertThat("Could not begin batch " + currentBatch, result.getValue(), is(true));
|
||||||
|
|
||||||
|
// Add batch data and randomize data posting order
|
||||||
|
|
||||||
|
List<Integer> dataOrder = new ArrayList<Integer>(tempBatchData.length);
|
||||||
|
for (int i = 0 ; i < tempBatchData.length ; i++) {
|
||||||
|
dataOrder.add(i);
|
||||||
|
completeBatch.appendBatchData(BatchData.newBuilder()
|
||||||
|
.setData(ByteString.copyFrom(tempBatchData[i]))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
Collections.shuffle(dataOrder);
|
||||||
|
|
||||||
|
// Post data
|
||||||
|
|
||||||
|
for (int i = 0 ; i < tempBatchData.length ; i++) {
|
||||||
|
|
||||||
|
int dataIndex = dataOrder.get(i);
|
||||||
|
|
||||||
|
result = bulletinBoardServer.postBatchMessage(BatchMessage.newBuilder()
|
||||||
|
.setSignerId(signerIDs[0])
|
||||||
|
.setBatchId(currentBatch)
|
||||||
|
.setSerialNum(dataIndex)
|
||||||
|
.setData(completeBatch.getBatchDataList().get(dataIndex))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
assertThat("Could not post batch data for batch ID " + currentBatch + " serial number " + dataIndex,
|
||||||
|
result.getValue(), is(true));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close batch
|
||||||
|
|
||||||
|
signers[0].updateContent(completeBatch);
|
||||||
|
completeBatch.setSignature(signers[0].sign());
|
||||||
|
|
||||||
|
result = bulletinBoardServer.closeBatchMessage(CloseBatchMessage.newBuilder()
|
||||||
|
.setBatchId(currentBatch)
|
||||||
|
.setBatchLength(tempBatchData.length)
|
||||||
|
.setSig(completeBatch.getSignature())
|
||||||
|
.build());
|
||||||
|
|
||||||
|
assertThat("Could not close batch " + currentBatch, result.getValue(), is(true));
|
||||||
|
|
||||||
|
// Update locally stored batches
|
||||||
|
completeBatches.add(completeBatch);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReadBatch() throws CommunicationException {
|
||||||
|
|
||||||
|
for (CompleteBatch completeBatch : completeBatches) {
|
||||||
|
|
||||||
|
List<BatchData> batchDataList =
|
||||||
|
bulletinBoardServer.readBatch(BatchSpecificationMessage.newBuilder()
|
||||||
|
.setSignerId(completeBatch.getBeginBatchMessage().getSignerId())
|
||||||
|
.setBatchId(completeBatch.getBeginBatchMessage().getBatchId())
|
||||||
|
.setStartPosition(0)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
assertThat("Non-matching batch data for batch " + completeBatch.getBeginBatchMessage().getBatchId(),
|
||||||
|
completeBatch.getBatchDataList().equals(batchDataList), is(true));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void close(){
|
public void close(){
|
||||||
signers[0].clearSigningKey();
|
signers[0].clearSigningKey();
|
||||||
signers[1].clearSigningKey();
|
signers[1].clearSigningKey();
|
||||||
|
|
|
@ -111,6 +111,39 @@ public class MySQLBulletinBoardServerTest {
|
||||||
System.err.println("Time of operation: " + (end - start));
|
System.err.println("Time of operation: " + (end - start));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBatchPostAfterClose() {
|
||||||
|
try{
|
||||||
|
serverTest.testBatchPostAfterClose();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBatch() {
|
||||||
|
|
||||||
|
final int BATCH_NUM = 20;
|
||||||
|
|
||||||
|
try{
|
||||||
|
for (int i = 0 ; i < BATCH_NUM ; i++) {
|
||||||
|
serverTest.testPostBatch();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
serverTest.testReadBatch();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void close() {
|
public void close() {
|
||||||
System.err.println("Starting to close MySQLBulletinBoardServerTest");
|
System.err.println("Starting to close MySQLBulletinBoardServerTest");
|
||||||
|
|
|
@ -16,6 +16,7 @@ public interface BulletinBoardConstants {
|
||||||
|
|
||||||
// Other Constants
|
// Other Constants
|
||||||
|
|
||||||
public static final String BATCH_TAG = "Batch";
|
public static final String BATCH_TAG = "@BATCH";
|
||||||
|
public static final String BATCH_ID_TAG_PREFIX = "#";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ public class CompleteBatch {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompleteBatch(BeginBatchMessage newBeginBatchMessage) {
|
public CompleteBatch(BeginBatchMessage newBeginBatchMessage) {
|
||||||
|
this();
|
||||||
beginBatchMessage = newBeginBatchMessage;
|
beginBatchMessage = newBeginBatchMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +48,10 @@ public class CompleteBatch {
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBeginBatchMessage(BeginBatchMessage beginBatchMessage) {
|
||||||
|
this.beginBatchMessage = beginBatchMessage;
|
||||||
|
}
|
||||||
|
|
||||||
public void appendBatchData(BatchData newBatchData) {
|
public void appendBatchData(BatchData newBatchData) {
|
||||||
batchDataList.add(newBatchData);
|
batchDataList.add(newBatchData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package meerkat.bulletinboard;
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import com.google.protobuf.Message;
|
import com.google.protobuf.Message;
|
||||||
import meerkat.crypto.DigitalSignature;
|
import meerkat.crypto.DigitalSignature;
|
||||||
import meerkat.protobuf.BulletinBoardAPI.BeginBatchMessage;
|
|
||||||
import meerkat.protobuf.BulletinBoardAPI.BatchData;
|
import meerkat.protobuf.BulletinBoardAPI.BatchData;
|
||||||
import meerkat.protobuf.Crypto;
|
import meerkat.protobuf.Crypto;
|
||||||
|
|
||||||
|
@ -11,10 +10,11 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.UnrecoverableKeyException;
|
import java.security.UnrecoverableKeyException;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Arbel Deutsch Peled on 20-Dec-15.
|
* Created by Arbel Deutsch Peled on 20-Dec-15.
|
||||||
|
@ -77,6 +77,12 @@ public class GenericBatchDigitalSignature implements BatchDigitalSignature{
|
||||||
return digitalSignature.verify();
|
return digitalSignature.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password)
|
||||||
|
throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
|
||||||
|
return digitalSignature.getPKCS12KeyStoreBuilder(keyStream, password);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) throws IOException, CertificateException, UnrecoverableKeyException {
|
public void loadSigningCertificate(KeyStore.Builder keyStoreBuilder) throws IOException, CertificateException, UnrecoverableKeyException {
|
||||||
digitalSignature.loadSigningCertificate(keyStoreBuilder);
|
digitalSignature.loadSigningCertificate(keyStoreBuilder);
|
||||||
|
|
|
@ -5,11 +5,13 @@ import com.google.protobuf.Message;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.SignatureException;
|
|
||||||
import java.security.UnrecoverableKeyException;
|
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.SignatureException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.UnrecoverableKeyException;
|
||||||
import static meerkat.protobuf.Crypto.*;
|
import static meerkat.protobuf.Crypto.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,6 +73,20 @@ public interface DigitalSignature {
|
||||||
*/
|
*/
|
||||||
public boolean verify();
|
public boolean verify();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a keystore from an input stream in PKCS12 format.
|
||||||
|
*
|
||||||
|
* @param keyStream
|
||||||
|
* @param password
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
* @throws CertificateException
|
||||||
|
* @throws KeyStoreException
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
*/
|
||||||
|
public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password)
|
||||||
|
throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a private signing key. The keystore must include both the public and private
|
* Loads a private signing key. The keystore must include both the public and private
|
||||||
* key parts.
|
* key parts.
|
||||||
|
|
|
@ -211,6 +211,7 @@ public class ECDSASignature implements DigitalSignature {
|
||||||
* @throws KeyStoreException
|
* @throws KeyStoreException
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password)
|
public KeyStore.Builder getPKCS12KeyStoreBuilder(InputStream keyStream, char[] password)
|
||||||
throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
|
throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
|
||||||
KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
|
KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
|
||||||
|
|
Loading…
Reference in New Issue