bool SecurityHelper::signDataObject(DataObjectRef& dObj, RSA *key) { unsigned char *signature; if (!key || !dObj) return false; unsigned int siglen = RSA_size(key); signature = (unsigned char *)malloc(siglen); if (!signature) return false; printf("signing data object, siglen=%u\n", siglen); memset(signature, 0, siglen); if (RSA_sign(NID_sha1, dObj->getId(), sizeof(DataObjectId_t), signature, &siglen, key) != 1) { free(signature); return false; } dObj->setSignature(getManager()->getKernel()->getThisNode()->getIdStr(), signature, siglen); // Assume that our own signature is valid dObj->setSignatureStatus(DataObject::SIGNATURE_VALID); // Do not free the allocated signature as it is now owned by the data object... return true; }
bool SecurityHelper::verifyDataObject(DataObjectRef& dObj, CertificateRef& cert) const { RSA *key; // Cannot verify without signature if (!dObj->getSignature()) { HAGGLE_ERR("No signature in data object, cannot verify\n"); return false; } writeErrors("(not this): "); key = cert->getPubKey(); if (RSA_verify(NID_sha1, dObj->getId(), sizeof(DataObjectId_t), const_cast<unsigned char *>(dObj->getSignature()), dObj->getSignatureLength(), key) != 1) { char *raw; size_t len; writeErrors(""); dObj->getRawMetadataAlloc((unsigned char **)&raw, &len); if (raw) { HAGGLE_DBG("Signature is invalid:\n%s\n", raw); free(raw); } dObj->setSignatureStatus(DataObject::SIGNATURE_INVALID); return false; } HAGGLE_DBG("Signature is valid\n"); dObj->setSignatureStatus(DataObject::SIGNATURE_VALID); return true; }
ProtocolEvent ProtocolUDPGeneric::sendDataObjectNowNoControl( const DataObjectRef& dObj) { NodeRef currentPeer; { Mutex::AutoLocker l(mutex); currentPeer = peerNode; } // MOS NodeRef actualPeer = getManager()->getKernel()->getNodeStore()->retrieve(currentPeer, true); if (!actualPeer) { HAGGLE_ERR("%s Peer not in node store\n", getName()); return PROT_EVENT_ERROR; } // check if already in peers bloomfilter if (actualPeer->hasThisOrParentDataObject(dObj)) { // MOS HAGGLE_DBG("%s Peer already had data object.\n", getName()); return PROT_EVENT_SUCCESS; } // done // SW: we move the hook here to minimize race condition where we send // too many redundant node descriptions // TODO: we may want to synchronize on the dObj or have some serial // queue so this is not probabilistic sendDataObjectNowSuccessHook(dObj); HAGGLE_DBG("%s Sending data object [%s] to peer \'%s\'\n", getName(), dObj->getIdStr(), peerDescription().c_str()); DataObjectDataRetrieverRef retriever = dObj->getDataObjectDataRetriever(); if (!retriever || !retriever->isValid()) { HAGGLE_ERR("%s unable to start reading data\n", getName()); return PROT_EVENT_ERROR; } ProtocolEvent pEvent = PROT_EVENT_SUCCESS; ssize_t len = retriever->retrieve(buffer, bufferSize, false); if (0 == len) { HAGGLE_ERR("%s DataObject is empty\n", getName()); return PROT_EVENT_ERROR; } if (len < 0) { HAGGLE_ERR("%s Could not retrieve data from data object\n", getName()); return PROT_EVENT_ERROR; } if ((size_t) len == bufferSize) { HAGGLE_ERR("%s Buffer is too small for message\n", getName()); return PROT_EVENT_ERROR; } Timeval t_start; t_start.setNow(); setSessionNo(dObj->getId()); // MOS setSeqNo(0); // MOS size_t bytesSent = 0; // MOS - simple way to increase udp redundancy for(int i = 0; i <= getConfiguration()->getRedundancy(); i++) { pEvent = sendData(buffer, (size_t) len, 0, &bytesSent); if (bytesSent != (size_t) len) { pEvent = PROT_EVENT_ERROR; } if (pEvent != PROT_EVENT_SUCCESS) { HAGGLE_ERR("%s Broadcast - Error\n", getName()); return pEvent; } } #ifdef DEBUG Timeval tx_time = Timeval::now() - t_start; HAGGLE_DBG("%s Sent %lu bytes data in %.3lf seconds, average speed = %.2lf kB/s\n", getName(), len, tx_time.getTimeAsSecondsDouble(), (double)len / (1000*tx_time.getTimeAsSecondsDouble())); #endif dataObjectsOutgoing += 1; // MOS dataObjectsSent += 1; // MOS if(!dObj->isControlMessage()) dataObjectsOutgoingNonControl += 1; // MOS dataObjectBytesOutgoing += bytesSent; // MOS dataObjectBytesSent += len; // MOS if(dObj->isNodeDescription()) { nodeDescSent += 1; nodeDescBytesSent += len; } // MOS return PROT_EVENT_SUCCESS; }