// The mint has a different key pair for each denomination.
// Pass the actual denomination such as 5, 10, 20, 50, 100...
bool OTMint_Lucre::AddDenomination(OTPseudonym & theNotary, int64_t lDenomination, int32_t nPrimeLength/*=1024*/)
{
    OT_ASSERT(NULL != m_pKeyPublic);
    
	bool bReturnValue = false;
	
	// Let's make sure it doesn't already exist
	OTASCIIArmor theArmor;
	if (GetPublic(theArmor, lDenomination))
	{
		// it already exists.
		OTLog::Error("Error: Denomination public already exists in OTMint::AddDenomination\n");
		return false;
	}
	if (GetPrivate(theArmor, lDenomination))
	{
		// it already exists.
		OTLog::Error("Error: Denomination private already exists in OTMint::AddDenomination\n");
		return false;
	}
	
	//		OTLog::Error("%s <size of bank prime in bits> <bank data file> <bank public data file>\n",
	
    if ((nPrimeLength/8) < (MIN_COIN_LENGTH+DIGEST_LENGTH))
	{
		OTLog::vError("Prime must be at least %d bits\n",
				(MIN_COIN_LENGTH+DIGEST_LENGTH)*8);
		return false;
	}
	
    if (nPrimeLength%8)
	{
		OTLog::Error("Prime length must be a multiple of 8\n");
		return false;
	}
	
#ifdef _WIN32
	SetMonitor("openssl.dump");
#else
	SetMonitor(stderr);
#endif
	
    OpenSSL_BIO bio		=	BIO_new(BIO_s_mem());
    OpenSSL_BIO bioPublic	=	BIO_new(BIO_s_mem());
	
	// Generate the mint private key information
    Bank bank(nPrimeLength/8);
    bank.WriteBIO(bio);
	
	// Generate the mint public key information
    PublicBank pbank(bank);
    pbank.WriteBIO(bioPublic);	
	
	// Copy from BIO back to a normal OTString or Ascii-Armor  
	char privateBankBuffer[4096], publicBankBuffer[4096];   // todo stop hardcoding these string lengths
	int32_t  privatebankLen	= BIO_read(bio, privateBankBuffer, 4000); // cutting it a little short on purpose, with the buffer.
	int32_t  publicbankLen	= BIO_read(bioPublic, publicBankBuffer, 4000); // Just makes me feel more comfortable for some reason.
	
	if (privatebankLen && publicbankLen)
	{
		// With this, we have the Lucre public and private bank info converted to OTStrings
		OTString strPublicBank;		strPublicBank.Set(publicBankBuffer, publicbankLen);
		OTString strPrivateBank;	strPrivateBank.Set(privateBankBuffer, privatebankLen);
		
		OTASCIIArmor * pPublic	= new OTASCIIArmor();
		OTASCIIArmor * pPrivate	= new OTASCIIArmor();
		
		OT_ASSERT(NULL != pPublic);
		OT_ASSERT(NULL != pPrivate);
		
		// Set the public bank info onto pPublic
		pPublic->SetString(strPublicBank, true); // linebreaks = true
		
		// Seal the private bank info up into an encrypted Envelope 
		// and set it onto pPrivate
		OTEnvelope theEnvelope;
		theEnvelope.Seal(theNotary, strPrivateBank);	// Todo check the return values on these two functions
		theEnvelope.GetAsciiArmoredData(*pPrivate);
		
		// Add the new key pair to the maps, using denomination as the key
		m_mapPublic[lDenomination]	= pPublic;
		m_mapPrivate[lDenomination]	= pPrivate;
		
		// Grab the Server Nym ID and save it with this Mint
		theNotary.GetIdentifier(m_ServerNymID);
        // ---------------------------
		// Grab the Server's public key and save it with this Mint
        //
        const OTAsymmetricKey & theNotaryPubKey = theNotary.GetPublicSignKey();
        delete m_pKeyPublic;
        m_pKeyPublic = theNotaryPubKey.ClonePubKey();
        // ---------------------------
		m_nDenominationCount++;
        // ---------------------------		
		// Success!
		bReturnValue = true;
		OTLog::vOutput(1, "Successfully added denomination: %lld\n", lDenomination);
	}
	
	return bReturnValue;
}
示例#2
0
// 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;
}
示例#3
0
文件: JSHandler.cpp 项目: ngot/fibjs
result_t JSHandler::invoke(object_base *v, obj_ptr<Handler_base> &retVal,
                           AsyncEvent *ac)
{
    if (ac)
        return CHECK_ERROR(CALL_E_NOASYNC);

    v8::Local<v8::Object> o = v->wrap();
    Isolate* isolate = holder();

    obj_ptr<Message_base> msg = Message_base::getInstance(v);
    v8::Local<v8::Value> a = v8::Local<v8::Value>::New(isolate->m_isolate, o);
    v8::Local<v8::Value> hdlr = GetPrivate("handler");

    while (true)
    {
        v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(hdlr);
        obj_ptr<List_base> params;
        std::vector<v8::Local<v8::Value> > argv;
        v8::Local<v8::Value> *pargv;
        int32_t len = 0, i;

        if (msg != NULL)
        {
            msg->get_params(params);
            params->get_length(len);
        }

        if (len > 0)
        {
            argv.resize(len + 1);
            argv[0] = a;

            for (i = 0; i < len; i++)
            {
                Variant v;
                params->_indexed_getter(i, v);
                argv[i + 1] = v;
            }

            pargv = argv.data();
        }
        else
            pargv = &a;

        {
            TryCatch try_catch;
            hdlr = func->Call(v8::Undefined(isolate->m_isolate), len + 1, pargv);
            if (try_catch.HasCaught())
            {
                v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
                        isolate->m_isolate, 1, v8::StackTrace::kScriptId);
                if (stackTrace->GetFrameCount() > 0)
                {
                    try_catch.ReThrow();
                    return CALL_E_JAVASCRIPT;
                }
                else
                    return CHECK_ERROR(Runtime::setError(GetException(try_catch, 0)));
            }
        }

        if (IsEmpty (hdlr))
            return CALL_RETURN_NULL;

        if (!hdlr->IsFunction())
        {
            if (hdlr->IsObject())
                return JSHandler::New(hdlr, retVal);

            msg->set_result(hdlr);
            return CALL_RETURN_NULL;
        }
    }

    return 0;
}
示例#4
0
void BundleHooks::FilterBundleEventReceivers(
  const BundleEvent& evt,
  ServiceListeners::BundleListenerMap& bundleListeners)
{
  std::vector<ServiceRegistrationBase> eventHooks;
  coreCtx->services.Get(us_service_interface_iid<BundleEventHook>(),
                        eventHooks);

  {
    auto l = coreCtx->listeners.bundleListenerMap.Lock();
    US_UNUSED(l);
    bundleListeners = coreCtx->listeners.bundleListenerMap.value;
  }

  if (!eventHooks.empty()) {
    std::vector<BundleContext> bundleContexts;
    for (auto& le : bundleListeners) {
      bundleContexts.push_back(MakeBundleContext(le.first->shared_from_this()));
    }
    std::sort(bundleContexts.begin(), bundleContexts.end());
    bundleContexts.erase(
      std::unique(bundleContexts.begin(), bundleContexts.end()),
      bundleContexts.end());

    const std::size_t unfilteredSize = bundleContexts.size();
    ShrinkableVector<BundleContext> filtered(bundleContexts);

    std::sort(eventHooks.begin(), eventHooks.end());
    for (auto iter = eventHooks.rbegin(), iterEnd = eventHooks.rend();
         iter != iterEnd;
         ++iter) {
      ServiceReference<BundleEventHook> sr;
      try {
        sr = iter->GetReference();
      } catch (const std::logic_error&) {
        std::string message("Failed to get event hook service reference");
        coreCtx->listeners.SendFrameworkEvent(
          FrameworkEvent(FrameworkEvent::Type::FRAMEWORK_WARNING,
                         GetBundleContext().GetBundle(),
                         message,
                         std::current_exception()));
        continue;
      }

      std::shared_ptr<BundleEventHook> eh =
        std::static_pointer_cast<BundleEventHook>(sr.d.load()->GetService(
          GetPrivate(GetBundleContext().GetBundle()).get()));
      if (eh) {
        try {
          eh->Event(evt, filtered);
        } catch (...) {
          std::string message("Failed to call Bundle EventHook # " +
                              sr.GetProperty(Constants::SERVICE_ID).ToString());
          coreCtx->listeners.SendFrameworkEvent(
            FrameworkEvent(FrameworkEvent::Type::FRAMEWORK_WARNING,
                           GetBundleContext().GetBundle(),
                           message,
                           std::current_exception()));
        }
      }
    }

    if (unfilteredSize != bundleContexts.size()) {
      for (ServiceListeners::BundleListenerMap::iterator le =
             bundleListeners.begin();
           le != bundleListeners.end();) {
        if (std::find_if(bundleContexts.begin(),
                         bundleContexts.end(),
                         [&le](const BundleContext& bc) {
                           return GetPrivate(bc) == le->first;
                         }) == bundleContexts.end()) {
          bundleListeners.erase(le++);
        } else {
          ++le;
        }
      }
    }
  }
}