// 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; }
// 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; }
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; }
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; } } } } }