Example #1
0
    def encrypt(self, plainData):
        """
        Encrypt the plainData using the existing Content Key (CK) and return a
        new EncryptedContent.

        :param plainData: The data to encrypt.
        :type plainData: Blob or an array which implements the buffer protocol
        :return: The new EncryptedContent.
        :rtype: EncryptedContent
        """
        # Generate the initial vector.
        initialVector = bytearray(EncryptorV2.AES_IV_SIZE)
        for i in range(len(initialVector)):
            initialVector[i] = _systemRandom.randint(0, 0xff)

        params = EncryptParams(EncryptAlgorithmType.AesCbc)
        params.setInitialVector(Blob(initialVector, False))
        encryptedData = AesAlgorithm.encrypt(Blob(self._ckBits, False),
                                             Blob(plainData, False), params)

        content = EncryptedContent()
        content.setInitialVector(params.getInitialVector())
        content.setPayload(encryptedData)
        content.setKeyLocatorName(self._ckName)

        return content
Example #2
0
    def encrypt(self, plainData):
        """
        Encrypt the plainData using the existing Content Key (CK) and return a
        new EncryptedContent.

        :param plainData: The data to encrypt.
        :type plainData: Blob or an array which implements the buffer protocol
        :return: The new EncryptedContent.
        :rtype: EncryptedContent
        """
        # Generate the initial vector.
        initialVector = bytearray(EncryptorV2.AES_IV_SIZE)
        for i in range(len(initialVector)):
            initialVector[i] = _systemRandom.randint(0, 0xff)

        params = EncryptParams(EncryptAlgorithmType.AesCbc)
        params.setInitialVector(Blob(initialVector, False))
        encryptedData = AesAlgorithm.encrypt(
          Blob(self._ckBits, False), Blob(plainData, False), params)

        content = EncryptedContent()
        content.setInitialVector(params.getInitialVector())
        content.setPayload(encryptedData)
        content.setKeyLocatorName(self._ckName)

        return content
Example #3
0
    def _doDecrypt(content, ckBits, onSuccess, onError):
        """
        :param EncryptedContent content:
        :param Blob ckBits:
        :param onSuccess: On success, this calls onSuccess(plainData) where
          plainData is a Blob.
        :param onError: On error, this calls onError(errorCode, message)
        :type onError: function object
        """
        if not content.hasInitialVector():
            onError(
                EncryptError.ErrorCode.MissingRequiredInitialVector,
                "Expecting Initial Vector in the encrypted content, but it is not present"
            )
            return

        try:
            params = EncryptParams(EncryptAlgorithmType.AesCbc)
            params.setInitialVector(content.getInitialVector())
            plainData = AesAlgorithm.decrypt(ckBits, content.getPayload(),
                                             params)
        except Exception as ex:
            onError(EncryptError.ErrorCode.DecryptionFailure,
                    "Decryption error in doDecrypt: " + repr(ex))
            return

        try:
            onSuccess(plainData)
        except:
            logging.exception("Error in onSuccess")
Example #4
0
    def _doDecrypt(content, ckBits, onSuccess, onError):
        """
        :param EncryptedContent content:
        :param Blob ckBits:
        :param onSuccess: On success, this calls onSuccess(plainData) where
          plainData is a Blob.
        :param onError: On error, this calls onError(errorCode, message)
        :type onError: function object
        """
        if not content.hasInitialVector():
            onError(EncryptError.ErrorCode.MissingRequiredInitialVector,
              "Expecting Initial Vector in the encrypted content, but it is not present")
            return

        try:
            params = EncryptParams(EncryptAlgorithmType.AesCbc)
            params.setInitialVector(content.getInitialVector())
            plainData = AesAlgorithm.decrypt(
              ckBits, content.getPayload(), params)
        except Exception as ex:
            onError(EncryptError.ErrorCode.DecryptionFailure,
              "Decryption error in doDecrypt: " + repr(ex))
            return

        try:
            onSuccess(plainData)
        except:
            logging.exception("Error in onSuccess")
Example #5
0
    def _decrypt(encryptedContent, keyBits, onPlainText, onError):
        """
        Decrypt encryptedContent using keyBits.

        :param encryptedContent: The EncryptedContent to decrypt, or a Blob
          which is first decoded as an EncryptedContent.
        :type encryptedContent: Blob or EncryptedContent
        :param {Blob} keyBits The key value.
        :param onPlainText: When encryptedBlob is decrypted, this calls
          onPlainText(decryptedBlob) with the decrypted Blob.
        :type onPlainText: function object
        :param onError: This calls onError(errorCode, message) for an error,
          where errorCode is from EncryptError.ErrorCode and message is a str.
        :type onError: function object
        """
        if isinstance(encryptedContent, Blob):
            # Decode as EncryptedContent.
            encryptedBlob = encryptedContent
            encryptedContent = EncryptedContent()
            encryptedContent.wireDecode(encryptedBlob)

        payload = encryptedContent.getPayload()

        if encryptedContent.getAlgorithmType() == EncryptAlgorithmType.AesCbc:
            # Prepare the parameters.
            decryptParams = EncryptParams(EncryptAlgorithmType.AesCbc)
            decryptParams.setInitialVector(encryptedContent.getInitialVector())

            # Decrypt the content.
            try:
                content = AesAlgorithm.decrypt(keyBits, payload, decryptParams)
            except Exception as ex:
                try:
                    onError(EncryptError.ErrorCode.InvalidEncryptedFormat,
                            repr(ex))
                except:
                    logging.exception("Error in onError")
                return
            onPlainText(content)
        elif encryptedContent.getAlgorithmType(
        ) == EncryptAlgorithmType.RsaOaep:
            # Prepare the parameters.
            decryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep)

            # Decrypt the content.
            try:
                content = RsaAlgorithm.decrypt(keyBits, payload, decryptParams)
            except Exception as ex:
                Consumer._callOnError(
                    onError, EncryptError.ErrorCode.InvalidEncryptedFormat,
                    repr(ex))
                return
            onPlainText(content)
        else:
            Consumer._callOnError(
                onError, EncryptError.ErrorCode.UnsupportedEncryptionScheme,
                repr(encryptedContent.getAlgorithmType()))
Example #6
0
    def _decrypt(encryptedContent, keyBits, onPlainText, onError):
        """
        Decrypt encryptedContent using keyBits.

        :param encryptedContent: The EncryptedContent to decrypt, or a Blob
          which is first decoded as an EncryptedContent.
        :type encryptedContent: Blob or EncryptedContent
        :param {Blob} keyBits The key value.
        :param onPlainText: When encryptedBlob is decrypted, this calls
          onPlainText(decryptedBlob) with the decrypted Blob.
        :type onPlainText: function object
        :param onError: This calls onError(errorCode, message) for an error,
          where errorCode is from EncryptError.ErrorCode and message is a str.
        :type onError: function object
        """
        if isinstance(encryptedContent, Blob):
            # Decode as EncryptedContent.
            encryptedBlob = encryptedContent
            encryptedContent = EncryptedContent()
            encryptedContent.wireDecode(encryptedBlob)

        payload = encryptedContent.getPayload()

        if encryptedContent.getAlgorithmType() == EncryptAlgorithmType.AesCbc:
            # Prepare the parameters.
            decryptParams = EncryptParams(EncryptAlgorithmType.AesCbc)
            decryptParams.setInitialVector(encryptedContent.getInitialVector())

            # Decrypt the content.
            try:
                content = AesAlgorithm.decrypt(keyBits, payload, decryptParams)
            except Exception as ex:
                try:
                    onError(EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex))
                except:
                    logging.exception("Error in onError")
                return
            onPlainText(content)
        elif encryptedContent.getAlgorithmType() == EncryptAlgorithmType.RsaOaep:
            # Prepare the parameters.
            decryptParams = EncryptParams(EncryptAlgorithmType.RsaOaep)

            # Decrypt the content.
            try:
                content = RsaAlgorithm.decrypt(keyBits, payload, decryptParams)
            except Exception as ex:
                Consumer._callOnError(onError,
                  EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex))
                return
            onPlainText(content)
        else:
            Consumer._callOnError(onError,
              EncryptError.ErrorCode.UnsupportedEncryptionScheme,
              repr(encryptedContent.getAlgorithmType()))
Example #7
0
    def createContentKey(self,
                         timeSlot,
                         onEncryptedKeys,
                         onError=defaultOnError):
        """
        Create the content key corresponding to the timeSlot. This first checks
        if the content key exists. For an existing content key, this returns the
        content key name directly. If the key does not exist, this creates one
        and encrypts it using the corresponding E-KEYs. The encrypted content
        keys are passed to the onEncryptedKeys callback.

        :param float timeSlot: The time slot as milliseconds since Jan 1,
          1970 UTC.
        :param onEncryptedKeys: If this creates a content key, then this calls
          onEncryptedKeys(keys) where keys is a list of encrypted content key
          Data packets. If onEncryptedKeys is None, this does not use it.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onEncryptedKeys: function object
        :param onError: (optional) This calls  errorCode, message) for an
          error, where errorCode is from EncryptError.ErrorCode and message is a
          str. If omitted, use a default callback which does nothing.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onError: function object
        :return: The content key name.
        :rtype: Name
        """
        hourSlot = Producer._getRoundedTimeSlot(timeSlot)

        # Create the content key name.
        contentKeyName = Name(self._namespace)
        contentKeyName.append(Encryptor.NAME_COMPONENT_C_KEY)
        contentKeyName.append(Schedule.toIsoString(hourSlot))

        # Check if we have created the content key before.
        if self._database.hasContentKey(timeSlot):
            # We have created the content key. Return its name directly.
            return contentKeyName

        # We haven't created the content key. Create one and add it into the
        # database.
        aesParams = AesKeyParams(128)
        contentKeyBits = AesAlgorithm.generateKey(aesParams).getKeyBits()
        self._database.addContentKey(timeSlot, contentKeyBits)

        # Now we need to retrieve the E-KEYs for content key encryption.
        timeCount = round(timeSlot)
        self._keyRequests[timeCount] = Producer._KeyRequest(len(
            self._eKeyInfo))
        keyRequest = self._keyRequests[timeCount]

        # Send interests for all nodes in the tree.
        for keyName in self._eKeyInfo:
            # For each current E-KEY.
            keyInfo = self._eKeyInfo[keyName]
            if (timeSlot < keyInfo.beginTimeSlot
                    or timeSlot >= keyInfo.endTimeSlot):
                # The current E-KEY cannot cover the content key, so retrieve one.
                keyRequest.repeatAttempts[keyName] = 0
                self._sendKeyInterest(Interest(keyName), timeSlot,
                                      onEncryptedKeys, onError)
            else:
                # The current E-KEY can cover the content key.
                # Encrypt the content key directly.
                eKeyName = Name(keyName)
                eKeyName.append(Schedule.toIsoString(keyInfo.beginTimeSlot))
                eKeyName.append(Schedule.toIsoString(keyInfo.endTimeSlot))
                self._encryptContentKey(keyInfo.keyBits, eKeyName, timeSlot,
                                        onEncryptedKeys, onError)

        return contentKeyName
Example #8
0
    def createContentKey(self, timeSlot, onEncryptedKeys, onError=defaultOnError):
        """
        Create the content key corresponding to the timeSlot. This first checks
        if the content key exists. For an existing content key, this returns the
        content key name directly. If the key does not exist, this creates one
        and encrypts it using the corresponding E-KEYs. The encrypted content
        keys are passed to the onEncryptedKeys callback.

        :param float timeSlot: The time slot as milliseconds since Jan 1,
          1970 UTC.
        :param onEncryptedKeys: If this creates a content key, then this calls
          onEncryptedKeys(keys) where keys is a list of encrypted content key
          Data packets. If onEncryptedKeys is None, this does not use it.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onEncryptedKeys: function object
        :param onError: (optional) This calls  errorCode, message) for an
          error, where errorCode is from EncryptError.ErrorCode and message is a
          str. If omitted, use a default callback which does nothing.
          NOTE: The library will log any exceptions raised by this callback, but
          for better error handling the callback should catch and properly
          handle any exceptions.
        :type onError: function object
        :return: The content key name.
        :rtype: Name
        """
        hourSlot = Producer._getRoundedTimeSlot(timeSlot)

        # Create the content key name.
        contentKeyName = Name(self._namespace)
        contentKeyName.append(Encryptor.NAME_COMPONENT_C_KEY)
        contentKeyName.append(Schedule.toIsoString(hourSlot))

        # Check if we have created the content key before.
        if self._database.hasContentKey(timeSlot):
            # We have created the content key. Return its name directly.
            return contentKeyName

        # We haven't created the content key. Create one and add it into the
        # database.
        aesParams = AesKeyParams(128)
        contentKeyBits = AesAlgorithm.generateKey(aesParams).getKeyBits()
        self._database.addContentKey(timeSlot, contentKeyBits)

        # Now we need to retrieve the E-KEYs for content key encryption.
        timeCount = round(timeSlot)
        self._keyRequests[timeCount] = Producer._KeyRequest(len(self._eKeyInfo))
        keyRequest = self._keyRequests[timeCount]

        # Check if the current E-KEYs can cover the content key.
        timeRange = Exclude()
        Producer.excludeAfter(timeRange, Name.Component(Schedule.toIsoString(timeSlot)))
        # Send interests for all nodes in the tree.
        for keyName in self._eKeyInfo:
            # For each current E-KEY.
            keyInfo = self._eKeyInfo[keyName]
            if timeSlot < keyInfo.beginTimeSlot or timeSlot >= keyInfo.endTimeSlot:
                # The current E-KEY cannot cover the content key, so retrieve one.
                keyRequest.repeatAttempts[keyName] = 0
                self._sendKeyInterest(
                    Interest(keyName).setExclude(timeRange).setChildSelector(1), timeSlot, onEncryptedKeys, onError
                )
            else:
                # The current E-KEY can cover the content key.
                # Encrypt the content key directly.
                eKeyName = Name(keyName)
                eKeyName.append(Schedule.toIsoString(keyInfo.beginTimeSlot))
                eKeyName.append(Schedule.toIsoString(keyInfo.endTimeSlot))
                self._encryptContentKey(keyInfo.keyBits, eKeyName, timeSlot, onEncryptedKeys, onError)

        return contentKeyName