def test_copy_fields(self): data = Data(self.freshData.getName()) data.setContent(self.freshData.getContent()) data.setMetaInfo(self.freshData.getMetaInfo()) self.credentials.signData(data) self.assertTrue(dataDumpsEqual(freshDump, initialDump), 'Freshly created data does not match original dump')
def test_copy_fields(self): data = Data(self.freshData.getName()) data.setContent(self.freshData.getContent()) data.setMetaInfo(self.freshData.getMetaInfo()) self.credentials.signData(data) freshDump = dumpData(data) self.assertTrue(dataDumpsEqual(freshDump, initialDump), 'Freshly created data does not match original dump')
def onInterest(self, prefix, interest, face, interestFilterId, filter): self._callbackCount = 0 # log.debug("prefix: '{}'".format(prefix)) # log.debug("interest: '{}'".format(interest)) # log.debug("face: '{}'".format(face)) # log.debug("interestFilterId: '{}'".format(interestFilterId)) # log.debug("filter: '{}'".format(filter)) data = Data() # # log.debug("----") # for n in self.db: # log.debug(n) # log.debug(self.db[n].value) # log.debug("----") # n = str(prefix).split("/")[-1] log.debug("{} value '{}' ({})".format(prefix, self.db[n].value, self.freshnessPeriod)) data.setContent(str(self.db[n].value)) # TODO: Why does this need to be converted to string? data.setName(prefix) meta = MetaInfo() meta.setFreshnessPeriod(self.freshnessPeriod) data.setMetaInfo(meta) self.keyChain.sign(data) face.putData(data)
def capture(self, interest, transport): # print("capture cmd received start processing") interestName = interest.getName() if (interestName.size() >= 7): #right format segmentIndex = interestName.get(6).toSegment() # print "request segmentIndex : ",segmentIndex if segmentIndex == 0: # print("a new picture") #request a new picture self.stream = io.BytesIO() self.stream.flush() self.segmentList = [] self.dataList = [] self.camera.capture(self.stream, 'jpeg') #print("photo caputred in stream") imageBytes = self.stream.getvalue() print ("imageBytes %d" % len(imageBytes)) #segmentation self.segmentNumber = len(imageBytes)/(self.segmentSize+1)+1 print("segmentNumber: %d" % self.segmentNumber) for i in range(self.segmentNumber): startIndex = i*self.segmentSize if (i != self.segmentNumber -1): segBytes = imageBytes[startIndex:(startIndex+self.segmentSize)] else: segBytes = imageBytes[startIndex:] #self.segmentList.append(segBytes) newName = interestName.getPrefix(-1).appendSegment(i) #print newName.toUri() data = Data(newName) metaInfo = MetaInfo() metaInfo.setFinalBlockId(Blob.fromRawStr(str(self.segmentNumber-1))) data.setMetaInfo(metaInfo) #data.setContent(Blob.fromRawStr(self.segmentList[i])) data.setContent(Blob.fromRawStr(segBytes)) self.dataList.append(data) self.sendData(self.dataList[0], transport, sign=False) else: self.sendData(self.dataList[segmentIndex], transport, sign=False)
def nodata_reply(self, name, code, retry_after=0.0): # type: (Name, int, float) -> None logging.info("Reply with code: %s", code) data = Data(name) metainfo = MetaInfo() msg = ServerResponseMessage() msg.server_response.ret_code = code if code != RET_OK: metainfo.type = ContentType.NACK else: metainfo.type = ContentType.BLOB if retry_after > 0.1: metainfo.freshnessPeriod = int(retry_after / 10) msg.server_response.retry_after = int(retry_after) else: metainfo.freshnessPeriod = 600 data.setMetaInfo(metainfo) data.setContent(ProtobufTlv.encode(msg)) self.keychain.sign(data) self.face.putData(data)
def onInterest(self, prefix, interest, transport, registeredPrefixId): """ Interest: Name: /ndn/no/ntnu/<device>/sensorPull/<nonce> Selector: KeyLocator = ID The ID of the requesting Device is stored in KeyLocator in the Interest, and the TemporaryMasterPublicKey to the device is sent in the Interest Name as shown above. Encrypt a symmetric key with the MasterPublicKey and the ID. Encrypt the SensorData with symmetric encryption, using the symmetric key. Data: Content: master_public_key to PKG ibeKey = ibe(randomKey) cipher = encrypt(sensorData, randomKey) Sign the Data and send. :param Name prefix: :param Interest interest: :param Transport transport: An object of a subclass of Transport to use for communication. :param Name registeredPrefixId: """ self.ibs_scheme.verifyInterest(self.signature_master_public_key, interest, self.onVerifiedInterest, self.onVerifyInterestFailed) ID = "" if interest.getKeyLocator().getType() == KeyLocatorType.KEYNAME: ID = interest.getKeyLocator().getKeyName().toUri() keyName = interest.getName() session = keyName.get(keyName.size() - 1).toEscapedString() data = Data(interest.getName()) contentData = "This should be sensordata blablabla" # Symmetric key for encryption self.key = self.ibe_scheme.getRandomKey() # Identity-Based Encryption of symmetric key identityBasedEncryptedKey = self.ibe_scheme.encryptKey( self.master_public_key, ID, self.key) identityBasedEncryptedKey = str( serializeObject(identityBasedEncryptedKey, self.ibe_scheme.group)) # Master Public Key identityBasedMasterPublicKey = str( serializeObject(self.master_public_key, self.ibe_scheme.group)) # Signature Master Public Key identityBasedSignatureMasterPublicKey = str( serializeObject(self.signature_master_public_key, self.ibs_scheme.group)) # Symmetric AES encryption of contentData a = SymmetricCryptoAbstraction(extractor(self.key)) encryptedMessage = a.encrypt(contentData) message = messageBuf_pb2.Message() message.identityBasedMasterPublicKey = identityBasedMasterPublicKey message.identityBasedSignatureMasterPublicKey = identityBasedSignatureMasterPublicKey message.identityBasedEncryptedKey = identityBasedEncryptedKey message.encryptedMessage = encryptedMessage message.encAlgorithm = messageBuf_pb2.Message.AES message.ibeAlgorithm = self.ibe_scheme.algorithm message.ibsAlgorithm = self.ibs_scheme.algorithm message.nonce = session message.timestamp = int(round(util.getNowMilliseconds() / 1000.0)) message.type = messageBuf_pb2.Message.SENSOR_DATA content = message.SerializeToString() metaInfo = MetaInfo() metaInfo.setFreshnessPeriod(30000) # 30 seconds data.setContent(Blob(content)) data.setMetaInfo(metaInfo) self.ibs_scheme.signData(self.signature_master_public_key, self.signature_private_key, self.deviceName, data) #self.keyChain.sign(data, self.certificateName) encodedData = data.wireEncode() logging.info("Encrypting with ID: " + ID) transport.send(encodedData.toBuffer()) logging.info("Sent encrypted Data")
def setObject(self, namespace, obj, useSignatureManifest=False): """ Segment the object and create child segment packets of the given Namespace. :param Namespace namespace: The Namespace to append segment packets to. This ignores the Namespace from setNamespace(). :param Blob obj: The object to segment. :param bool useSignatureManifest: (optional) If True, only use a DigestSha256Signature on the segment packets and create a signed _manifest packet as a child of the given Namespace. If omitted or False, sign each segment packet individually. """ keyChain = namespace._getKeyChain() if keyChain == None: raise RuntimeError( "SegmentStreamHandler.setObject: There is no KeyChain") # Get the final block ID. finalSegment = 0 # Instead of a brute calculation, imitate the loop we will use below. segment = 0 offset = 0 while offset < obj.size(): finalSegment = segment segment += 1 offset += self._maxSegmentPayloadLength finalBlockId = Name().appendSegment(finalSegment)[0] SHA256_DIGEST_SIZE = 32 if useSignatureManifest: # Get ready to save the segment implicit digests. manifestContent = bytearray( (finalSegment + 1) * SHA256_DIGEST_SIZE) # Use a DigestSha256Signature with all zeros. digestSignature = DigestSha256Signature() digestSignature.setSignature(Blob(bytearray(SHA256_DIGEST_SIZE))) segment = 0 offset = 0 while offset < obj.size(): payloadLength = self._maxSegmentPayloadLength if offset + payloadLength > obj.size(): payloadLength = obj.size() - offset # Make the Data packet. segmentNamespace = namespace[Name.Component.fromSegment(segment)] data = Data(segmentNamespace.getName()) metaInfo = namespace._getNewDataMetaInfo() if metaInfo != None: # Start with a copy of the provided MetaInfo. data.setMetaInfo(metaInfo) data.getMetaInfo().setFinalBlockId(finalBlockId) data.setContent(obj.toBytes()[offset:offset + payloadLength]) if useSignatureManifest: data.setSignature(digestSignature) # Append the implicit digest to the manifestContent. implicitDigest = data.getFullName()[-1].getValue() digestOffset = segment * SHA256_DIGEST_SIZE manifestContent[digestOffset:digestOffset + SHA256_DIGEST_SIZE] = \ implicitDigest.toBytes()[:] else: keyChain.sign(data) segmentNamespace.setData(data) segment += 1 offset += self._maxSegmentPayloadLength if useSignatureManifest: # Create the _manifest data packet. namespace[self.NAME_COMPONENT_MANIFEST].serializeObject( Blob(manifestContent)) # TODO: Do this in a canSerialize callback from Namespace.serializeObject? namespace._setObject(obj)
def on_result_interest(self, _prefix, interest, face, _interest_filter_id, _filter_obj): # type: (Name, Interest, Face, int, InterestFilter) -> bool prefix = Name(SERVER_PREFIX).append(RESULT_PREFIX) if not prefix.isPrefixOf(interest.name): # Wrong prefix return False data_name = interest.name[prefix.size():] logging.info("On result interest: %s", data_name.toUri()) # key, stat = self._result_set_prefix_match(data_name) status = self.load_status(data_name) if status is None: # No such request self.nodata_reply(interest.name, RET_NO_REQUEST) return True if data_name[-1].isSegment(): # Segment no suffix seg_no = data_name[-1].toSegment() result = self.storage.get(data_name.getPrefix(-1)) elif data_name[-1] == Name("_meta")[0]: # MetaInfo suffix seg_no = -1 result = self.storage.get(data_name.getPrefix(-1)) else: # No suffix seg_no = None result = self.storage.get(data_name) if result is not None: # There are data segment_cnt = (len(result) + self.segment_size - 1) // self.segment_size # Note: I don't understand why namespace keep all data in memory metainfo = MetaInfo() # metainfo.setFinalBlockId(segment_cnt - 1) # WHY this doesn't work? metainfo.setFinalBlockId(Name().appendSegment(segment_cnt - 1)[0]) if segment_cnt > 1 and seg_no is None: # Fetch segmented data with no suffix will get only first segment seg_no = 0 data_name.appendSequenceNumber(seg_no) data = Data(Name(prefix).append(data_name)) data.setMetaInfo(metainfo) if seg_no == -1: # _meta data.content = self.storage.get(data_name) else: # data if segment_cnt > 1: # Segmented if seg_no < segment_cnt: start_offset = seg_no * self.segment_size end_offset = start_offset + self.segment_size data.content = Blob(bytearray(result[start_offset:end_offset])) else: data.content = None else: # No segmentation data.content = Blob(bytearray(result)) self.keychain.sign(data) face.putData(data) return True else: # Data are not ready if status.status == STATUS_NO_INPUT: self.nodata_reply(interest.name, RET_NO_INPUT) elif status.status == STATUS_FAILED: self.nodata_reply(interest.name, RET_EXECUTION_FAILED) else: self.nodata_reply(interest.name, RET_RETRY_AFTER, status.estimated_time - Common.getNowMilliseconds()) return True