Exemplo n.º 1
0
/*
	On send events, the security manager 
 
 */
void SecurityManager::onSendDataObject(Event *e)
{
	if (!e || !e->hasData())
		return;

	DataObjectRef dObj = e->getDataObject();
	
	if (dObj->isThisNodeDescription()) {
		// This is our node description. Piggy-back our certificate.
		if (myCert) {
			Metadata *m;

			m = dObj->getMetadata()->getMetadata("Security");
			
			if (m) {
				HAGGLE_ERR("Node description already has a Security tag!\n");
			} else {
				m = dObj->getMetadata()->addMetadata("Security");
				
				if (m) {
					m->addMetadata(myCert->toMetadata());
				}
			}
		}
	}
	
	// In most cases the data object is already signed here (e.g., if it is generated by a local
	// application, or was received from another node). The only reason to check if we should
	// sign the data object here, is if a data object was generated internally by Haggle -- in
	// which case the data object might not have a signature (e.g., the data object is a node
	// description).
	InterfaceRef iface = dObj->getRemoteInterface();
	
	if (dObj->shouldSign() && !(iface && iface->getType() == Interface::TYPE_APPLICATION_PORT)) {
		// FIXME: data objects should really be signed in the SecurityHelper thread since
		// it is a potentially CPU intensive operation. But it is currently not possible
		// to ensure that the signing operation has finished in the helper thread before
		// the data object is actually sent on the wire by the protocol manager.
		// To handle this situation, we probably need to add a new public event for 
		// security related operations, after which the security manager generates the
		// real send event.
		
		if (helper->signDataObject(dObj, privKey)) {
			HAGGLE_DBG("Successfully signed data object %s\n", dObj->getIdStr());
		} else {
			HAGGLE_DBG("Signing of data object %s failed!\n", dObj->getIdStr());
		}
	}	
}
Exemplo n.º 2
0
/*
	Check incoming data objects for two reasons:
	1) whether they have an embedded certificate, in which case we verify 
	it and add it to our store in case it is not already there.
	2) sign any data objects that were generated by local applications.
 */
void SecurityManager::onIncomingDataObject(Event *e)
{
	DataObjectRef dObj;
	
	if (!e || !e->hasData())
		return;
	
	dObj = e->getDataObject();
	
	if (dObj->isDuplicate())
		return;

	Metadata *m = dObj->getMetadata()->getMetadata("Security");
	
	// Check if there is a certificate embedded that we do not already have stored
	if (m && m->getMetadata("Certificate")) {
		HAGGLE_DBG("Data object has embedded certificate, trying to verify it!\n");
		helper->addTask(new SecurityTask(SECURITY_TASK_VERIFY_CERTIFICATE, dObj));
	}
			
	InterfaceRef iface = dObj->getRemoteInterface();

	// Check if this data object came from an application, in that case we sign it.
	// In the future, the signing should potentially be handled by the application
	// itself. But this requires some major rethinking of how to manage certificates 
	// and keys, etc.
	if (iface && iface->getType() == Interface::TYPE_APPLICATION_PORT && dObj->shouldSign()) {
		HAGGLE_DBG("Data object should be signed\n");

		// FIXME: data objects should really be signed in the SecurityHelper thread since
		// it is a potentially CPU intensive operation. But it is currently not possible
		// to ensure that the signing operation has finished in the helper thread before
		// the data object is added to the data store.
		if (helper->signDataObject(dObj, privKey)) {
			HAGGLE_DBG("Successfully signed data object %s, which was added by an application.\n", 
				   dObj->getIdStr());
		} else {
			HAGGLE_DBG("Signing of data object %s, which was added by an application, failed!\n", 
				   dObj->getIdStr());
		}
	}
}