Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // XC's REV1 - Encrypted Trusted Mixer - LET'S WRITE A MIXER! Support XC's Development Fund - XXVTS3279gzC5kagTCrEe4x5R7urnm6h2b
- - // this command only gets processed by mixer servers
- - else if (strCommand == "mixdisc" && GetBoolArg("-xmixer")) {
- - CMixDisc md;
- - vRecv >> md;
- -
- - // determine if we have enough coins to handle the request
- - Array args;
- - Value balance = getbalance(args, false);
- -
- - if (md.amount * 10 < balance.get_real() && pfrom->addrName != GetLocalAddress(NULL).ToStringIPPort()) {
- - // save transaction information in server
- - CServerMixTx smtx;
- - smtx.addrName = pfrom->addrName;
- - smtx.amount = md.amount;
- - smtx.stage = 0;
- - int64 smtxid;
- -
- - {
- - LOCK(cs_mapServerMixTxs);
- - std::map<int64, CServerMixTx>::iterator it = mapServerMixTxs.end();
- - if (it == mapServerMixTxs.begin()) smtxid = 1;
- - else smtxid = (--it)->first + 1;
- -
- - mapServerMixTxs[smtxid] = smtx;
- - }
- -
- - unsigned char rnum;
- - if (RAND_bytes(&rnum, 1) != 1) {
- - std::cerr << "RAND_bytes mixdisc fail; aborting" << std::endl;
- - goto abort; // fuck it
- - }
- - int num = rnum;
- -
- - boost::this_thread::sleep(boost::posix_time::milliseconds(num*10));
- -
- - // send the acknowledgement to the client with server ID
- - CMixAck ma;
- - ma.mtxid = md.mtxid;
- - ma.smtxid = smtxid;
- - pfrom->PushMessage("mixack", ma);
- - }
- - }
- -
- - else if (strCommand == "mixaccept" && GetBoolArg("-xmixer")) {
- - CMixAccept ma;
- - vRecv >> ma;
- -
- - bool success = false;
- - RSA* servrsa = RSA_new();
- -
- - if (servrsa != NULL) {
- - {
- - LOCK(cs_mapServerMixTxs);
- - std::map<int64, CServerMixTx>::iterator it = mapServerMixTxs.find(ma.smtxid);
- - if (it != mapServerMixTxs.end() &&
- - it->second.stage == 0 &&
- - it->second.addrName == pfrom->addrName) {
- - it->second.stage = 1;
- - it->second.servrsa = servrsa;
- - success = true;
- - }
- - }
- -
- - if (success) {
- - // generate a public encryption key and send it over
- - if (genrsa(servrsa)) {
- - CMixKey mk;
- - if (rsa2hex(servrsa, mk.key)) {
- - std::cout << "servrsa: " << servrsa << std::endl;
- - std::cout << "server RSA size: " << RSA_size(servrsa) << std::endl;
- - mk.mtxid = ma.mtxid;
- - mk.smtxid = ma.smtxid;
- -
- - pfrom->PushMessage("mixkey", mk);
- - }
- - else {
- - std::cerr << "Could not convert RSA key to hex" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Could not generate RSA key" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Invalid mixaccept message" << std::endl;
- - RSA_free(servrsa);
- - }
- - }
- - else {
- - std::cerr << "Could not allocate RSA key" << std::endl;
- - }
- - }
- -
- - else if (strCommand == "mixstart" && GetBoolArg("-xmixer")) {
- - CMixStart ms;
- - vRecv >> ms;
- -
- - CServerMixTx smtx;
- - bool success = false;
- -
- - {
- - LOCK(cs_mapServerMixTxs);
- - std::map<int64, CServerMixTx>::iterator it = mapServerMixTxs.find(ms.smtxid);
- - if (it != mapServerMixTxs.end() &&
- - it->second.stage == 1 &&
- - it->second.addrName == pfrom->addrName) {
- - smtx = it->second;
- - success = true;
- - mapServerMixTxs.erase(ms.smtxid); // done with this now!
- - }
- - }
- -
- - if (success) {
- - // get a new wallet address for client mixer, and encrypt it with the client's key
- - Array args;
- - Value newaddress = getnewaddress(args, false);
- - std::string address = newaddress.get_str();
- -
- - RSA* rsa = RSA_new();
- - if (rsa != NULL) {
- - std::cout << "servrsa: " << smtx.servrsa << std::endl;
- - std::cout << "server RSA size in mixstart: " << RSA_size(smtx.servrsa) << std::endl;
- - //unencrypt final target from client
- - std::string to;
- - if (strdec(smtx.servrsa, ms.to, to)) {
- - // unencrypt client public key and put in RSA
- - std::string ckey;
- - if (strdec(smtx.servrsa, ms.key, ckey) &&
- - hex2rsa(rsa, ckey)) {
- - BN_set_word(rsa->e, 17);
- - CMixFin mf;
- - // encrypt intermediate address with client public key
- - //std::cout << "Server's client enc target address: " << ms.to << std::endl;
- - std::cout << "Server's client target address: " << to << std::endl;
- - //std::cout << "Server's client enc hex key: " << ms.key << std::endl;
- - std::cout << "Server's client Hex key: " << ckey << std::endl;
- - std::cout << "Server's client RSA size: " << RSA_size(rsa) << std::endl;
- - std::cout << "Server's iaddress: " << address << std::endl;
- - if (strenc(rsa, address, mf.address)) {
- - //std::cout << mf.address << std::endl;
- - RSA_free(rsa);
- - RSA_free(smtx.servrsa);
- -
- - mf.mtxid = ms.mtxid;
- - pfrom->PushMessage("mixfin", mf);
- -
- - boost::thread t(ServerMix, address, to, smtx.amount);
- - }
- - else {
- - std::cerr << "Could not encrypt intermediate address" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Could not decrypt client public keys" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Could not decrypt target address" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Could not allocate client RSA object" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Invalid mixstart request" << std::endl;
- - }
- - }
- -
- - else if (strCommand == "mixack") {
- - // recieved an mixdisc broadcast acknowledgement, so we save the server info and accept
- - // the request if we haven't already saved a server for this ID
- - CMixAck ma;
- - vRecv >> ma;
- -
- - bool success = false;
- -
- - {
- - LOCK(cs_mapMixTxs);
- -
- - // find the transaction, ignore invalid mixacks
- - std::map<int64, CMixTx>::iterator it = mapMixTxs.find(ma.mtxid);
- -
- - // stage == 0 means that we haven't found a server yet
- - if (it != mapMixTxs.end() && it->second.stage == 0) {
- - // save server address for future verification
- - it->second.addrName = pfrom->addrName;
- - it->second.stage = 1; // indicate that a server has been found (and saved)
- - it->second.inprogress = false;
- - success = true;
- - }
- - }
- -
- - if (success == true) {
- - std::cout << "Received mixack from " << pfrom->addrName << std::endl;
- - std::cout << "Client ID is " << ma.mtxid << " and server ID is " << ma.smtxid
- - << std::endl;
- - // tell the server that we have accepted its request
- - CMixAccept mac;
- - mac.mtxid = ma.mtxid;
- - mac.smtxid = ma.smtxid;
- -
- - pfrom->PushMessage("mixaccept", mac);
- - }
- - else {
- - std::cerr << "Recieved invalid request from server or request already handled."
- - << std::endl;
- - }
- - }
- -
- - else if (strCommand == "mixkey") {
- - CMixKey mk;
- - vRecv >> mk;
- -
- - CMixTx mtx;
- - bool success = false;
- -
- - std::cout << "Recieved mixkey with client ID of " << mk.mtxid << " and server ID of "
- - << mk.smtxid << std::endl;
- -
- - std::cout << "The key is " << mk.key << std::endl;
- -
- - RSA* rsa = RSA_new();
- - RSA* servrsa = RSA_new();
- -
- - if (rsa != NULL && servrsa != NULL) {
- - {
- - LOCK(cs_mapMixTxs);
- -
- - std::map<int64, CMixTx>::iterator it = mapMixTxs.find(mk.mtxid);
- - if (it != mapMixTxs.end() // make sure we actually have the request
- - && it->second.stage == 1 // make sure we haven't already done this step
- - && it->second.inprogress == false
- - && it->second.addrName == pfrom->addrName) { // make sure it's the same server
- - std::cout << "Filthy liars." << std::endl;
- - it->second.stage = 2; // indicate that we have received the mixkey request...
- - it->second.inprogress = true; // ...but that we haven't finished processing it yet
- - it->second.rsa = rsa;
- - mtx = it->second; // save a copy of the information
- - success = true; // indicate everything went well
- - }
- - }
- -
- - if (success) {
- - std::string key;
- - if (genrsa(rsa) && rsa2hex(rsa, key)) {
- - std::cout << "Client's public hex key: " << key << std::endl;
- - std::cout << "client's rsa size: " << RSA_size(rsa) << std::endl;
- - if (hex2rsa(servrsa, mk.key)) {
- - // encrypt our public keys and target location using the server's public keys
- - CMixStart ms;
- - std::cout << "Client's server rsa size: " << RSA_size(servrsa) << std::endl;
- - if (strenc(servrsa, key, ms.key)) {
- - if (strenc(servrsa, mtx.to, ms.to)) {
- - std::cout << "Client to: " << mtx.to << std::endl;
- -
- - RSA_free(servrsa);
- -
- - ms.smtxid = mk.smtxid;
- - ms.mtxid = mk.mtxid;
- -
- - success = false;
- -
- - {
- - LOCK(cs_mapMixTxs);
- - std::map<int64, CMixTx>::iterator it = mapMixTxs.find(mk.mtxid);
- - if (it != mapMixTxs.end()) {
- - it->second.inprogress = false; // indicate we're done with stage 2
- - success = true;
- - }
- - }
- -
- - if (success) {
- - // send the server our keys and the target
- - pfrom->PushMessage("mixstart", ms);
- - }
- - else {
- - std::cerr << "Could not find transaction, maybe someone broke it?"
- - << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Could not encrypt target address" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Could not encrypt client public key" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Could not convert server key hex to RSA key" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Could not generate client key and convert public key to hex"
- - << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Received an invalid mixkey transaction from server" << std::endl;
- - }
- - } else {
- - std::cerr << "Could not allocate client and server RSA structures." << std::endl;
- - }
- - }
- -
- - else if (strCommand == "mixfin") {
- - // last step in the mixing process
- - CMixFin mf;
- - vRecv >> mf;
- -
- - CMixTx mtx;
- - bool success = false;
- -
- - {
- - LOCK(cs_mapMixTxs);
- -
- - std::map<int64, CMixTx>::iterator it = mapMixTxs.find(mf.mtxid);
- - if (it != mapMixTxs.end() // make sure we actually have the request
- - && it->second.stage == 2 // make sure we have completed the mixkey step
- - && it->second.inprogress == false
- - && it->second.addrName == pfrom->addrName) { // make sure it's the same server
- - mtx = it->second; // save a copy of the information
- - mapMixTxs.erase(mf.mtxid); // erase the transaction, we won't need it anymore
- - success = true; // indicate everything went well
- - }
- - }
- -
- - if (success) {
- - std::string address;
- - if(strdec(mtx.rsa, mf.address, address)) {
- - //send the money to the server's wallet in randomly sized transactions
- - Array args;
- - double amount = mtx.amount;
- - double currentTxAmount = 0;
- - double totalTransferred = 0;
- - unsigned char rnum;
- - bool failed_transfer_rest = false;
- - double min = (double)MIN_TXOUT_AMOUNT/(double)COIN*2;
- -
- - while (totalTransferred != amount) {
- - if (RAND_bytes(&rnum, 1) != 1) {
- - failed_transfer_rest = true;
- - rnum = 0;
- - std::cerr << "RAND_bytes failed during mixer client transfer; transferring the rest in one go" << std::endl;
- - }
- -
- - std::cout << "Random number: " << (int)rnum << " and percentage: "
- - << ((double)rnum/255.0) << std::endl;
- -
- - // maximum tx size is 90% the total amount, min tx size is a constant
- - currentTxAmount = (((double)rnum/255.0)*((amount*0.9)-min))+min;
- -
- - if (totalTransferred + currentTxAmount > amount || failed_transfer_rest) {
- - currentTxAmount = amount - totalTransferred;
- - if (currentTxAmount < min) currentTxAmount = min;
- - }
- -
- - totalTransferred += currentTxAmount;
- -
- - std::cout << "Transfer " << currentTxAmount << " from " << mtx.from << " to "
- - << address << "." << std::endl;
- -
- - args.clear();
- - args.push_back(mtx.from);
- - args.push_back(address);
- - args.push_back(currentTxAmount);
- -
- - try {
- - sendfrom(args, false);
- - }
- - catch (Object& e) {
- - std::cout << "FATAL: ";
- - for (Object::iterator i = e.begin(); i != e.end(); ++i) {
- - if ((*i).value_.type() == str_type)
- - std::cout << ">" << (*i).value_.get_str()<< std::endl;
- - }
- - break;
- - }
- - }
- - }
- - else {
- - std::cerr << "Could not decrypt intermediate address" << std::endl;
- - }
- - }
- - else {
- - std::cerr << "Invalid mixfin message from server." << std::endl;
- - }
- - }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement