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)
Example #2
0
    def _onObjectNeeded(self, namespace, neededNamespace, callbackId):
        """
        This is called for object needed at the Handler's namespace. If
        neededNamespace is the Handler's Namespace (called by the appliction),
        then fetch the _latest packet. If neededNamespace is for the _latest
        packet (from an incoming Interest), produce the _latest packet for the
        current sequence number.
        """
        if neededNamespace == self.namespace:
            # Assume this is called by a consumer. Fetch the _latest packet.
            self._latestNamespace.objectNeeded(True)
            return True

        if (neededNamespace == self._latestNamespace
                and self._producedSequenceNumber >= 0):
            # Produce the _latest Data packet.
            sequenceName = Name(self.namespace.name).append(
                Name.Component.fromSequenceNumber(
                    self._producedSequenceNumber))
            delegations = DelegationSet()
            delegations.add(1, sequenceName)

            versionedLatest = self._latestNamespace[Name.Component.fromVersion(
                Common.getNowMilliseconds())]
            metaInfo = MetaInfo()
            metaInfo.setFreshnessPeriod(self._latestPacketFreshnessPeriod)
            versionedLatest.setNewDataMetaInfo(metaInfo)
            # Make the Data packet and reply to outstanding Interests.
            versionedLatest.serializeObject(delegations.wireEncode())

            return True

        return False
Example #3
0
def main():
    # The default Face will connect using a Unix socket, or to "localhost".
    face = Face()

    # Create an in-memory key chain with default keys.
    keyChain = KeyChain()
    face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName())

    streamNamespace = Namespace(Name("/example-data"), keyChain)

    dump("Register prefix", streamNamespace.name)
    # Set the face and register to receive Interests.
    streamNamespace.setFace(face,
      lambda prefixName: dump("Register failed for prefix", prefixName))

    # /example-data/2~3
    for sequenceNumber in range(2, 4):
        sequenceNamespace = streamNamespace[str(sequenceNumber)]
        dump("Preparing data for", sequenceNamespace.name)

        # Prepare the _meta packet.
        contentMetaInfo = ContentMetaInfo()
        contentMetaInfo.setContentType("jpeg")
        contentMetaInfo.setTimestamp(Common.getNowMilliseconds())
        contentMetaInfo.setHasSegments(True)
        sequenceNamespace["_meta"].serializeObject(contentMetaInfo.wireEncode())

        # Read jpeg file
        img_path = os.path.join(root_path, "sample420x236.jpg")
        with open(img_path, "rb") as f:
            data = f.read()
        segment_size = face.getMaxNdnPacketSize() // 2
        segment_cnt = (len(data) + segment_size - 1) // segment_size

        # We know the content has two segments.
        metaInfo = MetaInfo()
        metaInfo.setFinalBlockId(Name().appendSegment(segment_cnt - 1)[0])
        sequenceNamespace.setNewDataMetaInfo(metaInfo)
        for i in range(segment_cnt):
            start_offset = i * segment_size
            end_offset = start_offset + segment_size
            sequenceNamespace[Name.Component.fromSegment(i)].serializeObject(
                Blob(bytearray(data[start_offset:end_offset])))

    while True:
        face.processEvents()
        # We need to sleep for a few milliseconds so we don't use 100% of the CPU.
        time.sleep(0.01)
Example #4
0
def main():
    # The default Face will connect using a Unix socket, or to "localhost".
    face = Face()

    # Use the system default key chain and certificate name to sign.
    keyChain = KeyChain()
    face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName())

    prefix = Namespace("/ndn/test/status", keyChain)

    dump("Register prefix", prefix.name)
    # Set the face and register to receive Interests.
    prefix.setFace(face,
      lambda prefixName: dump("Register failed for prefix", prefixName))

    handler = GeneralizedObjectHandler()
    # Each generalized object will have a 1000 millisecond freshness period.
    metaInfo = MetaInfo()
    metaInfo.setFreshnessPeriod(1000.0)

    # This is called when the library receives an Interest which is not
    # satisfied by Data already in the Namespace tree.
    def onObjectNeeded(namespace, neededNamespace, callbackId):
        if not (neededNamespace is prefix):
            # This is not the expected Namespace.
            return False

        # Make a version from the current time.
        versionNamespace = prefix[
          Name.Component.fromVersion(Common.getNowMilliseconds())]
        # The metaInfo has the freshness period.
        versionNamespace.setNewDataMetaInfo(metaInfo)
        dump("Producing the generalized object for", versionNamespace.name)
        handler.setObject(
          versionNamespace, Blob("Status as of " + str(datetime.datetime.now())),
          "text/html")
        return True

    prefix.addOnObjectNeeded(onObjectNeeded)

    while True:
        face.processEvents()
        # We need to sleep for a few milliseconds so we don't use 100% of the CPU.
        time.sleep(0.01)
Example #5
0
def main(args):
    face = Face()

    keyChain = KeyChain()
    face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName())

    gobj = Namespace(args['<prefix>'], keyChain)

    gobj.setFace(
        face,
        lambda prefixName: dump("Register failed for prefix", prefixName))

    handler = GeneralizedObjectHandler()

    metaInfo = MetaInfo()
    if args['--freshness']:
        metaInfo.setFreshnessPeriod(float(args['--freshness']))
    else:
        metaInfo.setFreshnessPeriod(1000.0)

    def onObjectNeeded(namespace, neededNamespace, callbackId):
        if not (neededNamespace is gobj):
            # This is not the expected Namespace.
            return False

        # Make a version from the current time.
        versionNamespace = gobj[Name.Component.fromVersion(
            Common.getNowMilliseconds())]
        # The metaInfo has the freshness period.
        versionNamespace.setNewDataMetaInfo(metaInfo)

        with open(args['<file>'], 'r') as f:
            handler.setObject(versionNamespace, Blob(f.read()), "text/html")
        return True

    gobj.addOnObjectNeeded(onObjectNeeded)
    while True:
        face.processEvents()
        time.sleep(0.01)
Example #6
0
    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)
Example #7
0
    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")
Example #8
0
def main():
    # The default Face will connect using a Unix socket, or to "localhost".
    face = Face()

    # Create an in-memory key chain with default keys.
    keyChain = KeyChain("pib-memory:", "tpm-memory:")
    keyChain.importSafeBag(
        SafeBag(Name("/testname/KEY/123"),
                Blob(DEFAULT_RSA_PRIVATE_KEY_DER, False),
                Blob(DEFAULT_RSA_PUBLIC_KEY_DER, False)))
    face.setCommandSigningInfo(keyChain, keyChain.getDefaultCertificateName())
    # Enable Interest loopback so that the EncryptorV2 can fetch Data packets
    # from the AccessManagerV2.
    face.setInterestLoopbackEnabled(True)

    contentPrefix = Name("/testname/content")
    contentNamespace = Namespace(contentPrefix, keyChain)

    # We know the content has two segments.
    metaInfo = MetaInfo()
    metaInfo.setFinalBlockId(Name().appendSegment(1)[0])
    contentNamespace.setNewDataMetaInfo(metaInfo)

    ckPrefix = Name("/some/ck/prefix")
    encryptor = prepareData(ckPrefix, keyChain, face)

    # Make the callback to produce a Data packet for a content segment.
    def onObjectNeeded(namespace, neededNamespace, id):
        if not (len(neededNamespace.name) == len(contentPrefix) + 1
                and contentPrefix.isPrefixOf(neededNamespace.name)
                and neededNamespace.name[-1].isSegment()):
            # Not a content segment, ignore.
            return False

        # Get the segment number.
        segment = neededNamespace.name[-1].toSegment()
        if not (segment >= 0 and segment <= 1):
            # An invalid segment was requested.
            return False

        segmentContent = ("This test message was decrypted"
                          if segment == 0 else " from segments.")
        # Now call serializeObject which will answer the pending incoming Interest.
        dump("Producing Data", neededNamespace.name)
        neededNamespace.serializeObject(
            encryptor.encrypt(Blob(segmentContent)).wireEncodeV2())

        return True

    contentNamespace.addOnObjectNeeded(onObjectNeeded)

    dump("Register prefix", contentNamespace.name)
    # Set the face and register to receive Interests.
    contentNamespace.setFace(
        face,
        lambda prefixName: dump("Register failed for prefix", prefixName))

    while True:
        face.processEvents()
        # We need to sleep for a few milliseconds so we don't use 100% of the CPU.
        time.sleep(0.01)
Example #9
0
    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