int main(int argc,char **argv) { if(argc != 5) { fprintf(stderr,"%s <bank public info> <private coin request> <signed coin request> <coin>\n", argv[0]); exit(1); } const char *szBankFile=argv[1]; const char *szPrivateRequestFile=argv[2]; const char *szSignatureFile=argv[3]; const char *szCoinFile=argv[4]; SetDumper(stderr); BIO *bioBank=BIO_new_file(szBankFile,"r"); BIO *bioPrivateRequest=BIO_new_file(szPrivateRequestFile,"r"); BIO *bioSignature=BIO_new_file(szSignatureFile,"r"); BIO *bioCoin=BIO_new_file(szCoinFile,"w"); PublicBank bank(bioBank); CoinRequest req(bioPrivateRequest); ReadNumber(bioSignature,"request="); BIGNUM *bnSignature=ReadNumber(bioSignature,"signature="); DumpNumber("signature=",bnSignature); Coin coin; req.ProcessResponse(&coin,bank,bnSignature); coin.WriteBIO(bioCoin); }
// Lucre step 4: client unblinds token -- now it's ready for use. bool OTToken::ProcessToken(const OTPseudonym & theNym, OTMint & theMint, OTToken & theRequest) { // OTLog::vError("%s <bank public info> <private coin request> <signed coin request> <coin>\n", bool bReturnValue = false; // When the Mint has signed a token and sent it back to the client, // the client must unblind the token and set it as spendable. Thus, // this function is only performed on tokens in the signedToken state. if (OTToken::signedToken != m_State) { OTLog::Error("Signed token expected in OTToken::ProcessToken\n"); return false; } // Lucre SetDumper(stderr); BIO *bioBank = BIO_new(BIO_s_mem()); // input BIO *bioSignature = BIO_new(BIO_s_mem()); // input BIO *bioPrivateRequest = BIO_new(BIO_s_mem()); // input BIO *bioCoin = BIO_new(BIO_s_mem()); // output // Get the bank's public key (decoded into strPublicMint) // and put it into bioBank so we can use it with Lucre. OTASCIIArmor ascPublicMint; theMint.GetPublic(ascPublicMint, GetDenomination()); OTString strPublicMint(ascPublicMint); BIO_puts(bioBank, strPublicMint.Get()); // Get the existing signature into a bio. // OTLog::vError("DEBUGGING, m_Signature: -------------%s--------------\n", m_Signature.Get()); OTString strSignature(m_Signature); BIO_puts(bioSignature, strSignature.Get()); // I need the Private coin request also. (Only the client has this private coin request data.) OTASCIIArmor thePrototoken; // The server sets m_nChosenIndex when it signs the token. bool bFoundToken = theRequest.GetPrivatePrototoken(thePrototoken, m_nChosenIndex); if (bFoundToken) { // OTLog::vError("THE PRIVATE REQUEST ARMORED CONTENTS:\n------------------>%s<-----------------------\n", // thePrototoken.Get()); // Decrypt the prototoken OTString strPrototoken; OTEnvelope theEnvelope(thePrototoken); theEnvelope.Open(theNym, strPrototoken); // todo check return value. // OTLog::vError("THE PRIVATE REQUEST CONTENTS:\n------------------>%s<-----------------------\n", // strPrototoken.Get()); // copy strPrototoken to a BIO BIO_puts(bioPrivateRequest, strPrototoken.Get()); // ------- Okay, the BIOs are all loaded.... let's process... PublicBank bank(bioBank); CoinRequest req(bioPrivateRequest); // TODO make sure I'm not leaking memory with these ReadNumbers // Probably need to be calling some free function for each one. // Apparently reading the request id here and then just discarding it... ReadNumber(bioSignature,"request="); // Versus the signature data, which is read into bnSignature apparently. BIGNUM * bnSignature = ReadNumber(bioSignature,"signature="); DumpNumber("signature=", bnSignature); // Produce the final unblinded token in Coin coin, and write it to bioCoin... Coin coin; // Coin Request, processes into Coin, with Bank and Signature passed in. req.ProcessResponse(&coin, bank, bnSignature); // Notice still apparently "request" info is discarded. coin.WriteBIO(bioCoin); // convert bioCoin to a C-style string... char CoinBuffer[1024]; // todo stop hardcoding these string lengths int coinLen = BIO_read(bioCoin, CoinBuffer, 1000); // cutting it a little short on purpose, with the buffer. Just makes me feel more comfortable for some reason. if (coinLen) { // ...to OTString... OTString strCoin; strCoin.Set(CoinBuffer, coinLen); // OTLog::vError("Processing token...\n%s\n", strCoin.Get()); // ...to Envelope stored in m_ascSpendable (encrypted and base64-encoded) OTEnvelope theEnvelope; theEnvelope.Seal(theNym, strCoin); // Todo check the return values on these two functions theEnvelope.GetAsciiArmoredData(m_ascSpendable); // Here's the final product. // OTLog::vError("NEW SPENDABLE token...\n--------->%s<----------------\n", m_ascSpendable.Get()); // Now the coin is encrypted from here on out, and otherwise ready-to-spend. m_State = OTToken::spendableToken; bReturnValue = true; // Lastly, we free the signature data, which is no longer needed, and which could be // otherwise used to trace the token. (Which we don't want.) m_Signature.Release(); } } // Todo log error here if the private prototoken is not found. (Very strange if so!!) // else {} // Cleanup openssl resources. BIO_free_all(bioBank); BIO_free_all(bioSignature); BIO_free_all(bioPrivateRequest); BIO_free_all(bioCoin); return bReturnValue; }