Skip to content

Commit

Permalink
Merge pull request #3 from com-chain/keystore
Browse files Browse the repository at this point in the history
Keystore
  • Loading branch information
FlorianDubath authored Dec 5, 2019
2 parents a4c814b + d7f1ef4 commit 963c3b0
Show file tree
Hide file tree
Showing 10 changed files with 348 additions and 123 deletions.
107 changes: 67 additions & 40 deletions api.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ function getTransaction($hash, $gethRPC){
->build();
$keyspace = 'comchain';
$session = $cluster->connect($keyspace);
$query = "SELECT * FROM transactions WHERE hash = '$hash'";
foreach ($session->execute(new Cassandra\SimpleStatement($query)) as $row) {
$query = "SELECT * FROM transactions WHERE hash = ?";
$options = array('arguments' => array($hash));

foreach ($session->execute(new Cassandra\SimpleStatement($query), $options) as $row) {
$arr = $row;
}

Expand Down Expand Up @@ -154,71 +156,96 @@ function getRPCResponse($result){
}

// Lookup into the DB for a valid shop from the REQUEST parameters
// TODO PROTECT AGAINST CQL injection
function validateShop( $shop_id, $server_name){

function validateShop($shop_id, $server_name){
$cluster = Cassandra::cluster('127.0.0.1') ->withCredentials("transactions_ro", "Public_transactions")->build();
$keyspace = 'comchain';
$session = $cluster->connect($keyspace);
$query = "SELECT * FROM sellers  WHERE store_id = '$shop_id' AND server_name = '$server_name' ";
foreach ($session->execute(new Cassandra\SimpleStatement($query)) as $row) {
$query = "SELECT * FROM sellers WHERE store_id = ? AND server_name = ? ";
$options = array('arguments' => array($shop_id, $server_name));
foreach ($session->execute(new Cassandra\SimpleStatement($query), $options) as $row) {
return true;
}

return false;
}

// Insert Pending Shop transaction storing the shop_id and the shop_ref
// TODO PROTECT AGAINST CQL injection
function insertPendingShopTransaction($shop_id,$shop_ref,$transaction_ash,$delegate){
$field_add='';
$value_add='';
if (isset($delegate)){
$field_add=', delegate';
$value_add=", '$delegate'";
}

//TODO change the table
$cluster = Cassandra::cluster('127.0.0.1') ->withCredentials("webhook_rw", "Private_access_transactions")->build();
$keyspace = 'comchain';
$session = $cluster->connect($keyspace);
$query = "INSERT INTO webshop_transactions (hash, store_id, store_ref, status, $field_add) VALUES ('$transaction_ash','$shop_id','$shop_ref' $value_add)"; // Set old timestamp for the lock (tr_attempt_date)
}

// Insert Pending Delegated transaction storing the delegate
// TODO PROTECT AGAINST CQL injection
function insertPendingDelegateTransaction($delegate,$transaction_ash){
$cluster = Cassandra::cluster('127.0.0.1') ->withCredentials("webhook_rw", "Private_access_transactions")->build();
$keyspace = 'comchain';
$session = $cluster->connect($keyspace);
//TODO change the table
$query = "INSERT INTO webshop_transactions (hash, delegate) VALUES ('$transaction_ash','$delegate')";
function validateShopData() {
$shop_id=$_REQUEST['shopId'];
$shop_ref=$_REQUEST['txId'];
$server_name=$_REQUEST['serverName'];
return (isset($shop_id) && isset($server_name) && isset($shop_ref) && validateShop( $shop_id, $server_name));
}

function sendRawTransaction($rawtx,$gethRPC){
function storeAdditionalData($transaction_ash) {
$shop_id=$_REQUEST['shopId'];
$shop_ref=$_REQUEST['txId'];
$server_name=$_REQUEST['serverName'];
$delegate=$_REQUEST['delegate'];
$memo_from=$_REQUEST['memo_from'];
$memo_to=$_REQUEST['memo_to'];

$do_insert=false;
$fields =array();
$val =array();
if (validateShopData()) {
$fields['store_id'] = $shop_id;
$fields['store_ref'] = $shop_ref;
$val[]='?';
$val[]='?';
}

if (isset($delegate)) {
$fields['delegate'] = $delegate;
$val[]='?';
}

if (isset($memo_from) && $memo_from!="") {
$fields['message_from'] = $memo_from;
$val[]='?';
}


if (isset($memo_to) && $memo_to!="") {
$fields['message_to'] = $memo_to;
$val[]='?';
}

if (sizeof($fields)>0) {
$fields['hash'] = $transaction_ash;
$val[]='?';
// build the query
$query = "INSERT INTO webshop_transactions (".join(', ',array_keys($fields));
$query = $query.') VALUES ('.join(', ',$val).')';

$cluster = Cassandra::cluster('127.0.0.1') ->withCredentials("webhook_rw", "Private_access_transactions")->build();
$keyspace = 'comchain';
$session = $cluster->connect($keyspace);
$session->execute(new Cassandra\SimpleStatement($query), array('arguments' => $fields));
}
}


function sendRawTransaction($rawtx,$gethRPC){
$data = getDefaultResponse();
try {
$data['data'] = getRPCResponse($gethRPC->eth_sendRawTransaction($rawtx));

// If needed put the delegate and/or the Shop information into the DB as a pending transaction
if (isset($shop_id) && isset($server_name) && isset($shop_ref) && validateShop( $shop_id, $server_name)){
insertPendingShopTransaction($shop_id,$shop_ref,$data['data'],$delegate);
} else if(isset($delegate)){
insertPendingDelegateTransaction($delegate, $data['data']);
}
}
catch (exception $e) {
$data['error'] = true;
$data['msg'] = $e->getMessage();
$data['msg'] = 'E1'.$e->getMessage();
}

try {
storeAdditionalData($data['data']);
}
catch (exception $e) {
$data['error'] = true;
$data['msg'] = 'E2'.$e->getMessage();
}
return json_encode($data);
}

function formatAddress($addr){
if (substr($addr, 0, 2) == "0x")
return $addr;
Expand Down
73 changes: 42 additions & 31 deletions auth.php
Original file line number Diff line number Diff line change
@@ -1,88 +1,99 @@
<?php
require("includes/session.inc");
require_once 'libs/jsonRPCClient.php';

session_start();
session_regenerate_id(true);

header('Access-Control-Allow-Origin: *');
require_once 'libs/jsonRPCClient.php';

$cluster = Cassandra::cluster('127.0.0.1') ->withCredentials("challenges_rw", "Private_access_challenges")
->build();
$ml_cluster = Cassandra::cluster('127.0.0.1') ->withCredentials("session_rw", "Private_access_sessions")
->build();
// Build DB connection for the challenge
$cluster = Cassandra::cluster('127.0.0.1') ->withCredentials("challenges_rw", "Private_access_challenges")->build();
$keyspace = 'comchain';
$session = $cluster->connect($keyspace);

// Build DB connection for the session
$ml_cluster = Cassandra::cluster('127.0.0.1') ->withCredentials("session_rw", "Private_access_sessions")->build();
$ml_keyspace = 'ml';
$ml_session = $ml_cluster->connect($ml_keyspace);

// Build link to ethereum
$gethRPC = new jsonRPCClient('http://127.0.0.1:8545');

// Processing request: check for valid address logout on 0x0
if (strlen($_GET['addr']) == 42) {
$addr = strtolower(preg_replace("/[^a-zA-Z0-9]+/", "", $_GET['addr']));
} else if($_GET['addr'] == "0x0"){
$addr = strtolower(preg_replace("/[^a-zA-Z0-9]+/", "", $_GET['addr']));
} else if($_GET['addr'] == "0x0") {
session_destroy();
$message['Authentication'] = "Logout";
echo json_encode($message);
exit;
}else{
$message['Authentication'] = "Logout";
echo json_encode($message);
exit;
} else {
session_destroy();
$message['Error'] = "Address invalid";
echo json_encode($message);
exit;
}

// Check if the message contains a signature or create a new challenge
if (strlen($_GET['sign']) == 132) {
$sign = strtolower(preg_replace("/[^a-zA-Z0-9]+/", "", $_GET['sign']));
$sign = strtolower(preg_replace("/[^a-zA-Z0-9]+/", "", $_GET['sign']));
}else{
$challenge = random_str(25);
$query = "INSERT INTO challenges (addr, challenge) VALUES ('$addr', '$challenge')";
$session->execute(new Cassandra\SimpleStatement($query));
$arrayChallenge['Challenge'] = $challenge;
echo json_encode($arrayChallenge);
$arrayChallenge = createChallenge($addr, $session);
echo json_encode($arrayChallenge);
exit;
}

// Check if the challenge is OK
$user = getChallenge($addr,$session);
$signingAddr = ecrecover(getTransaction($user['challenge'], $sign),$addr,$gethRPC);

if ($user['addr'] == $signingAddr){
$_SESSION['loggedAddr'] = $signingAddr;
$query = "SELECT roles FROM users WHERE addr = '$signingAddr'";
foreach ($ml_session->execute(new Cassandra\SimpleStatement($query)) as $row) {
//$roles = $row['roles'];
foreach ($ml_session->execute(new Cassandra\SimpleStatement($query)) as $row) {
// NOT USED YET: THIS IS A STUB
//$roles = $row['roles'];
foreach($row['roles'] as $role){
$_SESSION[$role] = true;
}
}
}
// build the responce
$arrayLogin['Authentication'] = "OK";
$arrayLogin['Address'] = $signingAddr;
echo json_encode($arrayLogin);
echo json_encode($arrayLogin);
}else{
$challenge = random_str(25);
$query = "INSERT INTO challenges (addr, challenge) VALUES ('$addr', '$challenge')";
$session->execute(new Cassandra\SimpleStatement($query));
// challenge NOK: create a new one
$arrayChallenge = createChallenge($addr, $session);
$arrayLogin['Authentication'] = "KO";
$arrayLogin['Challenge'] = $challenge;
echo json_encode($arrayLogin);
echo json_encode($arrayLogin);
}

/*
FUNCTIONS
*/
function createChallenge($addr, $session) {
challenge = random_str(25);
$query = "INSERT INTO challenges (addr, challenge) VALUES ('$addr', '$challenge')";
$session->execute(new Cassandra\SimpleStatement($query));
$arrayLogin['Challenge'] = $challenge;
return $arrayLogin;
}

function getChallenge ($addr, $session){
$query = "SELECT * FROM challenges WHERE addr = '$addr'";
$counter=0;
foreach ($session->execute(new Cassandra\SimpleStatement($query)) as $row) {
$user['addr'] = $row['addr'];
$user['challenge'] = $row['challenge'];
$counter++;
$user['addr'] = $row['addr'];
$user['challenge'] = $row['challenge'];
$counter++;
}
$query = "DELETE FROM challenges WHERE addr = '$addr'";
$session->execute(new Cassandra\SimpleStatement($query));
return $user;
}

function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
$str = '';
$max = mb_strlen($keyspace, '8bit') - 1;
for ($i = 0; $i < $length; ++$i) {
Expand Down
18 changes: 14 additions & 4 deletions ecrecover_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@
use kornrunner\Keccak;

function personal_ecRecover($msg, $signed) {
$personal_prefix_msg = "\x19Ethereum Signed Message:\n". strlen($msg). $msg;
$hex = keccak256($personal_prefix_msg);
return ecRecover($hex, $signed);
return personal_ecRecoverPublic($msg, $signed)[0];
}

function ecRecover($hex, $signed) {
return ecRecoverPublic($hex, $signed)[0];
}

function personal_ecRecoverPublic($msg, $signed) {
$personal_prefix_msg = "\x19Ethereum Signed Message:\n". strlen($msg). $msg;
$hex = keccak256($personal_prefix_msg);
return ecRecoverPublic($hex, $signed);
}

function ecRecoverPublic($hex, $signed) {
$rHex = substr($signed, 2, 64);
$sHex = substr($signed, 66, 64);
$vValue = hexdec(substr($signed, 130, 2));
Expand All @@ -37,7 +45,7 @@ function ecRecover($hex, $signed) {
$publicKey = Signature::recoverPublicKey($rGmp, $sGmp, $messageGmp, $recovery);
$publicKeyString = $publicKey["x"] . $publicKey["y"];

return '0x'. substr(keccak256(hex2bin($publicKeyString)), -40);
return array('0x'. substr(keccak256(hex2bin($publicKeyString)), -40),$publicKeyString);
}

function strToHex($string)
Expand All @@ -49,3 +57,5 @@ function strToHex($string)
function keccak256($str) {
return '0x'. Keccak::hash($str, 256);
}

?>
10 changes: 6 additions & 4 deletions enroll.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ function saveAddress($uid, $token, $pubkeyid, $currency, $adresse, $maxAccounts)
$dbg=',in,'.$maxAccounts.',' ;
$count=1;
$addr = $adresse;
$sql ="SELECT Adresses, Count from $table where Code = '$uid'";
foreach ($session->execute(new Cassandra\SimpleStatement($sql)) as $row) {
$sql ="SELECT Adresses, Count from $table where Code = ?";
$options = array('arguments' => array($uid));
foreach ($session->execute(new Cassandra\SimpleStatement($sql), $options) as $row) {
$count = $row['Count']+1;

if ($row['adresses'] != ""){
Expand All @@ -51,8 +52,9 @@ function saveAddress($uid, $token, $pubkeyid, $currency, $adresse, $maxAccounts)
$result = "KO";
if ($count < $maxAccounts) {
$dbg = $dbg.'count ok,';
$updateCount = "UPDATE $table SET Count=$count, Adresses='$addr' WHERE Code='$uid'";
if ($session->execute(new Cassandra\SimpleStatement($updateCount))) {
$updateCount = "UPDATE $table SET Count=$count, Adresses=? WHERE Code=?";
$options = array('arguments' => array($add,$uid));
if ($session->execute(new Cassandra\SimpleStatement($updateCount), $options)) {
$result = "OK";

}
Expand Down
8 changes: 4 additions & 4 deletions export.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
$keyspace = 'comchain';
$session = $cluster->connect($keyspace);

$query = "SELECT * FROM transactions";
$query = "SELECT hash from trans_by_addr WHERE addr CONTAINS '$addr'";
$query = "SELECT hash from trans_by_addr WHERE addr CONTAINS ?";
$options = array('arguments' => array($addr));
$counter=0;
foreach ($session->execute(new Cassandra\SimpleStatement($query)) as $row) {
foreach ($session->execute(new Cassandra\SimpleStatement($query), $options) as $row) {
$string[$counter] = implode(",",$row);
$counter++;
}
Expand All @@ -48,7 +48,7 @@
#$counter = $offset + $limit;
#$query = "PAGING OFF";
#$session->execute(new Cassandra\SimpleStatement($query));
$query = "select addr_from, addr_to, time, recieved, sent, tax, type, hash, block from transactions WHERE hash IN $hashes AND time >= '$start' AND time <= '$end' ORDER by time";
$query = "select * from transactions WHERE hash IN $hashes AND time >= '$start' AND time <= '$end' ORDER by time";
$counter = 0;
foreach ($session->execute(new Cassandra\SimpleStatement($query)) as $row) {
$jstring[$counter] = json_encode($row);
Expand Down
5 changes: 3 additions & 2 deletions getadd.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ function getAddress($currency,$code){
$table="Members";

$results = "";
$sql ="SELECT Adresses from $table where Code = '$code'";
foreach ($session->execute(new Cassandra\SimpleStatement($sql)) as $row) {
$sql ="SELECT Adresses from $table where Code = ?";
$options = array('arguments' => array($code));
foreach ($session->execute(new Cassandra\SimpleStatement($sql), $options) as $row) {

$results = $row['adresses'];
}
Expand Down
Loading

0 comments on commit 963c3b0

Please sign in to comment.