Exemple #1
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.
        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        # Now process as Interest or Data.
        if data != None:
            if self._onBtleData:
                self._onBtleData(data)
Exemple #2
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """
        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

        # Now process as Interest or Data.
        if interest != None:
            # Call all interest filter callbacks which match.
            for i in range(len(self._interestFilterTable)):
                entry = self._interestFilterTable[i]
                if entry.getFilter().doesMatch(interest.getName()):
                    includeFilter = True
                    # Use getcallargs to test if onInterest accepts 5 args.
                    try:
                        inspect.getcallargs(entry.getOnInterest(),
                          None, None, None, None, None)
                    except TypeError:
                        # Assume onInterest is old-style with 4 arguments.
                        includeFilter = False

                    if includeFilter:
                        try:
                            entry.getOnInterest()(
                              entry.getFilter().getPrefix(), interest,
                              entry.getFace(), entry.getInterestFilterId(),
                              entry.getFilter())
                        except:
                            logging.exception("Error in onInterest")
                    else:
                        # Old-style onInterest without the filter argument. We
                        # still pass a Face instead of Transport since Face also
                        # has a send method.
                        try:
                            entry.getOnInterest()(
                              entry.getFilter().getPrefix(), interest,
                              entry.getFace(), entry.getInterestFilterId())
                        except:
                            logging.exception("Error in onInterest")
        elif data != None:
            pendingInterests = self._extractEntriesForExpressedInterest(
              data.getName())
            for pendingInterest in pendingInterests:
                try:
                    pendingInterest.getOnData()(pendingInterest.getInterest(), data)
                except:
                    logging.exception("Error in onData")
Exemple #3
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.
        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        # Now process as Interest or Data.
        if data != None:
            if self._onBtleData:
                self._onBtleData(data)
Exemple #4
0
    def wireDecode(self, buf, wireFormat=None):
        """
        Override to call the base class wireDecode then check the certificate
        format.

        :param input: The array with the bytes to decode. If input is not a
          Blob, then copy the bytes to save the defaultWireEncoding (otherwise
          take another pointer to the same Blob).
        :type input: A Blob or an array type with int elements
        :param wireFormat: (optional) A WireFormat object used to decode this
           Data object. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        """
        Data.wireDecode(self, buf, wireFormat)
        self._checkFormat()
Exemple #5
0
    def wireDecode(self, buf, wireFormat = None):
        """
        Override to call the base class wireDecode then check the certificate
        format.

        :param input: The array with the bytes to decode. If input is not a
          Blob, then copy the bytes to save the defaultWireEncoding (otherwise
          take another pointer to the same Blob).
        :type input: A Blob or an array type with int elements
        :param wireFormat: (optional) A WireFormat object used to decode this
           Data object. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        """
        Data.wireDecode(self, buf, wireFormat)
        self._checkFormat()
Exemple #6
0
    def wireDecode(self, input, wireFormat = None):
        """
        Override to call the base class wireDecode then populate the list of
        delegations from the content.

        :param input: The array with the bytes to decode.
        :type input: A Blob or an array type with int elements
        :param wireFormat: (optional) A WireFormat object used to decode this
           DelegationSet. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        """
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        Data.wireDecode(self, input, wireFormat)
        if self.getMetaInfo().getType() != ContentType.LINK:
            raise RuntimeError(
              "Link.wireDecode: MetaInfo ContentType is not LINK.")

        self._delegations.wireDecode(self.getContent())
Exemple #7
0
    def wireDecode(self, input, wireFormat=None):
        """
        Override to call the base class wireDecode then populate the list of
        delegations from the content.

        :param input: The array with the bytes to decode.
        :type input: A Blob or an array type with int elements
        :param wireFormat: (optional) A WireFormat object used to decode this
           DelegationSet. If omitted, use WireFormat.getDefaultWireFormat().
        :type wireFormat: A subclass of WireFormat
        """
        if wireFormat == None:
            # Don't use a default argument since getDefaultWireFormat can change.
            wireFormat = WireFormat.getDefaultWireFormat()

        Data.wireDecode(self, input, wireFormat)
        if self.getMetaInfo().getType() != ContentType.LINK:
            raise RuntimeError(
                "Link.wireDecode: MetaInfo ContentType is not LINK.")

        self._delegations.wireDecode(self.getContent())
Exemple #8
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.
        
        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """
        # The type codes for TLV Interest and Data packets are chosen to not
        #   conflict with the first byte of a binary XML packet, so we canjust
        #   look at the first byte.
        if not (element[0] == Tlv.Interest or element[0] == Tlv.Data):
            # Ignore non-TLV elements.
            return

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

        # Now process as Interest or Data.
        if interest != None:
            entry = self._getEntryForRegisteredPrefix(interest.getName())
            if entry != None:
                entry.getOnInterest()(entry.getPrefix(), interest,
                                      self._transport,
                                      entry.getRegisteredPrefixId())
        elif data != None:
            pendingInterests = self._extractEntriesForExpressedInterest(
                data.getName())
            for pendingInterest in pendingInterests:
                pendingInterest.getOnData()(pendingInterest.getInterest(),
                                            data)
Exemple #9
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """
        # The type codes for TLV Interest and Data packets are chosen to not
        #   conflict with the first byte of a binary XML packet, so we canjust
        #   look at the first byte.
        if not (element[0] == Tlv.Interest or element[0] == Tlv.Data):
            # Ignore non-TLV elements.
            return

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

        # Now process as Interest or Data.
        if interest != None:
            entry = self._getEntryForRegisteredPrefix(interest.getName())
            if entry != None:
                entry.getOnInterest()(
                  entry.getPrefix(), interest, self._transport,
                  entry.getRegisteredPrefixId())
        elif data != None:
            pendingInterests = self._extractEntriesForExpressedInterest(
              data.getName())
            for pendingInterest in pendingInterests:
                pendingInterest.getOnData()(pendingInterest.getInterest(), data)
Exemple #10
0
 def wireDecode(self, buf, wireFormat = None):
     """
     Make sure the fields are populated after decoding
     """
     Data.wireDecode(self, buf, wireFormat)
     self.decode()
Exemple #11
0
 def wireDecode(self, buf, wireFormat = None):
     """
     Make sure the fields are populated after decoding
     """
     Data.wireDecode(self, buf, wireFormat)
     self.decode()
Exemple #12
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                interest.setLpPacket(lpPacket)
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        if lpPacket != None:
            # We have decoded the fragment, so remove the wire encoding to save
            #   memory.
            lpPacket.setFragmentWireEncoding(Blob())

            networkNack = NetworkNack.getFirstHeader(lpPacket)
            if networkNack != None:
                if interest == None:
                    # We got a Nack but not for an Interest, so drop the packet.
                    return

                pendingInterests = []
                self._pendingInterestTable.extractEntriesForNackInterest(
                    interest, pendingInterests)
                for pendingInterest in pendingInterests:
                    try:
                        pendingInterest.getOnNetworkNack()(
                            pendingInterest.getInterest(), networkNack)
                    except:
                        logging.exception("Error in onNetworkNack")

                # We have processed the network Nack packet.
                return

        # Now process as Interest or Data.
        if interest != None:
            # Call all interest filter callbacks which match.
            matchedFilters = []
            self._interestFilterTable.getMatchedFilters(
                interest, matchedFilters)
            for i in range(len(matchedFilters)):
                entry = matchedFilters[i]
                includeFilter = True
                onInterestCall = entry.getOnInterest()
                # If onInterest is not a function nor a method assumes it is a
                # calleable object
                if (not inspect.isfunction(onInterestCall)
                        and not inspect.ismethod(onInterestCall)):
                    onInterestCall = onInterestCall.__call__
                # Use getcallargs to test if onInterest accepts 5 args.
                try:
                    inspect.getcallargs(onInterestCall, None, None, None, None,
                                        None)
                except TypeError:
                    # Assume onInterest is old-style with 4 arguments.
                    includeFilter = False

                if includeFilter:
                    try:
                        entry.getOnInterest()(entry.getFilter().getPrefix(),
                                              interest, entry.getFace(),
                                              entry.getInterestFilterId(),
                                              entry.getFilter())
                    except:
                        logging.exception("Error in onInterest")
                else:
                    # Old-style onInterest without the filter argument. We
                    # still pass a Face instead of Transport since Face also
                    # has a send method.
                    try:
                        entry.getOnInterest()(entry.getFilter().getPrefix(),
                                              interest, entry.getFace(),
                                              entry.getInterestFilterId())
                    except:
                        logging.exception("Error in onInterest")
        elif data != None:
            pendingInterests = []
            self._pendingInterestTable.extractEntriesForExpressedInterest(
                data, pendingInterests)
            for pendingInterest in pendingInterests:
                try:
                    pendingInterest.getOnData()(pendingInterest.getInterest(),
                                                data)
                except:
                    logging.exception("Error in onData")
Exemple #13
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                interest.setLpPacket(lpPacket)
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        if lpPacket != None:
            # We have decoded the fragment, so remove the wire encoding to save
            #   memory.
            lpPacket.setFragmentWireEncoding(Blob())

            networkNack = NetworkNack.getFirstHeader(lpPacket)
            if networkNack != None:
                if interest == None:
                    # We got a Nack but not for an Interest, so drop the packet.
                    return

                pendingInterests = []
                self._pendingInterestTable.extractEntriesForNackInterest(
                  interest, pendingInterests)
                for pendingInterest in pendingInterests:
                    try:
                        pendingInterest.getOnNetworkNack()(
                          pendingInterest.getInterest(), networkNack)
                    except:
                        logging.exception("Error in onNetworkNack")

                # We have processed the network Nack packet.
                return

        # Now process as Interest or Data.
        if interest != None:
            # Call all interest filter callbacks which match.
            matchedFilters = []
            self._interestFilterTable.getMatchedFilters(interest, matchedFilters)
            for i in range(len(matchedFilters)):
                entry = matchedFilters[i]
                includeFilter = True
                onInterestCall = entry.getOnInterest()
                # If onInterest is not a function nor a method assumes it is a
                # calleable object
                if (not inspect.isfunction(onInterestCall) and
                    not inspect.ismethod(onInterestCall)):
                    onInterestCall = onInterestCall.__call__
                # Use getcallargs to test if onInterest accepts 5 args.
                try:
                    inspect.getcallargs(onInterestCall,
                      None, None, None, None, None)
                except TypeError:
                    # Assume onInterest is old-style with 4 arguments.
                    includeFilter = False

                if includeFilter:
                    try:
                        entry.getOnInterest()(
                          entry.getFilter().getPrefix(), interest,
                          entry.getFace(), entry.getInterestFilterId(),
                          entry.getFilter())
                    except:
                        logging.exception("Error in onInterest")
                else:
                    # Old-style onInterest without the filter argument. We
                    # still pass a Face instead of Transport since Face also
                    # has a send method.
                    try:
                        entry.getOnInterest()(
                          entry.getFilter().getPrefix(), interest,
                          entry.getFace(), entry.getInterestFilterId())
                    except:
                        logging.exception("Error in onInterest")
        elif data != None:
            pendingInterests = []
            self._pendingInterestTable.extractEntriesForExpressedInterest(
              data, pendingInterests)
            for pendingInterest in pendingInterests:
                try:
                    pendingInterest.getOnData()(pendingInterest.getInterest(), data)
                except:
                    logging.exception("Error in onData")
Exemple #14
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """
        # The type codes for TLV Interest and Data packets are chosen to not
        #   conflict with the first byte of a binary XML packet, so we canjust
        #   look at the first byte.
        if not (element[0] == Tlv.Interest or element[0] == Tlv.Data):
            # Ignore non-TLV elements.
            # Assume it is Binary XML.
            if not WireFormat.ENABLE_NDNX:
                raise RuntimeError(
                  "BinaryXmlWireFormat (NDNx) is deprecated. To enable while you upgrade your network to use NDN-TLV, set WireFormat.ENABLE_NDNX = True")

            return

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

        # Now process as Interest or Data.
        if interest != None:
            # Call all interest filter callbacks which match.
            for i in range(len(self._interestFilterTable)):
                entry = self._interestFilterTable[i]
                if entry.getFilter().doesMatch(interest.getName()):
                    includeFilter = True
                    # Use getcallargs to test if onInterest accepts 5 args.
                    try:
                        inspect.getcallargs(entry.getOnInterest(),
                          None, None, None, None, None)
                    except TypeError:
                        # Assume onInterest is old-style with 4 arguments.
                        includeFilter = False

                    if includeFilter:
                        entry.getOnInterest()(
                          entry.getFilter().getPrefix(), interest,
                          entry.getFace(), entry.getInterestFilterId(),
                          entry.getFilter())
                    else:
                        # Old-style onInterest without the filter argument. We
                        # still pass a Face instead of Transport since Face also
                        # has a send method.
                        entry.getOnInterest()(
                          entry.getFilter().getPrefix(), interest,
                          entry.getFace(), entry.getInterestFilterId())
        elif data != None:
            pendingInterests = self._extractEntriesForExpressedInterest(
              data.getName())
            for pendingInterest in pendingInterests:
                pendingInterest.getOnData()(pendingInterest.getInterest(), data)
Exemple #15
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                interest.setLpPacket(lpPacket)
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        if lpPacket != None:
            # We have decoded the fragment, so remove the wire encoding to save
            #   memory.
            lpPacket.setFragmentWireEncoding(Blob())

            networkNack = NetworkNack.getFirstHeader(lpPacket)
            if networkNack != None:
                if interest == None:
                    # We got a Nack but not for an Interest, so drop the packet.
                    return

                pendingInterests = []
                self._pendingInterestTable.extractEntriesForNackInterest(
                  interest, pendingInterests)
                for pendingInterest in pendingInterests:
                    try:
                        pendingInterest.getOnNetworkNack()(
                          pendingInterest.getInterest(), networkNack)
                    except:
                        logging.exception("Error in onNetworkNack")

                # We have processed the network Nack packet.
                return

        # Now process as Interest or Data.
        if interest != None:
            self._dispatchInterest(interest)
        elif data != None:
            self._satisfyPendingInterests(data)
Exemple #16
0
class SafeBag(object):
    """
    There are three forms of the SafeBag constructor:
    SafeBag(certificate, privateKeyBag) - Create a SafeBag with the given
    certificate and private key.
    SafeBag(keyName, privateKeyBag, publicKeyEncoding [, password,
    digestAlgorithm, wireFormat]) - Create a SafeBag with given private key
    and a new self-signed certificate for the given public key.
    SafeBag(input) - Create a SafeBag by decoding the input as an NDN-TLV SafeBag.

    :param Data certificate: The certificate data packet (used only for
      SafeBag(certificate, privateKeyBag)). This copies the object.
    :param Blob privateKeyBag: The encoded private key. If encrypted, this is a
      PKCS #8 EncryptedPrivateKeyInfo. If not encrypted, this is an unencrypted
      PKCS #8 PrivateKeyInfo.
    :param password: (optional) The password for decrypting the private key in
      order to sign the self-signed certificate, which should have characters in 
      the range of 1 to 127. If the password is supplied, use it to decrypt the
      PKCS #8 EncryptedPrivateKeyInfo. If the password is omitted or None,
      privateKeyBag is an unencrypted PKCS #8 PrivateKeyInfo.
    :type password: an array which implements the buffer protocol
    :param int digestAlgorithm: (optional) The digest algorithm for signing the
      self-signed certificate. If omitted, use DigestAlgorithm.SHA256 .
    :type digestAlgorithm: int from the DigestAlgorithm enum
    :param WireFormat wireFormat: (optional) A WireFormat object used to encode
      the self-signed certificate in order to sign it. If omitted, use
      WireFormat.getDefaultWireFormat().
    :param input: The array with the bytes to decode.
    :type input: A Blob or an array type with int elements
    """
    def __init__(self, arg1, privateKeyBag = None,
      publicKeyEncoding = None, password = None,
      digestAlgorithm = DigestAlgorithm.SHA256, wireFormat = None):
        if isinstance(arg1, Name):
            keyName = arg1
            if wireFormat == None:
                # Don't use a default argument since getDefaultWireFormat can change.
                wireFormat = WireFormat.getDefaultWireFormat()

            self._certificate = SafeBag._makeSelfSignedCertificate(
              keyName, privateKeyBag, publicKeyEncoding, password,
              digestAlgorithm, wireFormat)
            self._privateKeyBag = privateKeyBag
        elif isinstance(arg1, Data):
            # The certificate is supplied.
            self._certificate = Data(arg1)
            self._privateKeyBag = privateKeyBag
        else:
            # Assume the first argument is the encoded SafeBag.
            self.wireDecode(arg1)

    def getCertificate(self):
        """
        Get the certificate data packet.

        :return: The certificate as a Data packet. If you need to process it as
          a certificate object then you must create a new CertificateV2(data).
        :rtype: Data
        """
        return self._certificate

    def getPrivateKeyBag(self):
        """
        Get the encoded private key.

        :return: The encoded private key. If encrypted, this is a PKCS #8
          EncryptedPrivateKeyInfo. If not encrypted, this is an unencrypted PKCS
          #8 PrivateKeyInfo.
        :rtype: Blob
        """
        return self._privateKeyBag

    def wireDecode(self, input):
        """
        Decode the input as an NDN-TLV SafeBag and update this object.

        :param input: The array with the bytes to decode.
        :type input: A Blob or an array type with int elements
        """
        if isinstance(input, Blob):
          input = input.buf()

        # Decode directly as TLV. We don't support the WireFormat abstraction
        # because this isn't meant to go directly on the wire.
        decoder = TlvDecoder(input)
        endOffset = decoder.readNestedTlvsStart(Tlv.SafeBag_SafeBag)

        # Get the bytes of the certificate and decode.
        certificateBeginOffset = decoder.getOffset()
        certificateEndOffset = decoder.readNestedTlvsStart(Tlv.Data)
        decoder.seek(certificateEndOffset)
        self._certificate = Data()
        self._certificate.wireDecode(
          decoder.getSlice(certificateBeginOffset, certificateEndOffset),
          TlvWireFormat.get())

        self._privateKeyBag = Blob(
          decoder.readBlobTlv(Tlv.SafeBag_EncryptedKeyBag), True)

        decoder.finishNestedTlvs(endOffset)

    def wireEncode(self, wireFormat = None):
        """
        Encode this as an NDN-TLV SafeBag.

        :return: The encoded byte array as a Blob.
        :rtype: Blob
        """
        # Encode directly as TLV. We don't support the WireFormat abstraction
        # because this isn't meant to go directly on the wire.
        encoder = TlvEncoder(256)
        saveLength = len(encoder)

        # Encode backwards.
        encoder.writeBlobTlv(
          Tlv.SafeBag_EncryptedKeyBag, self._privateKeyBag.buf())
        # Add the entire Data packet encoding as is.
        encoder.writeBuffer(
          self._certificate.wireEncode(TlvWireFormat.get()).buf())

        encoder.writeTypeAndLength(
          Tlv.SafeBag_SafeBag, len(encoder) - saveLength)

        return Blob(encoder.getOutput(), False)

    @staticmethod
    def _makeSelfSignedCertificate(
      keyName, privateKeyBag, publicKeyEncoding, password, digestAlgorithm,
      wireFormat):
        certificate = CertificateV2()

        # Set the name.
        now = Common.getNowMilliseconds()
        certificateName = Name(keyName)
        certificateName.append("self").appendVersion(int(now))
        certificate.setName(certificateName)

        # Set the MetaInfo.
        certificate.getMetaInfo().setType(ContentType.KEY)
        # Set a one-hour freshness period.
        certificate.getMetaInfo().setFreshnessPeriod(3600 * 1000.0)

        # Set the content.
        publicKey = PublicKey(publicKeyEncoding)
        certificate.setContent(publicKey.getKeyDer())

        # Create a temporary in-memory Tpm and import the private key.
        tpm = Tpm("", "", TpmBackEndMemory())
        tpm._importPrivateKey(keyName, privateKeyBag.toBytes(), password)

        # Set the signature info.
        if publicKey.getKeyType() == KeyType.RSA:
            certificate.setSignature(Sha256WithRsaSignature())
        elif publicKey.getKeyType() == KeyType.EC:
            certificate.setSignature(Sha256WithEcdsaSignature())
        else:
            raise ValueError("Unsupported key type")
        signatureInfo = certificate.getSignature()
        KeyLocator.getFromSignature(signatureInfo).setType(KeyLocatorType.KEYNAME)
        KeyLocator.getFromSignature(signatureInfo).setKeyName(keyName)

        # Set a 20-year validity period.
        ValidityPeriod.getFromSignature(signatureInfo).setPeriod(
          now, now + 20 * 365 * 24 * 3600 * 1000.0)

        # Encode once to get the signed portion.
        encoding = certificate.wireEncode(wireFormat)
        signatureBytes = tpm.sign(encoding.toSignedBytes(), keyName,
          digestAlgorithm)
        signatureInfo.setSignature(signatureBytes)

        # Encode again to include the signature.
        certificate.wireEncode(wireFormat)

        return certificate
Exemple #17
0
    def onReceivedElement(self, element):
        """
        This is called by the transport's ElementReader to process an
        entire received Data or Interest element.

        :param element: The bytes of the incoming element.
        :type element: An array type with int elements
        """

        lpPacket = None
        if element[0] == Tlv.LpPacket_LpPacket:
            # Decode the LpPacket and replace element with the fragment.
            lpPacket = LpPacket()
            # Set copy False so that the fragment is a slice which will be
            # copied below. The header fields are all integers and don't need to
            # be copied.
            TlvWireFormat.get().decodeLpPacket(lpPacket, element, False)
            element = lpPacket.getFragmentWireEncoding().buf()

        # First, decode as Interest or Data.
        interest = None
        data = None
        decoder = TlvDecoder(element)
        if decoder.peekType(Tlv.Interest, len(element)):
            interest = Interest()
            interest.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                interest.setLpPacket(lpPacket)
        elif decoder.peekType(Tlv.Data, len(element)):
            data = Data()
            data.wireDecode(element, TlvWireFormat.get())

            if lpPacket != None:
                data.setLpPacket(lpPacket)

        if lpPacket != None:
            # We have decoded the fragment, so remove the wire encoding to save
            #   memory.
            lpPacket.setFragmentWireEncoding(Blob())

            networkNack = NetworkNack.getFirstHeader(lpPacket)
            if networkNack != None:
                if interest == None:
                    # We got a Nack but not for an Interest, so drop the packet.
                    return

                pendingInterests = []
                self._pendingInterestTable.extractEntriesForNackInterest(
                    interest, pendingInterests)
                for pendingInterest in pendingInterests:
                    try:
                        pendingInterest.getOnNetworkNack()(
                            pendingInterest.getInterest(), networkNack)
                    except:
                        logging.exception("Error in onNetworkNack")

                # We have processed the network Nack packet.
                return

        # Now process as Interest or Data.
        if interest != None:
            self._dispatchInterest(interest)
        elif data != None:
            self._satisfyPendingInterests(data)
Exemple #18
0
class SafeBag(object):
    """
    There are three forms of the SafeBag constructor:
    SafeBag(certificate, privateKeyBag) - Create a SafeBag with the given
    certificate and private key.
    SafeBag(keyName, privateKeyBag, publicKeyEncoding [, password,
    digestAlgorithm, wireFormat]) - Create a SafeBag with given private key
    and a new self-signed certificate for the given public key.
    SafeBag(input) - Create a SafeBag by decoding the input as an NDN-TLV SafeBag.

    :param Data certificate: The certificate data packet (used only for
      SafeBag(certificate, privateKeyBag)). This copies the object.
    :param Blob privateKeyBag: The encoded private key. If encrypted, this is a
      PKCS #8 EncryptedPrivateKeyInfo. If not encrypted, this is an unencrypted
      PKCS #8 PrivateKeyInfo.
    :param password: (optional) The password for decrypting the private key in
      order to sign the self-signed certificate, which should have characters in 
      the range of 1 to 127. If the password is supplied, use it to decrypt the
      PKCS #8 EncryptedPrivateKeyInfo. If the password is omitted or None,
      privateKeyBag is an unencrypted PKCS #8 PrivateKeyInfo.
    :type password: an array which implements the buffer protocol
    :param int digestAlgorithm: (optional) The digest algorithm for signing the
      self-signed certificate. If omitted, use DigestAlgorithm.SHA256 .
    :type digestAlgorithm: int from the DigestAlgorithm enum
    :param WireFormat wireFormat: (optional) A WireFormat object used to encode
      the self-signed certificate in order to sign it. If omitted, use
      WireFormat.getDefaultWireFormat().
    :param input: The array with the bytes to decode.
    :type input: A Blob or an array type with int elements
    """
    def __init__(self,
                 arg1,
                 privateKeyBag=None,
                 publicKeyEncoding=None,
                 password=None,
                 digestAlgorithm=DigestAlgorithm.SHA256,
                 wireFormat=None):
        if isinstance(arg1, Name):
            keyName = arg1
            if wireFormat == None:
                # Don't use a default argument since getDefaultWireFormat can change.
                wireFormat = WireFormat.getDefaultWireFormat()

            self._certificate = SafeBag._makeSelfSignedCertificate(
                keyName, privateKeyBag, publicKeyEncoding, password,
                digestAlgorithm, wireFormat)
            self._privateKeyBag = privateKeyBag
        elif isinstance(arg1, Data):
            # The certificate is supplied.
            self._certificate = Data(arg1)
            self._privateKeyBag = privateKeyBag
        else:
            # Assume the first argument is the encoded SafeBag.
            self.wireDecode(arg1)

    def getCertificate(self):
        """
        Get the certificate data packet.

        :return: The certificate as a Data packet. If you need to process it as
          a certificate object then you must create a new CertificateV2(data).
        :rtype: Data
        """
        return self._certificate

    def getPrivateKeyBag(self):
        """
        Get the encoded private key.

        :return: The encoded private key. If encrypted, this is a PKCS #8
          EncryptedPrivateKeyInfo. If not encrypted, this is an unencrypted PKCS
          #8 PrivateKeyInfo.
        :rtype: Blob
        """
        return self._privateKeyBag

    def wireDecode(self, input):
        """
        Decode the input as an NDN-TLV SafeBag and update this object.

        :param input: The array with the bytes to decode.
        :type input: A Blob or an array type with int elements
        """
        if isinstance(input, Blob):
            input = input.buf()

        # Decode directly as TLV. We don't support the WireFormat abstraction
        # because this isn't meant to go directly on the wire.
        decoder = TlvDecoder(input)
        endOffset = decoder.readNestedTlvsStart(Tlv.SafeBag_SafeBag)

        # Get the bytes of the certificate and decode.
        certificateBeginOffset = decoder.getOffset()
        certificateEndOffset = decoder.readNestedTlvsStart(Tlv.Data)
        decoder.seek(certificateEndOffset)
        self._certificate = Data()
        self._certificate.wireDecode(
            decoder.getSlice(certificateBeginOffset, certificateEndOffset),
            TlvWireFormat.get())

        self._privateKeyBag = Blob(
            decoder.readBlobTlv(Tlv.SafeBag_EncryptedKeyBag), True)

        decoder.finishNestedTlvs(endOffset)

    def wireEncode(self, wireFormat=None):
        """
        Encode this as an NDN-TLV SafeBag.

        :return: The encoded byte array as a Blob.
        :rtype: Blob
        """
        # Encode directly as TLV. We don't support the WireFormat abstraction
        # because this isn't meant to go directly on the wire.
        encoder = TlvEncoder(256)
        saveLength = len(encoder)

        # Encode backwards.
        encoder.writeBlobTlv(Tlv.SafeBag_EncryptedKeyBag,
                             self._privateKeyBag.buf())
        # Add the entire Data packet encoding as is.
        encoder.writeBuffer(
            self._certificate.wireEncode(TlvWireFormat.get()).buf())

        encoder.writeTypeAndLength(Tlv.SafeBag_SafeBag,
                                   len(encoder) - saveLength)

        return Blob(encoder.getOutput(), False)

    @staticmethod
    def _makeSelfSignedCertificate(keyName, privateKeyBag, publicKeyEncoding,
                                   password, digestAlgorithm, wireFormat):
        certificate = CertificateV2()

        # Set the name.
        now = Common.getNowMilliseconds()
        certificateName = Name(keyName)
        certificateName.append("self").appendVersion(int(now))
        certificate.setName(certificateName)

        # Set the MetaInfo.
        certificate.getMetaInfo().setType(ContentType.KEY)
        # Set a one-hour freshness period.
        certificate.getMetaInfo().setFreshnessPeriod(3600 * 1000.0)

        # Set the content.
        publicKey = PublicKey(publicKeyEncoding)
        certificate.setContent(publicKey.getKeyDer())

        # Create a temporary in-memory Tpm and import the private key.
        tpm = Tpm("", "", TpmBackEndMemory())
        tpm._importPrivateKey(keyName, privateKeyBag.toBytes(), password)

        # Set the signature info.
        if publicKey.getKeyType() == KeyType.RSA:
            certificate.setSignature(Sha256WithRsaSignature())
        elif publicKey.getKeyType() == KeyType.EC:
            certificate.setSignature(Sha256WithEcdsaSignature())
        else:
            raise ValueError("Unsupported key type")
        signatureInfo = certificate.getSignature()
        KeyLocator.getFromSignature(signatureInfo).setType(
            KeyLocatorType.KEYNAME)
        KeyLocator.getFromSignature(signatureInfo).setKeyName(keyName)

        # Set a 20-year validity period.
        ValidityPeriod.getFromSignature(signatureInfo).setPeriod(
            now, now + 20 * 365 * 24 * 3600 * 1000.0)

        # Encode once to get the signed portion.
        encoding = certificate.wireEncode(wireFormat)
        signatureBytes = tpm.sign(encoding.toSignedBytes(), keyName,
                                  digestAlgorithm)
        signatureInfo.setSignature(signatureBytes)

        # Encode again to include the signature.
        certificate.wireEncode(wireFormat)

        return certificate