Example #1
0
// Use a local variable for theToken, do NOT allocate it on the heap
// unless you are going to delete it yourself.
// Repeat: OTPurse is NOT responsible to delete it. We create our OWN internal
// variable here, new that, and add it to the stack. We do not add the one passed in.
bool OTPurse::Push(const OTPseudonym & theOwner, const OTToken & theToken)
{
    if (theToken.GetAssetID() == m_AssetID)
    {
        OTString strToken(theToken);

//		OTLog::vError("$$$$$$$$$$$$$$$  PUSHING token to Purse:\n---------->%s<-------------\n", strToken.Get());

        OTEnvelope theEnvelope;
        theEnvelope.Seal(theOwner, strToken);

        OTASCIIArmor * pArmor = new OTASCIIArmor(theEnvelope);
//		OTLog::vError("$$$$$$$$$$$$$$$  PUSHING token to Purse in armored form:\n---------->%s<-------------\n",
//				pArmor->Get());

        m_dequeTokens.push_front(pArmor);

        // We keep track of the purse's total value.
        m_lTotalValue += theToken.GetDenomination();

        return true;
    }
    else {
        OTString strPurseAssetType(m_AssetID), strTokenAssetType(theToken.GetAssetID());
        OTLog::vError("ERROR: Tried to push token with wrong asset type in OTPurse::Push\nPurse Asset Type:\n%s\n"
                      "Token Asset Type:\n%s\n", strPurseAssetType.Get(), strTokenAssetType.Get());

        return false;
    }
}
Example #2
0
// Hypocritically (compared to Push) in the case of Pop(), we DO
// allocate a OTToken and return the pointer. The caller IS
// responsible to delete it when he's done with it.
//
// The apparent discrepancy is due to the fact that internally,
// we aren't storing the token object but an encrypted string of it.
// But this is hidden from the user of the purse, who perceives only
// that he is passing tokens in and getting them back out again.
OTToken * OTPurse::Pop(const OTPseudonym & theOwner)
{
    if (m_dequeTokens.empty())
        return NULL;


    // Grab a copy of the pointer and remove it from the deque
    OTASCIIArmor * pArmor =  m_dequeTokens.front();
    m_dequeTokens.pop_front();

//	OTLog::vError("$$$$$$$$$$$$$$ ARMORED TEXT in PURSE POP:\n--------->%s<-----------\n", pArmor->Get());

    // Copy the token contents into an Envelope, and delete the pointer.
    OTEnvelope theEnvelope(*pArmor);
    delete pArmor;
    pArmor = NULL;

    // Open the envelope into a string.
    OTString strToken;
    theEnvelope.Open(theOwner, strToken);

//	OTLog::vError("$$$$$$$$$$$$$$$ OPENED ENVELOPE TEXT in PURSE POP:\n--------->%s<-----------\n", strToken.Get());

    // Create a new token with the same server and asset IDs as this purse.
    OTToken * pToken =  new OTToken(*this);

    OT_ASSERT(NULL != pToken);

    // Load the token from the string we got out of the envelope.
    pToken->LoadContractFromString(strToken);

    if (pToken->GetAssetID() != m_AssetID ||
            pToken->GetServerID() != m_ServerID)
    {
        delete pToken;
        pToken = NULL;

        OTLog::Error("ERROR: Token with wrong asset type in OTPurse::Pop\n");
    }
    else
    {
        // We keep track of the purse's total value.
        m_lTotalValue -= pToken->GetDenomination();
    }

    // CALLER is responsible to delete this token.
    return pToken;
}
// Lucre step 3: the mint signs the token
// 
bool OTMint_Lucre::SignToken(OTPseudonym & theNotary, OTToken & theToken, OTString & theOutput, int32_t nTokenIndex)
{
	bool bReturnValue = false;
	
	//OTLog::Error("%s <bank file> <coin request> <coin signature> [<signature repeats>]\n",
    _OT_Lucre_Dumper setDumper;
	
//	OTLog::vError("OTMint::SignToken!!\nnTokenIndex: %d\n Denomination: %lld\n", nTokenIndex, theToken.GetDenomination());
	
    OpenSSL_BIO bioBank		= BIO_new(BIO_s_mem()); // input
    OpenSSL_BIO bioRequest		= BIO_new(BIO_s_mem()); // input
    OpenSSL_BIO bioSignature	= BIO_new(BIO_s_mem()); // output
	
	OTASCIIArmor thePrivate;
	GetPrivate(thePrivate, theToken.GetDenomination());
	
	// The Mint private info is encrypted in m_mapPrivates[theToken.GetDenomination()]. 
	// So I need to extract that first before I can use it.
	OTEnvelope theEnvelope(thePrivate);

	OTString strContents; // output from opening the envelope.
	// Decrypt the Envelope into strContents    
	if (!theEnvelope.Open(theNotary, strContents))
		return false;

	// copy strContents to a BIO
	BIO_puts(bioBank, strContents.Get());
	
//	OTLog::vError("BANK CONTENTS:\n%s--------------------------------------\n", strContents.Get());
	
	// Instantiate the Bank with its private key
    Bank bank(bioBank);
//	OTLog::vError("BANK INSTANTIATED.--------------------------------------\n");

	// I need the request. the prototoken.
	OTASCIIArmor ascPrototoken;
	bool bFoundToken = theToken.GetPrototoken(ascPrototoken, nTokenIndex);
	
	if (bFoundToken)
	{
		// base64-Decode the prototoken
		OTString strPrototoken(ascPrototoken);
		
//		OTLog::vError("\n--------------------------------------\nDEBUG:  PROTOTOKEN CONTENTS:\n"
//				"-----------------%s---------------------\n", strPrototoken.Get() );
		
		// copy strPrototoken to a BIO
		BIO_puts(bioRequest, strPrototoken.Get());

		// Load up the coin request from the bio (the prototoken)
		PublicCoinRequest req(bioRequest);
//		OTLog::Error("PROTOTOKEN INSTANTIATED.--------------------------------------\n");

		// Sign it with the bank we previously instantiated.
		// results will be in bnSignature (BIGNUM)
		BIGNUM * bnSignature = bank.SignRequest(req);

		if (NULL == bnSignature)
		{
			OTLog::Error("MAJOR ERROR!: Bank.SignRequest failed in OTMint_Lucre::SignToken\n");
		}
		
		else 
		{
//			OTLog::Error("BANK.SIGNREQUEST SUCCESSFUL.--------------------------------------\n");

			// Write the request contents, followed by the signature contents,
			// to the Signature bio. Then free the BIGNUM.
			req.WriteBIO(bioSignature); // the original request contents
			DumpNumber(bioSignature,"signature=", bnSignature); // the new signature contents
			BN_free(bnSignature);

			// Read the signature bio into a C-style buffer...
			char sig_buf[1024];   // todo stop hardcoding these string lengths
//			memset(sig_buf, 0, 1024); // zero it out. (I had this commented out, but the size was 2048, so maybe it's safe now at 1024.)
			
			int32_t sig_len	= BIO_read(bioSignature, sig_buf, 1000); // cutting it a little short on purpose, with the buffer. Just makes me feel more comfortable for some reason.
			
			
			// Add the null terminator by hand (just in case.)
			sig_buf[sig_len]	= '\0';
			
			if (sig_len)
			{ // ***********************************************
//				OTLog::vError("\n--------------------------------------\n"
//						"*** Siglen is %d. sig_str_len is %d.\nsig buf:\n------------%s------------\nLAST "
//						"CHARACTER IS '%c'  SECOND TO LAST CHARACTER IS '%c'\n", 
//						sig_len, sig_str_len, sig_buf, sig_buf[sig_str_len-1], sig_buf[sig_str_len-2]);
				
				// Copy the original coin request into the spendable field of the token object.
				// (It won't actually be spendable until the client processes it, though.)
				theToken.SetSpendable(ascPrototoken);
				
//				OTLog::vError("*** SPENDABLE:\n-----------%s---------------------\n", ascPrototoken.Get());
						
						
				// Base64-encode the signature contents into theToken.m_Signature.
				OTString	strSignature(sig_buf);
	//			strSignature.Set(sig_buf, sig_len-1); // sig_len includes null terminator, whereas Set() adds 1 for it.
				
//				OTLog::vError("SIGNATURE:\n--------------------%s"
//						"------------------\n", strSignature.Get());

				// Here we pass the signature back to the caller.
				// He will probably set it onto the token.
				theOutput.Set(sig_buf, sig_len);
				bReturnValue = true;
				
				// This is also where we set the expiration date on the token.
				// The client should have already done this, but we are explicitly
				// setting the values here to prevent any funny business.
				theToken.SetSeriesAndExpiration(m_nSeries, m_VALID_FROM, m_VALID_TO);
			}
		}
	}

	return bReturnValue;
}