Commit cb128edb authored by Miguel Mateo Montero's avatar Miguel Mateo Montero
Browse files

release 09-2020

parents
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>eu.ari.fentec</groupId>
<artifactId>merchant_server</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>merchant_server Maven Webapp</name>
<url>http://maven.apache.org</url>
<build>
<finalName>merchant_server</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20151123</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.10.0</version>
</dependency>
<dependency>
<groupId>eu.ari.fentec</groupId>
<artifactId>digcur_utils</artifactId>
<version>1</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.27</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
/**
*
*FENTEC Functional Encryption Technologies
*Privacy-preserving and Auditable Digital Currency Use Case
*Copyright © 2019 Atos Spain SA
*
*This program is free software: you can redistribute it and/or modify
*it under the terms of the GNU General Public License as published by
*the Free Software Foundation, either version 3 of the License, or
*(at your option) any later version.
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License
*along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
package eu.ari.fentec.connector;
import org.json.JSONObject;
import eu.ari.fentec.econtract.Econtract;
import eu.ari.fentec.utils.conf.Configuration;
import eu.ari.fentec.utils.crypto.Utils;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import org.bouncycastle.util.encoders.Base64;
/**
* @author A101866
* connector ot the Exchange server
*
*/
public class ExchangeConnector {
private Logger logger = Logger.getLogger(ExchangeConnector.class);
/**
* @param funds
* @param walletID
* @param eCoinTypeName
* @return
*/
public boolean wireTransferRequest(int funds, byte[] walletID, ArrayList<String> eCoinTypeName) {
try {
String jsonS = getJsonTransfer(funds, walletID, eCoinTypeName);
RequestBody body = RequestBody.create(MediaType.parse("Application/Json"), jsonS);
logger.debug("wiring transfer to exchange to create the account: " + jsonS);
Request request = new Request.Builder()
.url(Configuration.getConfiguration().getProperty("EXCHANGE_END_POINT") + "wireTranfer").post(body)
.build();
Response response;
OkHttpClient mClient = new OkHttpClient();
response = mClient.newCall(request).execute();
if (response.code() == 200) {
return true;
} else {
logger.error("error while creating wiring transfer for merchant account to exchange.");
logger.error(" exchange response: " + response.code());
logger.error(" exchange msg: " + response.message());
return false;
}
} catch (Exception e) {
logger.error(e, e);
return false;
}
}
/**
* @param funds
* @param walletID
* @param eCoinTypeName
* @return Body of the request to Exchange
*/
private String getJsonTransfer(int funds, byte[] walletID, ArrayList<String> eCoinTypeName) {
JSONObject jo = new JSONObject();
jo.put("funds", funds);
jo.put("walletID", Base64.toBase64String(walletID));
for (String s : eCoinTypeName)
jo.append("ect", s);
return jo.toString(4);
}
/**
* request to exchange to verify validity of eCoins recevied
* @param econtract
* @param walletID
* @return
*/
public boolean ecoinVerification(Econtract econtract, byte[] walletID) {
try {
String contractS = new Utils().serializeEcontract(econtract);
String id = Base64.toBase64String(walletID);
JSONObject jo = new JSONObject();
jo.put("econtract", contractS);
jo.put("id", id);
String jsonS = jo.toString(4);
RequestBody body = RequestBody.create(MediaType.parse("Application/Json"), jsonS);
logger.debug("sending contract to exchange for verification: " + econtract.getId());
Request request = new Request.Builder()
.url(Configuration.getConfiguration().getProperty("EXCHANGE_END_POINT") + "ecoinVerify").post(body)
.build();
Response response;
OkHttpClient mClient = new OkHttpClient();
response = mClient.newCall(request).execute();
if (response.code() == 200) {
return true;
} else {
logger.error("ecoin Verification fail");
logger.error(" exchange response: " + response.code());
logger.error(" exchange msg: " + response.message());
return false;
}
} catch (Exception e) {
logger.error(e, e);
return false;
}
}
}
/**
*
*FENTEC Functional Encryption Technologies
*Privacy-preserving and Auditable Digital Currency Use Case
*Copyright © 2019 Atos Spain SA
*
*This program is free software: you can redistribute it and/or modify
*it under the terms of the GNU General Public License as published by
*the Free Software Foundation, either version 3 of the License, or
*(at your option) any later version.
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License
*along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
package eu.ari.fentec.connector;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import org.json.JSONObject;
import eu.ari.fentec.utils.conf.Configuration;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* @author A101866
* Connector to Trusted authority
*/
public class TrustedAuthConnector {
private Logger logger = Logger.getLogger(TrustedAuthConnector.class);
/**
* @param name
* @param ectAL
* @param type
* @return id for the account
*/
public String createAccountRequest (String name, ArrayList<String> ectAL, String type) {
try {
String jsonS = getJsonB(name, ectAL, type);
RequestBody body = RequestBody.create(MediaType.parse("Application/Json"), jsonS);
logger.debug("Creating account for merchant: " + jsonS);
Request request = new Request.Builder().url(Configuration.getConfiguration().getProperty("TRUSTEDAUTH_END_POINT")+"createAccount")
.post(body)
.build();
Response response;
OkHttpClient mClient = new OkHttpClient();
response = mClient.newCall(request).execute();
if (response.code() == 200) {
String id = response.message();
return id;
}else {
logger.error("error while creating merchant account at the trusted authority.");
logger.error(" trusted authority response: "+response.code());
logger.error("trusted authority msg: " + response.message());
return null;
}
}catch (Exception e) {
logger.error(e,e);
return null;
}
}
/**
* @param name
* @param ectAL
* @param type
* @return body for the request
*/
private String getJsonB(String name, ArrayList<String> ectAL, String type) {
JSONObject jo = new JSONObject();
jo.put("name", name);
for(String s : ectAL)
jo.append("eCoinTypes", s);
jo.put("type", type);
return jo.toString(4);
}
}
/**
*
*FENTEC Functional Encryption Technologies
*Privacy-preserving and Auditable Digital Currency Use Case
*Copyright © 2019 Atos Spain SA
*
*This program is free software: you can redistribute it and/or modify
*it under the terms of the GNU General Public License as published by
*the Free Software Foundation, either version 3 of the License, or
*(at your option) any later version.
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License
*along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
package eu.ari.fentec.entities.merchant;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;
import org.bson.Document;
import com.google.gson.Gson;
import com.mongodb.client.MongoCursor;
import eu.ari.fentec.connector.ExchangeConnector;
import eu.ari.fentec.db.ConnectorMongo;
import eu.ari.fentec.econtract.Contract;
import eu.ari.fentec.econtract.EcoinPaid;
import eu.ari.fentec.econtract.Econtract;
import eu.ari.fentec.econtract.Item;
import eu.ari.fentec.econtract.Product;
import eu.ari.fentec.econtract.ItemList;
import eu.ari.fentec.payment.DenominationS;
import eu.ari.fentec.payment.Ecoin;
import eu.ari.fentec.utils.common.Const;
import eu.ari.fentec.utils.common.Pair;
import eu.ari.fentec.utils.conf.ConfPnames;
import eu.ari.fentec.utils.conf.Configuration;
import eu.ari.fentec.utils.crypto.Utils;
import eu.ari.fentec.wallet.Wallet;
import eu.ari.fentec.wrapper.KPabe_Wrapper;
/**
* @author A101866
* Mechant entity
*
*/
public class Merchant implements MerchantIf{
private static Logger logger = Logger.getLogger(Merchant.class);
private static ConnectorMongo mongo = new ConnectorMongo("merchant", "merch", "merchantDB");
MerchantMetadata mmd = null;
Wallet wallet = null;
/**
* Constructor
* @param mmd MerchantMetadata
*/
public Merchant(MerchantMetadata mmd) {
this.mmd = mmd;
wallet = new Wallet ();
wallet.setFunds(0);
ExchangeConnector exchange = new ExchangeConnector();
ArrayList<String> ectN = new ArrayList<>();
ectN.add(mmd.products.get(0).getProductType()+"");
boolean success = exchange.wireTransferRequest(0, wallet.getId(), ectN);
logger.debug("wireTransfer to Exchange result for ("+this.getName()+"): "+ success);
}
/* (non-Javadoc)
* @see eu.ari.fentec.entities.merchant.MerchantIf#econtractRequest(java.lang.String)
*/
public String econtractRequest(String productS) {
Econtract econtract = null;
//writeOnTextArea("econtractRequest: INIT \n");
ItemList pl = new Utils().deserializeItemList(productS);
ArrayList<Item> productsList = pl.getItemList();
try {
//public Contract( String issuer, ArrayList<Item> items, int cost)
int cost = 0;
for (Item it : productsList) {
for (Product p : mmd.products) {
if (it.getName().equalsIgnoreCase(p.getName())) {
cost = cost + (p.getPrice() * it.getAmount());
}
}
}
Contract contract = new Contract( mmd.name , productsList, cost);
//Sign the contract
Gson gson = new Gson();
String contractJSON = gson.toJson(contract);
logger.debug("contract to be signed: \n" + contractJSON);
Signature ecdsaSignature = Signature.getInstance("SHA256withECDSA", "BC");
ecdsaSignature.initSign(mmd.ecdsaPrivateKey);
ecdsaSignature.update(contractJSON.getBytes("UTF-8"));
econtract = new Econtract(contract, mmd.ecdsaPublicKey, ecdsaSignature.sign());
String econtractJSON = gson.toJson(econtract);
logger.debug ("El contrato en formato json: " + econtractJSON);
mongo.insertDocument(this.getName(), Const.COLLECTION_NAME, econtract, Const.PROPOSED);
String econtractS = new Utils().serializeEcontract(econtract);
return econtractS;
} catch (Exception e) {
logger.error(e,e);
}
return null;
}
/* (non-Javadoc)
* @see eu.ari.fentec.entities.MerchantIf#econtractSendBack(eu.ari.fentec.payment.Econtract, eu.ari.fentec.entities.Exchange)
*/
public boolean econtractSendBack(String econtractS) {
//writeOnTextArea("econtractSendBack:INIT \n");
//if (Configuration.DEBUG) System.out.println("econtractSendBack:INIT number of ecoinSignature:"+econtract.getEcoinsSignatures().size());
//Extract/Decrypt the Issur signature of its part of the ecoin id
try {
logger.debug("Meachant processing send Back");
Econtract econtract = new Utils().deserializeEcontract(econtractS);
logger.debug("contract deserialized");
for(Pair<EcoinPaid, byte[]> pair : econtract.getEcoinsSignatures()) {
logger.debug("processing coin");
EcoinPaid ecoin = pair.getKey();
StringBuffer sb = new StringBuffer();
sb.append("\n\tEcoin id: "+ Base64.toBase64String(ecoin.getID()));
logger.debug("key obtained, going to decrypt vt");
KPabe_Wrapper wrapper = new KPabe_Wrapper (Configuration.getKPABELIB(), Configuration.getConfiguration().getProperty(ConfPnames.GOLANG_DEBUG));
//String path = Configuration.getKEYPATH()+"/"+ecoin.getECoinTypeName()+"/master";
String path = Configuration.getKEYPATH()+"/"+"kudo"+"/master";
String pathuser = path+"/"+this.getName();
//String encodedSignature = wrapper.Decrypt(path, this.getName(), ecoin.getFEIssuerSignature());
Long startTime = System.nanoTime();
String encodedSignature = wrapper.Decrypt(path, pathuser, ecoin.getFEIssuerSignature());
Long endTime = System.nanoTime();
Long timeElapsed = endTime - startTime;
logger.error("MAMM;TIME;DECRYPTVT;"+econtract.getContract().getContractNumber()+";"+timeElapsed);
logger.debug("vt decrypted");
if (Configuration.DEBUG) System.out.println("encodedSignature:"+encodedSignature);
logger.debug("retrieveing signature");
byte[] sig = Hex.decode(encodedSignature);
ecoin.setIssuerSignature(sig);
logger.debug("vt signature set");
sb.append("\n\tFEcipherText_signature of Validation ID: " + ecoin.getFEIssuerSignature());
sb.append("\n\tDecripted signature of Validation ID: "+ ecoin.getIssuerSignature());
logger.debug("RCORT;validation token signature;"+ecoin.getIssuerSignature().length);
logger.debug("RCORT;validation token signature FE encdrypted;"+ecoin.getFEIssuerSignature().getBytes().length);
if (Configuration.DEBUG) System.out.println(sb.toString());
}
ExchangeConnector exchange = new ExchangeConnector();
if(!this.econtractVerification(econtract) || !exchange.ecoinVerification(econtract, wallet.getId())) {
mongo.udateDocument(this.getName(), Const.COLLECTION_NAME, econtract, Const.REJECTED);
}
else {
//Update the wallet
synchronized (this) {
wallet.updateFunds(wallet.getFunds() + econtract.getContract().getCost());
}
//Update the e-contract
Econtract ec = new Utils().deserializeEcontract(mongo.getDocument(econtract.getId(), Const.COLLECTION_NAME).getString("contract"));
ec.getEcoinsSignatures().addAll(econtract.getEcoinsSignatures());
mongo.udateDocument(this.getName(), Const.COLLECTION_NAME, ec, Const.PAID);
return true;
}
}catch (Exception e) {
if (Configuration.DEBUG) System.out.println(e.getMessage());
e.printStackTrace();
if (Configuration.DEBUG) System.out.println("---------------------------->eCoins could not be verified, payment rejected;");
}
return false;
}
/* (non-Javadoc)
* @see eu.ari.fentec.entities.MerchantIf#printEContracts()
*/
public void printEContracts() {
int i = 1;
if (Configuration.DEBUG) System.out.println("\n---------- THE MERCHANT'S E-CONTRACTS ----------");
if (Configuration.DEBUG) System.out.println("_____________________________________#");
MongoCursor<Document> mc = mongo.getAllDocuments(Const.COLLECTION_NAME);
while (mc.hasNext()) {
Document doc = mc.next();
String econt = (String) doc.get("contract");
Econtract econtract = new Utils().deserializeEcontract(econt);
if (Configuration.DEBUG) System.out.println("E-CONTRACT " + i);
if (Configuration.DEBUG) System.out.println("\tBase64-ID: " + econtract.getId());
Contract contract = econtract.getContract();
Gson gson = new Gson();
String contractJSON = gson.toJson(contract);
if (Configuration.DEBUG) System.out.println("\tContract: " + contractJSON);
if(econtract.getIssuerSignature().getValue() != null) if (Configuration.DEBUG) System.out.println("\tMerchant's signature: " + Base64.toBase64String(econtract.getIssuerSignature().getValue()));
else if (Configuration.DEBUG) System.out.println("\tMerchant's signature: NULL");
int j = 1;
if (econtract.getPayment() != null) {
for(Pair<EcoinPaid, byte[]> pair : econtract.getEcoinsSignatures()) {
if (Configuration.DEBUG) System.out.println("\tE-Coins' signatures " + j);
if(pair.getValue() != null) if (Configuration.DEBUG) System.out.println("\t\tE-Coin's signature: " + Base64.toBase64String(pair.getValue()));
else if (Configuration.DEBUG) System.out.println("\t\tE-Coin's signature: NULL");
j++;
}
}
i++;
}
if (Configuration.DEBUG) System.out.println("_____________________________________#\n");
}