Beispiel #1
0
 def test_round_trip_dynamodb(self):
     dynamodb_item = self.payload.dynamodb_item()
     payload = EncryptedPayload.from_dynamodb_item(dynamodb_item)
     self.assertEquals(IV, payload.iv)
     self.assertEquals(CIPHERTEXT, payload.ciphertext)
     self.assertEquals(KEY, payload.key)
     self.assertEquals(ORBIT_REGION, payload.key_region)
     self.assertEquals(ENCODING, payload.encoding)
Beispiel #2
0
    def get_password(self, app_region, label, length=64, generate=True):
        """
        Get a password for an application in a region.
        :param app_region:  Application configuration in region.
        :param label: Password label.
        :param length: Password length.
        :param generate: Generate new password if missing.
        :return: Encrypted password.
        """
        app_name = app_region.app.name
        region = app_region.region
        logger.debug('Getting password for %s in %s.', label, app_name)
        table_name = '%s-passwords' % app_region.app.orbit.name
        password_name = '%s:%s' % (app_name, label)

        dynamodb = self._clients.dynamodb(region)
        existing_item = dynamodb.get_item(TableName=table_name,
                                          Key={
                                              'name': {
                                                  'S': password_name
                                              }
                                          }).get('Item')
        if existing_item:
            logger.debug('Found existing password for %s in %s.', label,
                         app_name)
            encrypted = EncryptedPayload.from_dynamodb_item(existing_item)

            def decrypt_func():
                """Decrypt via KMS."""
                return self._kms_crypt.decrypt_payload(encrypted)

            return encrypted, decrypt_func

        if not generate:
            return None, lambda: None

        # Not found, generate:
        logger.debug('Generating password for %s in %s.', label, app_name)
        plaintext = self._generate_password(length)
        encrypted_payload = self._kms_crypt.encrypt(app_region, plaintext)
        password_item = encrypted_payload.dynamodb_item()
        password_item['name'] = {'S': password_name}

        # Persist encrypted password:
        dynamodb.put_item(
            TableName=table_name,
            Item=password_item,
            ConditionExpression='attribute_not_exists(ciphertext)')

        # Plaintext can be returned _once_ without Decrypt() permission
        return encrypted_payload, lambda: plaintext
Beispiel #3
0
    def get_password(self, app_region, label, length=64, generate=True):
        """
        Get a password for an application in a region.
        :param app_region:  Application configuration in region.
        :param label: Password label.
        :param length: Password length.
        :param generate: Generate new password if missing.
        :return: Encrypted password.
        """
        app_name = app_region.app.name
        region = app_region.region
        logger.debug('Getting password for %s in %s.', label, app_name)
        table_name = '%s-passwords' % app_region.app.orbit.name
        password_name = '%s:%s' % (app_name, label)

        dynamodb = self._clients.dynamodb(region)
        existing_item = dynamodb.get_item(
            TableName=table_name,
            Key={'name': {'S': password_name}}
        ).get('Item')
        if existing_item:
            logger.debug('Found existing password for %s in %s.', label,
                         app_name)
            encrypted = EncryptedPayload.from_dynamodb_item(existing_item)

            def decrypt_func():
                """Decrypt via KMS."""
                return self._kms_crypt.decrypt_payload(encrypted)

            return encrypted, decrypt_func

        if not generate:
            return None, lambda: None

        # Not found, generate:
        logger.debug('Generating password for %s in %s.', label, app_name)
        plaintext = self._generate_password(length)
        encrypted_payload = self._kms_crypt.encrypt(app_region, plaintext)
        password_item = encrypted_payload.dynamodb_item()
        password_item['name'] = {'S': password_name}

        # Persist encrypted password:
        dynamodb.put_item(
            TableName=table_name,
            Item=password_item,
            ConditionExpression='attribute_not_exists(ciphertext)')

        # Plaintext can be returned _once_ without Decrypt() permission
        return encrypted_payload, lambda: plaintext