示例#1
0
文件: consumer.py 项目: MAHIS/PyNDN2
    def _decryptDKey(self, dKeyData, onPlainText, onError):
        """
        Decrypt dKeyData.

        :param Data dKeyData: The D-KEY data packet.
        :param onPlainText: When the data packet 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
        """
        # Get encrypted content.
        dataContent = dKeyData.getContent()

        # Process the nonce.
        # dataContent is a sequence of the two EncryptedContent.
        encryptedNonce = EncryptedContent()
        try:
          encryptedNonce.wireDecode(dataContent)
        except Exception as ex:
            try:
                onError(EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex))
            except:
                logging.exception("Error in onError")
            return
        consumerKeyName = encryptedNonce.getKeyLocator().getKeyName()

        # Get consumer decryption key.
        try:
          consumerKeyBlob = self._getDecryptionKey(consumerKeyName)
        except Exception as ex:
            Consumer._callOnError(onError,
              EncryptError.ErrorCode.NoDecryptKey, "Database error: " + repr(ex))
            return
        if consumerKeyBlob.size() == 0:
            try:
                onError(EncryptError.ErrorCode.NoDecryptKey,
                  "The desired consumer decryption key in not in the database")
            except:
                logging.exception("Error in onError")
            return

        # Process the D-KEY.
        # Use the size of encryptedNonce to find the start of encryptedPayload.
        encryptedPayloadBlob = Blob(
          dataContent.buf()[encryptedNonce.wireEncode().size():], False)
        if encryptedPayloadBlob.size() == 0:
            try:
                onError(EncryptError.ErrorCode.InvalidEncryptedFormat,
                  "The data packet does not satisfy the D-KEY packet format")
            except:
                logging.exception("Error in onError")

        # Decrypt the D-KEY.
        Consumer._decrypt(
          encryptedNonce, consumerKeyBlob,
          lambda nonceKeyBits: Consumer._decrypt(
            encryptedPayloadBlob, nonceKeyBits, onPlainText, onError),
          onError)
示例#2
0
    def _encryptSymmetric(payload, key, keyName, params):
        """
        Encrypt the payload using the symmetric key according to params, and
        return an EncryptedContent.

        :param Blob payload: The data to encrypt.
        :param Blob key: The key value.
        :param Name keyName: The key name for the EncryptedContent key locator.
        :param EncryptParams params: The parameters for encryption.
        :return: A new EncryptedContent.
        :rtype: EncryptedContent
        """
        algorithmType = params.getAlgorithmType()
        initialVector = params.getInitialVector()
        keyLocator = KeyLocator()
        keyLocator.setType(KeyLocatorType.KEYNAME)
        keyLocator.setKeyName(keyName)

        if (algorithmType == EncryptAlgorithmType.AesCbc
                or algorithmType == EncryptAlgorithmType.AesEcb):
            if (algorithmType == EncryptAlgorithmType.AesCbc):
                if initialVector.size() != AesAlgorithm.BLOCK_SIZE:
                    raise RuntimeError("incorrect initial vector size")

            encryptedPayload = AesAlgorithm.encrypt(key, payload, params)

            result = EncryptedContent()
            result.setAlgorithmType(algorithmType)
            result.setKeyLocator(keyLocator)
            result.setPayload(encryptedPayload)
            result.setInitialVector(initialVector)
            return result
        else:
            raise RuntimeError("Unsupported encryption method")
示例#3
0
    def _decryptAndImportKdk(self, kdkData, onError):
        """
        :param Data kdkData:
        :param onError: On error, this calls onError(errorCode, message)
        :type onError: function object
        :return: True for success, false for error (where this has called onError).
        :rtype: bool
        """
        try:
            logging.getLogger(__name__).info("Decrypting and importing KDK " +
              kdkData.getName().toUri())
            encryptedContent = EncryptedContent()
            encryptedContent.wireDecodeV2(kdkData.getContent())

            safeBag = SafeBag(encryptedContent.getPayload())
            secret = self._keyChain.getTpm().decrypt(
              encryptedContent.getPayloadKey().toBytes(),
              self._credentialsKey.getName())
            if secret.isNull():
                onError(EncryptError.ErrorCode.TpmKeyNotFound,
                  "Could not decrypt secret, " + self._credentialsKey.getName().toUri() +
                  " not found in TPM")
                return False

            self._internalKeyChain.importSafeBag(safeBag, secret.toBytes())
            return True
        except Exception as ex:
            onError(EncryptError.ErrorCode.DecryptionFailure,
              "Failed to decrypt KDK [" + kdkData.getName().toUri() + "]: " +
              repr(ex))
            return False
示例#4
0
    def _encryptSymmetric(payload, key, keyName, params):
        """
        Encrypt the payload using the symmetric key according to params, and
        return an EncryptedContent.

        :param Blob payload: The data to encrypt.
        :param Blob key: The key value.
        :param Name keyName: The key name for the EncryptedContent key locator.
        :param EncryptParams params: The parameters for encryption.
        :return: A new EncryptedContent.
        :rtype: EncryptedContent
        """
        algorithmType = params.getAlgorithmType()
        initialVector = params.getInitialVector()
        keyLocator = KeyLocator()
        keyLocator.setType(KeyLocatorType.KEYNAME)
        keyLocator.setKeyName(keyName)

        if (algorithmType == EncryptAlgorithmType.AesCbc or
            algorithmType == EncryptAlgorithmType.AesEcb):
            if (algorithmType == EncryptAlgorithmType.AesCbc):
                if initialVector.size() != AesAlgorithm.BLOCK_SIZE:
                    raise RuntimeError("incorrect initial vector size")

            encryptedPayload = AesAlgorithm.encrypt(key, payload, params)

            result = EncryptedContent()
            result.setAlgorithmType(algorithmType)
            result.setKeyLocator(keyLocator)
            result.setPayload(encryptedPayload)
            result.setInitialVector(initialVector)
            return result
        else:
            raise RuntimeError("Unsupported encryption method")
示例#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()))
示例#6
0
    def _decryptCKey(self, cKeyData, onPlainText, onError):
        """
        Decrypt cKeyData.

        :param Data cKeyData: The C-KEY data packet.
        :param onPlainText: When the data packet 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
        """
        # Get the encrypted content.
        cKeyContent = cKeyData.getContent()
        cKeyEncryptedContent = EncryptedContent()
        try:
            cKeyEncryptedContent.wireDecode(cKeyContent)
        except Exception as ex:
            try:
                onError(EncryptError.ErrorCode.InvalidEncryptedFormat,
                        repr(ex))
            except:
                logging.exception("Error in onError")
            return
        eKeyName = cKeyEncryptedContent.getKeyLocator().getKeyName()
        dKeyName = eKeyName.getPrefix(-3)
        dKeyName.append(Encryptor.NAME_COMPONENT_D_KEY).append(
            eKeyName.getSubName(-2))

        # Check if the decryption key is already in the store.
        if dKeyName in self._dKeyMap:
            dKey = self._dKeyMap[dKeyName]
            Consumer._decrypt(cKeyEncryptedContent, dKey, onPlainText, onError)
        else:
            # Get the D-Key Data.
            interestName = Name(dKeyName)
            interestName.append(Encryptor.NAME_COMPONENT_FOR).append(
                self._consumerName)
            interest = Interest(interestName)

            def onVerified(validDKeyData):
                def localOnPlainText(dKeyBits):
                    # dKeyName is already a local copy.
                    self._dKeyMap[dKeyName] = dKeyBits
                    Consumer._decrypt(cKeyEncryptedContent, dKeyBits,
                                      onPlainText, onError)

                self._decryptDKey(validDKeyData, localOnPlainText, onError)

            self._sendInterest(interest, 1, self._dKeyLink, onVerified,
                               onError)
示例#7
0
    def _encryptAsymmetric(payload, key, keyName, params):
        """
        Encrypt the payload using the asymmetric key according to params, and
        return an EncryptedContent.

        :param Blob payload: The data to encrypt. The size should be within
          range of the key.
        :param Blob key: The key value.
        :param Name keyName: The key name for the EncryptedContent key locator.
        :param EncryptParams params: The parameters for encryption.
        :return: A new EncryptedContent.
        :rtype: EncryptedContent
        """
        algorithmType = params.getAlgorithmType()
        keyLocator = KeyLocator()
        keyLocator.setType(KeyLocatorType.KEYNAME)
        keyLocator.setKeyName(keyName)

        if (algorithmType == EncryptAlgorithmType.RsaPkcs
                or algorithmType == EncryptAlgorithmType.RsaOaep):
            encryptedPayload = RsaAlgorithm.encrypt(key, payload, params)

            result = EncryptedContent()
            result.setAlgorithmType(algorithmType)
            result.setKeyLocator(keyLocator)
            result.setPayload(encryptedPayload)
            return result
        else:
            raise RuntimeError("Unsupported encryption method")
示例#8
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
示例#9
0
    def _decryptCKey(self, cKeyData, onPlainText, onError):
        """
        Decrypt cKeyData.

        :param Data cKeyData: The C-KEY data packet.
        :param onPlainText: When the data packet 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
        """
        # Get the encrypted content.
        cKeyContent = cKeyData.getContent()
        cKeyEncryptedContent = EncryptedContent()
        try:
            cKeyEncryptedContent.wireDecode(cKeyContent)
        except Exception as ex:
            try:
                onError(EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex))
            except:
                logging.exception("Error in onError")
            return
        eKeyName = cKeyEncryptedContent.getKeyLocator().getKeyName()
        dKeyName = eKeyName.getPrefix(-3)
        dKeyName.append(Encryptor.NAME_COMPONENT_D_KEY).append(
          eKeyName.getSubName(-2))

        # Check if the decryption key is already in the store.
        if dKeyName in self._dKeyMap:
            dKey = self._dKeyMap[dKeyName]
            Consumer._decrypt(cKeyEncryptedContent, dKey, onPlainText, onError)
        else:
            # Get the D-Key Data.
            interestName = Name(dKeyName)
            interestName.append(Encryptor.NAME_COMPONENT_FOR).append(
              self._consumerName)
            interest = Interest(interestName)

            def onVerified(validDKeyData):
                def localOnPlainText(dKeyBits):
                    # dKeyName is already a local copy.
                    self._dKeyMap[dKeyName] = dKeyBits
                    Consumer._decrypt(
                      cKeyEncryptedContent, dKeyBits, onPlainText, onError)
                self._decryptDKey(validDKeyData, localOnPlainText, onError)
            self._sendInterest(interest, 1, self._dKeyLink, onVerified, onError)
示例#10
0
    def _decryptContent(self, data, onPlainText, onError):
        """
        Decrypt the data packet.

        :param Data data: The data packet. This does not verify the packet.
        :param onPlainText: When the data packet 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
        """
        # Get the encrypted content.
        dataEncryptedContent = EncryptedContent()
        try:
            dataEncryptedContent.wireDecode(data.getContent())
        except Exception as ex:
            Consumer._callOnError(
                onError, EncryptError.ErrorCode.InvalidEncryptedFormat,
                repr(ex))
            return
        cKeyName = dataEncryptedContent.getKeyLocator().getKeyName()

        # Check if the content key is already in the store.
        if cKeyName in self._cKeyMap:
            cKey = self._cKeyMap[cKeyName]
            self._decrypt(dataEncryptedContent, cKey, onPlainText, onError)
        else:
            # Retrieve the C-KEY Data from the network.
            interestName = Name(cKeyName)
            interestName.append(Encryptor.NAME_COMPONENT_FOR).append(
                self._groupName)
            interest = Interest(interestName)

            def onVerified(validCKeyData):
                def localOnPlainText(cKeyBits):
                    # cKeyName is already a copy inside the local
                    #   dataEncryptedContent.
                    self._cKeyMap[cKeyName] = cKeyBits
                    Consumer._decrypt(dataEncryptedContent, cKeyBits,
                                      onPlainText, onError)

                self._decryptCKey(validCKeyData, localOnPlainText, onError)

            self._sendInterest(interest, 1, self._cKeyLink, onVerified,
                               onError)
示例#11
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
示例#12
0
    def _encryptAsymmetric(payload, key, keyName, params):
        """
        Encrypt the payload using the asymmetric key according to params, and
        return an EncryptedContent.

        :param Blob payload: The data to encrypt. The size should be within
          range of the key.
        :param Blob key: The key value.
        :param Name keyName: The key name for the EncryptedContent key locator.
        :param EncryptParams params: The parameters for encryption.
        :return: A new EncryptedContent.
        :rtype: EncryptedContent
        """
        algorithmType = params.getAlgorithmType()
        keyLocator = KeyLocator()
        keyLocator.setType(KeyLocatorType.KEYNAME)
        keyLocator.setKeyName(keyName)

        if (algorithmType == EncryptAlgorithmType.RsaPkcs or
            algorithmType == EncryptAlgorithmType.RsaOaep):
            encryptedPayload = RsaAlgorithm.encrypt(key, payload, params)

            result = EncryptedContent()
            result.setAlgorithmType(algorithmType)
            result.setKeyLocator(keyLocator)
            result.setPayload(encryptedPayload)
            return result
        else:
            raise RuntimeError("Unsupported encryption method")
示例#13
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()))
示例#14
0
    def _decryptContent(self, data, onPlainText, onError):
        """
        Decrypt the data packet.

        :param Data data: The data packet. This does not verify the packet.
        :param onPlainText: When the data packet 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
        """
        # Get the encrypted content.
        dataEncryptedContent = EncryptedContent()
        try:
            dataEncryptedContent.wireDecode(data.getContent())
        except Exception as ex:
            Consumer._callOnError(onError,
              EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex))
            return
        cKeyName = dataEncryptedContent.getKeyLocator().getKeyName()

        # Check if the content key is already in the store.
        if cKeyName in self._cKeyMap:
            cKey = self._cKeyMap[cKeyName]
            self._decrypt(dataEncryptedContent, cKey, onPlainText, onError)
        else:
            # Retrieve the C-KEY Data from the network.
            interestName = Name(cKeyName)
            interestName.append(Encryptor.NAME_COMPONENT_FOR).append(self._groupName)
            interest = Interest(interestName)

            def onVerified(validCKeyData):
                def localOnPlainText(cKeyBits):
                   # cKeyName is already a copy inside the local
                   #   dataEncryptedContent.
                   self._cKeyMap[cKeyName] = cKeyBits
                   Consumer._decrypt(
                     dataEncryptedContent, cKeyBits, onPlainText, onError)
                self._decryptCKey(validCKeyData, localOnPlainText, onError)
            self._sendInterest(interest, 1, self._cKeyLink, onVerified, onError)
示例#15
0
    def _makeAndPublishCkData(self, onError):
        """
        Make a CK Data packet for _ckName encrypted by the KEK in _kekData and
        insert it in the _storage.

        :param onError: On failure, this calls onError(errorCode, message) where
          errorCode is from EncryptError.ErrorCode, and message is an error
          string.
        :type onError: function object
        :return: True on success, else False.
        :rtype: bool
        """
        try:
            kek = PublicKey(self._kekData.getContent())

            content = EncryptedContent()
            content.setPayload(
                kek.encrypt(Blob(self._ckBits, False),
                            EncryptAlgorithmType.RsaOaep))

            ckData = Data(
                Name(self._ckName).append(
                    EncryptorV2.NAME_COMPONENT_ENCRYPTED_BY).append(
                        self._kekData.getName()))
            ckData.setContent(content.wireEncodeV2())
            # FreshnessPeriod can serve as a soft access control for revoking access.
            ckData.getMetaInfo().setFreshnessPeriod(
                EncryptorV2.DEFAULT_CK_FRESHNESS_PERIOD_MS)
            self._keyChain.sign(ckData, self._ckDataSigningInfo)
            self._storage.insert(ckData)

            logging.getLogger(__name__).info("Publishing CK data: " +
                                             ckData.getName().toUri())
            return True
        except Exception as ex:
            onError(
                EncryptError.ErrorCode.EncryptionFailure,
                "Failed to encrypt generated CK with KEK " +
                self._kekData.getName().toUri())
            return False
示例#16
0
    def _decryptAndImportKdk(self, kdkData, onError):
        """
        :param Data kdkData:
        :param onError: On error, this calls onError(errorCode, message)
        :type onError: function object
        :return: True for success, false for error (where this has called onError).
        :rtype: bool
        """
        try:
            logging.getLogger(__name__).info("Decrypting and importing KDK " +
                                             kdkData.getName().toUri())
            encryptedContent = EncryptedContent()
            encryptedContent.wireDecodeV2(kdkData.getContent())

            safeBag = SafeBag(encryptedContent.getPayload())
            secret = self._keyChain.getTpm().decrypt(
                encryptedContent.getPayloadKey().toBytes(),
                self._credentialsKey.getName())
            if secret.isNull():
                onError(
                    EncryptError.ErrorCode.TpmKeyNotFound,
                    "Could not decrypt secret, " +
                    credentialsKey_.getName().toUri() + " not found in TPM")
                return False

            self._internalKeyChain.importSafeBag(safeBag, secret.toBytes())
            return True
        except Exception as ex:
            onError(
                EncryptError.ErrorCode.DecryptionFailure,
                "Failed to decrypt KDK [" + kdkData.getName().toUri() + "]: " +
                repr(ex))
            return False
示例#17
0
    def _decryptCkAndProcessPendingDecrypts(self, contentKey, ckData,
                                            kdkKeyName, onError):
        logging.getLogger(__name__).info("Decrypting CK data ",
                                         ckData.getName().toUri())

        content = EncryptedContent()
        try:
            content.wireDecodeV2(ckData.getContent())
        except Exception as ex:
            onError(EncryptError.ErrorCode.InvalidEncryptedFormat,
                    "Error decrypting EncryptedContent: " + repr(ex))
            return

        try:
            ckBits = self._internalKeyChain.getTpm().decrypt(
                content.getPayload().toBytes(), kdkKeyName)
        except Exception as ex:
            # We don't expect this from the in-memory KeyChain.
            onError(EncryptError.ErrorCode.DecryptionFailure,
                    "Error decrypting the CK EncryptedContent " + repr(ex))
            return

        if ckBits.isNull():
            onError(
                EncryptError.ErrorCode.TpmKeyNotFound,
                "Could not decrypt secret, " + kdkKeyName.toUri() +
                " not found in TPM")
            return

        contentKey.bits = ckBits
        contentKey.isRetrieved = True

        for pendingDecrypt in contentKey.pendingDecrypts:
            # TODO: If this calls onError, should we quit?
            DecryptorV2._doDecrypt(pendingDecrypt.encryptedContent,
                                   contentKey.bits, pendingDecrypt.onSuccess,
                                   pendingDecrypt.onError)

        contentKey.pendingDecrypts = []
示例#18
0
    def _decryptCkAndProcessPendingDecrypts(
      self, contentKey, ckData, kdkKeyName, onError):
        logging.getLogger(__name__).info("Decrypting CK data " +
          ckData.getName().toUri())

        content = EncryptedContent()
        try:
          content.wireDecodeV2(ckData.getContent())
        except Exception as ex:
            onError(EncryptError.ErrorCode.InvalidEncryptedFormat,
              "Error decrypting EncryptedContent: " + repr(ex))
            return

        try:
            ckBits = self._internalKeyChain.getTpm().decrypt(
              content.getPayload().toBytes(), kdkKeyName)
        except Exception as ex:
            # We don't expect this from the in-memory KeyChain.
            onError(EncryptError.ErrorCode.DecryptionFailure,
              "Error decrypting the CK EncryptedContent " + repr(ex))
            return

        if ckBits.isNull():
            onError(EncryptError.ErrorCode.TpmKeyNotFound,
              "Could not decrypt secret, " + kdkKeyName.toUri() +
              " not found in TPM")
            return

        contentKey.bits = ckBits
        contentKey.isRetrieved = True

        for pendingDecrypt in contentKey.pendingDecrypts:
            # TODO: If this calls onError, should we quit?
            DecryptorV2._doDecrypt(
              pendingDecrypt.encryptedContent, contentKey.bits,
              pendingDecrypt.onSuccess, pendingDecrypt.onError)

        contentKey.pendingDecrypts = []
示例#19
0
    def addMember(self, memberCertificate):
        """
        Authorize a member identified by memberCertificate to decrypt data under
        the policy.

        :param CertificateV2 memberCertificate: The certificate that identifies
          the member to authorize.
        :return: The published KDK Data packet.
        :rtype: Data
        """
        kdkName = Name(self._nacKey.getIdentityName())
        kdkName.append(EncryptorV2.NAME_COMPONENT_KDK).append(
            # key-id
            self._nacKey.getName().get(-1)).append(
                EncryptorV2.NAME_COMPONENT_ENCRYPTED_BY).append(
                    memberCertificate.getKeyName())

        secretLength = 32
        secret = bytearray(secretLength)
        for i in range(secretLength):
            secret[i] = _systemRandom.randint(0, 0xff)
        # To be compatible with OpenSSL which uses a null-terminated string,
        # replace each 0 with 1. And to be compatible with the Java security
        # library which interprets the secret as a char array converted to UTF8,
        # limit each byte to the ASCII range 1 to 127.
        for i in range(secretLength):
            if secret[i] == 0:
                secret[i] = 1

            secret[i] &= 0x7f

        kdkSafeBag = self._keyChain.exportSafeBag(
            self._nacKey.getDefaultCertificate(),
            Blob(secret, False).toBytes())

        memberKey = PublicKey(memberCertificate.getPublicKey())

        encryptedContent = EncryptedContent()
        encryptedContent.setPayload(kdkSafeBag.wireEncode())
        encryptedContent.setPayloadKey(
            memberKey.encrypt(
                Blob(secret, False).toBytes(), EncryptAlgorithmType.RsaOaep))

        kdkData = Data(kdkName)
        kdkData.setContent(encryptedContent.wireEncodeV2())
        # FreshnessPeriod can serve as a soft access control for revoking access.
        kdkData.getMetaInfo().setFreshnessPeriod(
            AccessManagerV2.DEFAULT_KDK_FRESHNESS_PERIOD_MS)
        self._keyChain.sign(kdkData, SigningInfo(self._identity))

        self._storage.insert(kdkData)

        return kdkData
示例#20
0
    def _makeAndPublishCkData(self, onError):
        """
        Make a CK Data packet for _ckName encrypted by the KEK in _kekData and
        insert it in the _storage.

        :param onError: On failure, this calls onError(errorCode, message) where
          errorCode is from EncryptError.ErrorCode, and message is an error
          string.
        :type onError: function object
        :return: True on success, else False.
        :rtype: bool
        """
        try:
            kek = PublicKey(self._kekData.getContent())

            content = EncryptedContent()
            content.setPayload(kek.encrypt
              (Blob(self._ckBits, False), EncryptAlgorithmType.RsaOaep))

            ckData = Data(
              Name(self._ckName).append(EncryptorV2.NAME_COMPONENT_ENCRYPTED_BY)
               .append(self._kekData.getName()))
            ckData.setContent(content.wireEncodeV2())
            # FreshnessPeriod can serve as a soft access control for revoking access.
            ckData.getMetaInfo().setFreshnessPeriod(
              EncryptorV2.DEFAULT_CK_FRESHNESS_PERIOD_MS)
            self._keyChain.sign(ckData, self._ckDataSigningInfo)
            self._storage.insert(ckData)

            logging.getLogger(__name__).info("Publishing CK data: " +
              ckData.getName().toUri())
            return True
        except Exception as ex:
            onError(EncryptError.ErrorCode.EncryptionFailure,
              "Failed to encrypt generated CK with KEK " +
              self._kekData.getName().toUri())
            return False
示例#21
0
文件: consumer.py 项目: MAHIS/PyNDN2
    def _decryptCKey(self, cKeyData, onPlainText, onError):
        """
        Decrypt cKeyData.

        :param Data cKeyData: The C-KEY data packet.
        :param onPlainText: When the data packet 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
        """
        # Get the encrypted content.
        cKeyContent = cKeyData.getContent()
        cKeyEncryptedContent = EncryptedContent()
        try:
            cKeyEncryptedContent.wireDecode(cKeyContent)
        except Exception as ex:
            try:
                onError(EncryptError.ErrorCode.InvalidEncryptedFormat, repr(ex))
            except:
                logging.exception("Error in onError")
            return
        eKeyName = cKeyEncryptedContent.getKeyLocator().getKeyName()
        dKeyName = eKeyName.getPrefix(-3)
        dKeyName.append(Encryptor.NAME_COMPONENT_D_KEY).append(
          eKeyName.getSubName(-2))

        # Check if the decryption key is already in the store.
        if dKeyName in self._dKeyMap:
            dKey = self._dKeyMap[dKeyName]
            Consumer._decrypt(cKeyEncryptedContent, dKey, onPlainText, onError)
        else:
            # Get the D-Key Data.
            interestName = Name(dKeyName)
            interestName.append(Encryptor.NAME_COMPONENT_FOR).append(
              self._consumerName)
            interest = Interest(interestName)

            # Prepare the callback functions.
            def onData(dKeyInterest, dKeyData):
                # The Interest has no selectors, so assume the library correctly
                # matched with the Data name before calling onData.

                try:
                    def onVerified(validDKeyData):
                        def localOnPlainText(dKeyBits):
                            # dKeyName is already a local copy.
                            self._dKeyMap[dKeyName] = dKeyBits
                            Consumer._decrypt(
                              cKeyEncryptedContent, dKeyBits, onPlainText, onError)
                        self._decryptDKey(validDKeyData, localOnPlainText, onError)
                    self._keyChain.verifyData(
                        dKeyData, onVerified,
                        lambda d: Consumer._callOnError(onError, EncryptError.ErrorCode.Validation,
                                          "verifyData failed"))
                except Exception as ex:
                    try:
                        onError(EncryptError.ErrorCode.General,
                                "verifyData error: " + repr(ex))
                    except:
                        logging.exception("Error in onError")

            def onTimeout(dKeyInterest):
                # We should re-try at least once.
                try:
                    self._face.expressInterest(
                      interest, onData,
                      lambda contentInterest:
                        Consumer._callOnError(onError,
                          EncryptError.ErrorCode.Timeout, interest.getName().toUri()))
                except Exception as ex:
                    try:
                        onError(EncryptError.ErrorCode.General,
                                "expressInterest error: " + repr(ex))
                    except:
                        logging.exception("Error in onError")

            # Express the Interest.
            try:
                self._face.expressInterest(interest, onData, onTimeout)
            except Exception as ex:
                try:
                    onError(EncryptError.ErrorCode.General,
                            "expressInterest error: " + repr(ex))
                except:
                    logging.exception("Error in onError")
示例#22
0
文件: consumer.py 项目: pedosb/PyNDN2
    def _decryptCKey(self, cKeyData, onPlainText, onError):
        """
        Decrypt cKeyData.

        :param Data cKeyData: The C-KEY data packet.
        :param onPlainText: When the data packet 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
        """
        # Get the encrypted content.
        cKeyContent = cKeyData.getContent()
        cKeyEncryptedContent = EncryptedContent()
        try:
            cKeyEncryptedContent.wireDecode(cKeyContent)
        except Exception as ex:
            try:
                onError(EncryptError.ErrorCode.InvalidEncryptedFormat,
                        repr(ex))
            except:
                logging.exception("Error in onError")
            return
        eKeyName = cKeyEncryptedContent.getKeyLocator().getKeyName()
        dKeyName = eKeyName.getPrefix(-3)
        dKeyName.append(Encryptor.NAME_COMPONENT_D_KEY).append(
            eKeyName.getSubName(-2))

        # Check if the decryption key is already in the store.
        if dKeyName in self._dKeyMap:
            dKey = self._dKeyMap[dKeyName]
            Consumer._decrypt(cKeyEncryptedContent, dKey, onPlainText, onError)
        else:
            # Get the D-Key Data.
            interestName = Name(dKeyName)
            interestName.append(Encryptor.NAME_COMPONENT_FOR).append(
                self._consumerName)
            interest = Interest(interestName)

            # Prepare the callback functions.
            def onData(dKeyInterest, dKeyData):
                # The Interest has no selectors, so assume the library correctly
                # matched with the Data name before calling onData.

                try:

                    def onVerified(validDKeyData):
                        def localOnPlainText(dKeyBits):
                            # dKeyName is already a local copy.
                            self._dKeyMap[dKeyName] = dKeyBits
                            Consumer._decrypt(cKeyEncryptedContent, dKeyBits,
                                              onPlainText, onError)

                        self._decryptDKey(validDKeyData, localOnPlainText,
                                          onError)

                    self._keyChain.verifyData(
                        dKeyData, onVerified, lambda d: Consumer._callOnError(
                            onError, EncryptError.ErrorCode.Validation,
                            "verifyData failed"))
                except Exception as ex:
                    try:
                        onError(EncryptError.ErrorCode.General,
                                "verifyData error: " + repr(ex))
                    except:
                        logging.exception("Error in onError")

            def onTimeout(dKeyInterest):
                # We should re-try at least once.
                try:
                    self._face.expressInterest(
                        interest, onData,
                        lambda contentInterest: Consumer._callOnError(
                            onError, EncryptError.ErrorCode.Timeout,
                            interest.getName().toUri()))
                except Exception as ex:
                    try:
                        onError(EncryptError.ErrorCode.General,
                                "expressInterest error: " + repr(ex))
                    except:
                        logging.exception("Error in onError")

            # Express the Interest.
            try:
                self._face.expressInterest(interest, onData, onTimeout)
            except Exception as ex:
                try:
                    onError(EncryptError.ErrorCode.General,
                            "expressInterest error: " + repr(ex))
                except:
                    logging.exception("Error in onError")
示例#23
0
    def _decryptDKey(self, dKeyData, onPlainText, onError):
        """
        Decrypt dKeyData.

        :param Data dKeyData: The D-KEY data packet.
        :param onPlainText: When the data packet 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
        """
        # Get encrypted content.
        dataContent = dKeyData.getContent()

        # Process the nonce.
        # dataContent is a sequence of the two EncryptedContent.
        encryptedNonce = EncryptedContent()
        try:
            encryptedNonce.wireDecode(dataContent)
        except Exception as ex:
            try:
                onError(EncryptError.ErrorCode.InvalidEncryptedFormat,
                        repr(ex))
            except:
                logging.exception("Error in onError")
            return
        consumerKeyName = encryptedNonce.getKeyLocator().getKeyName()

        # Get consumer decryption key.
        try:
            consumerKeyBlob = self._getDecryptionKey(consumerKeyName)
        except Exception as ex:
            Consumer._callOnError(onError, EncryptError.ErrorCode.NoDecryptKey,
                                  "Database error: " + repr(ex))
            return
        if consumerKeyBlob.size() == 0:
            try:
                onError(
                    EncryptError.ErrorCode.NoDecryptKey,
                    "The desired consumer decryption key in not in the database"
                )
            except:
                logging.exception("Error in onError")
            return

        # Process the D-KEY.
        # Use the size of encryptedNonce to find the start of encryptedPayload.
        encryptedPayloadBlob = Blob(
            dataContent.buf()[encryptedNonce.wireEncode().size():], False)
        if encryptedPayloadBlob.size() == 0:
            try:
                onError(
                    EncryptError.ErrorCode.InvalidEncryptedFormat,
                    "The data packet does not satisfy the D-KEY packet format")
            except:
                logging.exception("Error in onError")
            return

        # Decrypt the D-KEY.
        Consumer._decrypt(
            encryptedNonce,
            consumerKeyBlob, lambda nonceKeyBits: Consumer._decrypt(
                encryptedPayloadBlob, nonceKeyBits, onPlainText, onError),
            onError)