def _item_check(materials_provider, table_name, table_index, ciphertext_item,
                plaintext_item, attribute_actions, prep):
    ciphertext_item = ddb_to_dict(ciphertext_item)
    plaintext_item = ddb_to_dict(plaintext_item)
    prep()  # Test scenario setup that needs to happen inside the test
    cmp = materials_provider(
    )  # Some of the materials providers need to be constructed inside the test
    table = fake_table(ciphertext_item)
    table_info = TableInfo(name=table_name,
                           primary_index=TableIndex(
                               partition=table_index['partition'],
                               sort=table_index.get('sort', None)))
    item_key = {
        table_info.primary_index.partition:
        ciphertext_item[table_info.primary_index.partition]
    }
    if table_info.primary_index.sort is not None:
        item_key[table_info.primary_index.sort] = ciphertext_item[
            table_info.primary_index.sort]

    e_table = EncryptedTable(table=table,
                             materials_provider=cmp,
                             table_info=table_info,
                             attribute_actions=attribute_actions,
                             auto_refresh_table_indexes=False)
    decrypted_item = e_table.get_item(Key=item_key)['Item']
    assert set(decrypted_item.keys()) == set(plaintext_item.keys())
    for key in decrypted_item:
        if key == 'version':
            continue
        assert decrypted_item[key] == plaintext_item[key]
예제 #2
0
 def get_item(self, **kwargs):
     materials_provider = KeyStoreMaterialsProvider(
         key_store=self._key_store, )
     encrypted_table = EncryptedTable(
         table=self._table,
         materials_provider=materials_provider,
         table_info=self._table_info,
         attribute_actions=self._attribute_actions,
     )
     return encrypted_table.get_item(**kwargs)
예제 #3
0
 def put_item(self, CSEKeyId: str, **kwargs):
     materials_provider = KeyStoreMaterialsProvider(
         key_store=self._key_store,
         material_description={"key_id": CSEKeyId},
     )
     encrypted_table = EncryptedTable(
         table=self._table,
         materials_provider=materials_provider,
         table_info=self._table_info,
         attribute_actions=self._attribute_actions,
     )
     encrypted_table.put_item(**kwargs)
예제 #4
0
def get_decrypted_item(index_key, table_name):
    table = boto3.resource('dynamodb').Table(table_name)

    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={'Account_Id': CryptoAction.DO_NOTHING})

    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=aws_kms_cmp,
                                     attribute_actions=actions)

    response = encrypted_table.get_item(Key=index_key)

    return response
예제 #5
0
def fetch_user_info(username, data, awsCmkId, table):
    kmsCmp = AwsKmsCryptographicMaterialsProvider(key_id=awsCmkId)
    actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN
    )
    encrypted_table = EncryptedTable(table=table, materials_provider=kmsCmp, attribute_actions=actions)

    resp = encrypted_table.get_item(
        Key = {'USERNAME': username}
    )

    user = resp['Item']

    info = user[data]

    return info
예제 #6
0
class CryptoItems:
    with open('aws') as v:
        aws_access_key_id = str(v.readline().strip())
        aws_secret_access_key = str(v.readline().strip())

    dbResource = boto3.resource('dynamodb',
                                aws_access_key_id=aws_access_key_id,
                                aws_secret_access_key=aws_secret_access_key,
                                region_name='us-east-1').Table('Users')

    # crypto key and material provider
    aws_cmk_id = 'arn:aws:kms:us-east-1:910140038075:key/353f6f4c-0d0b-47b1-99fc-3aeec929b973'
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

    # how the crypto is applied to attributes
    crypto_actions = AttributeActions(
        default_action=CryptoAction.DO_NOTHING,
        attribute_actions={'password': CryptoAction.ENCRYPT_AND_SIGN})

    crypto_context = EncryptionContext(table_name='Users')

    custom_crypto_config = CryptoConfig(materials_provider=aws_kms_cmp,
                                        attribute_actions=crypto_actions,
                                        encryption_context=crypto_context)

    encrypted_resource = EncryptedTable(table=dbResource,
                                        materials_provider=aws_kms_cmp,
                                        attribute_actions=crypto_actions)
예제 #7
0
def table_cycle_batch_writer_check(materials_provider, initial_actions, initial_item, table_name, region_name=None):
    kwargs = {}
    if region_name is not None:
        kwargs["region_name"] = region_name
    table = boto3.resource("dynamodb", **kwargs).Table(table_name)
    e_table = EncryptedTable(table=table, materials_provider=materials_provider, attribute_actions=initial_actions)

    cycle_batch_writer_check(table, e_table, initial_actions, initial_item)
def encrypt_item(USERNAME, PASSWORD, FIRST_NAME, MIDDLE_INITIAL, LAST_NAME,
                 DOB, SEX, HEIGHT, WEIGHT, ALLERGIES, TOKEN, awsCmkId, table):

    kmsCmp = AwsKmsCryptographicMaterialsProvider(key_id=awsCmkId)
    actions = AttributeActions(default_action=CryptoAction.ENCRYPT_AND_SIGN)

    index_key = {}

    plaintext_item = {
        'USERNAME': USERNAME,
        'PASSWORD': PASSWORD,
        'FIRST_NAME': FIRST_NAME,
        'MIDDLE_INITIAL': MIDDLE_INITIAL,
        'LAST_NAME': LAST_NAME,
        'DOB': DOB,
        'SEX': SEX,
        'HEIGHT': HEIGHT,
        'WEIGHT': WEIGHT,
        'ALLERGIES': ALLERGIES,
        'AUTH_TOKEN': TOKEN
    }

    encrypted_attributes = set(plaintext_item.keys())

    unencrypted_attributes = set(index_key.keys())

    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=kmsCmp,
                                     attribute_actions=actions)
    encrypted_table.put_item(Item=plaintext_item)

    encrypted_item = table.get_item(Key={'USERNAME': USERNAME})["Item"]
    decrypted_item = encrypted_table.get_item(
        Key={'USERNAME': USERNAME})["Item"]

    # Verify that all of the attributes are different in the encrypted item
    for name in encrypted_attributes:
        if name != 'USERNAME':
            assert encrypted_item[name] != plaintext_item[name]
            assert decrypted_item[name] == plaintext_item[name]

    # Verify that all of the attributes that should not be encrypted were not.
    for name in unencrypted_attributes:
        assert decrypted_item[name] == encrypted_item[name] == plaintext_item[
            name]
def get_decrypted_item(index_key, table_name):
    #table_name='CreditCardTokenizerTable'
    table = boto3.resource('dynamodb').Table(table_name)

    aws_cmk_id = 'arn:aws:kms:us-west-2:176385768664:key/bd3a8796-1638-42f3-b318-ac357427f326'
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={'Account_Id': CryptoAction.DO_NOTHING})

    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=aws_kms_cmp,
                                     attribute_actions=actions)

    response = encrypted_table.get_item(Key=index_key)

    return response
예제 #10
0
def encrypt_item(plaintext_item, table_name):
    table = boto3.resource('dynamodb').Table(table_name)

    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={'Account_Id': CryptoAction.DO_NOTHING})

    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=aws_kms_cmp,
                                     attribute_actions=actions)

    print(plaintext_item)
    response = encrypted_table.put_item(Item=plaintext_item)

    print(response)
    return response
예제 #11
0
def encrypt_item(table_name, aws_cmk_id, meta_table_name, material_name):
    """Demonstrate use of EncryptedTable to transparently encrypt an item."""
    index_key = {"partition_attribute": "is this", "sort_attribute": 55}
    plaintext_item = {
        "example": "data",
        "some numbers": 99,
        "and some binary": Binary(b"\x00\x01\x02"),
        "leave me": "alone",  # We want to ignore this attribute
    }
    # Collect all of the attributes that will be encrypted (used later).
    encrypted_attributes = set(plaintext_item.keys())
    encrypted_attributes.remove("leave me")
    # Collect all of the attributes that will not be encrypted (used later).
    unencrypted_attributes = set(index_key.keys())
    unencrypted_attributes.add("leave me")
    # Add the index pairs to the item.
    plaintext_item.update(index_key)

    # Create a normal table resource for the meta store.
    meta_table = boto3.resource("dynamodb").Table(meta_table_name)
    # Create a crypto materials provider for the meta store using the specified AWS KMS key.
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)
    # Create a meta store using the AWS KMS crypto materials provider.
    meta_store = MetaStore(table=meta_table, materials_provider=aws_kms_cmp)
    # Create a most recent provider using the meta store.
    most_recent_cmp = MostRecentProvider(
        provider_store=meta_store,
        material_name=material_name,
        version_ttl=600.0,  # Check for a new material version every five minutes.
    )
    # Create a normal table resource.
    table = boto3.resource("dynamodb").Table(table_name)
    # Create attribute actions that tells the encrypted table to encrypt all attributes except one.
    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN, attribute_actions={"leave me": CryptoAction.DO_NOTHING}
    )
    # Use these objects to create an encrypted table resource.
    encrypted_table = EncryptedTable(table=table, materials_provider=most_recent_cmp, attribute_actions=actions)

    # Put the item to the table, using the encrypted table resource to transparently encrypt it.
    encrypted_table.put_item(Item=plaintext_item)

    # Get the encrypted item using the standard table resource.
    encrypted_item = table.get_item(Key=index_key)["Item"]

    # Get the item using the encrypted table resource, transparently decyrpting it.
    decrypted_item = encrypted_table.get_item(Key=index_key)["Item"]

    # Verify that all of the attributes are different in the encrypted item
    for name in encrypted_attributes:
        assert encrypted_item[name] != plaintext_item[name]
        assert decrypted_item[name] == plaintext_item[name]

    # Verify that all of the attributes that should not be encrypted were not.
    for name in unencrypted_attributes:
        assert decrypted_item[name] == encrypted_item[name] == plaintext_item[name]

    # Clean up the item
    encrypted_table.delete_item(Key=index_key)
예제 #12
0
def _item_check(materials_provider, table_name, table_index, ciphertext_item,
                plaintext_item, attribute_actions, prep):
    ciphertext_item = ddb_to_dict(ciphertext_item)
    plaintext_item = ddb_to_dict(plaintext_item)
    metatable = None
    try:
        metatable = prep(
        )  # Test scenario setup that needs to happen inside the test
        cmp = materials_provider(
        )  # Some of the materials providers need to be constructed inside the test
        table = fake_table(ciphertext_item)
        table_info = TableInfo(
            name=table_name,
            primary_index=TableIndex(partition=table_index["partition"],
                                     sort=table_index.get("sort", None)),
        )
        item_key = {
            table_info.primary_index.partition:
            ciphertext_item[table_info.primary_index.partition]
        }
        if table_info.primary_index.sort is not None:
            item_key[table_info.primary_index.sort] = ciphertext_item[
                table_info.primary_index.sort]

        e_table = EncryptedTable(
            table=table,
            materials_provider=cmp,
            table_info=table_info,
            attribute_actions=attribute_actions,
            auto_refresh_table_indexes=False,
        )
        decrypted_item = e_table.get_item(Key=item_key)["Item"]
        assert set(decrypted_item.keys()) == set(plaintext_item.keys())
        for key in decrypted_item:
            if key == "version":
                continue
            assert decrypted_item[key] == plaintext_item[key]
    finally:
        if metatable:
            metatable.delete()
            metatable.wait_until_not_exists()
def fetch_user(username, awsCmkId, table):
    try:
        kmsCmp = AwsKmsCryptographicMaterialsProvider(key_id=awsCmkId)
        actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN
        )

        encrypted_table = EncryptedTable(table=table, materials_provider=kmsCmp, attribute_actions=actions)

        #gets decrypted info from encrypted table
        response = encrypted_table.get_item(
        Key = {'USERNAME': username}
        )
        
        item = response['Item']
        return item

    except Exception as e:
        print("in get_user.py: Exception. Could not get user from database. " + str(e))
        return -1
        
예제 #14
0
def table_cycle_check(materials_provider,
                      initial_actions,
                      initial_item,
                      table_name,
                      region_name=None):
    check_attribute_actions = initial_actions.copy()
    check_attribute_actions.set_index_keys(*list(TEST_KEY.keys()))
    item = initial_item.copy()
    item.update(TEST_KEY)

    kwargs = {}
    if region_name is not None:
        kwargs["region_name"] = region_name
    table = boto3.resource("dynamodb", **kwargs).Table(table_name)
    e_table = EncryptedTable(table=table,
                             materials_provider=materials_provider,
                             attribute_actions=initial_actions)

    _put_result = e_table.put_item(Item=item)  # noqa

    encrypted_result = table.get_item(Key=TEST_KEY, ConsistentRead=True)
    check_encrypted_item(item, encrypted_result["Item"],
                         check_attribute_actions)

    decrypted_result = e_table.get_item(Key=TEST_KEY, ConsistentRead=True)
    assert decrypted_result["Item"] == item

    e_table.delete_item(Key=TEST_KEY)
    del item
    del check_attribute_actions
예제 #15
0
def table_batch_writer_unprocessed_items_check(
    materials_provider, initial_actions, initial_item, table_name, region_name=None
):
    kwargs = {}
    if region_name is not None:
        kwargs["region_name"] = region_name
    resource = boto3.resource("dynamodb", **kwargs)
    table = resource.Table(table_name)

    items = _generate_items(initial_item, _nop_transformer)
    request_items = {table_name: [{"PutRequest": {"Item": _item}} for _item in items]}

    with patch.object(table.meta.client, "batch_write_item") as batch_write_mock:
        # Check that unprocessed items returned to a BatchWriter are successfully retried
        batch_write_mock.side_effect = [{"UnprocessedItems": request_items}, {"UnprocessedItems": {}}]
        e_table = EncryptedTable(table=table, materials_provider=materials_provider, attribute_actions=initial_actions)

        with e_table.batch_writer() as writer:
            for item in items:
                writer.put_item(item)

    del items
def encrypt_item(table_name, aws_cmk_id):
    """Demonstrate use of EncryptedTable to transparently encrypt an item."""
    index_key = {'partition_attribute': 'is this', 'sort_attribute': 55}
    plaintext_item = {
        'example': 'data',
        'some numbers': 99,
        'and some binary': Binary(b'\x00\x01\x02'),
        'leave me': 'alone'  # We want to ignore this attribute
    }
    # Collect all of the attributes that will be encrypted (used later).
    encrypted_attributes = set(plaintext_item.keys())
    encrypted_attributes.remove('leave me')
    # Collect all of the attributes that will not be encrypted (used later).
    unencrypted_attributes = set(index_key.keys())
    unencrypted_attributes.add('leave me')
    # Add the index pairs to the item.
    plaintext_item.update(index_key)

    # Create a normal table resource.
    table = boto3.resource('dynamodb').Table(table_name)
    # Create a crypto materials provider using the specified AWS KMS key.
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)
    # Create attribute actions that tells the encrypted table to encrypt all attributes except one.
    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={'leave me': CryptoAction.DO_NOTHING})
    # Use these objects to create an encrypted table resource.
    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=aws_kms_cmp,
                                     attribute_actions=actions)

    # Put the item to the table, using the encrypted table resource to transparently encrypt it.
    encrypted_table.put_item(Item=plaintext_item)

    # Get the encrypted item using the standard table resource.
    encrypted_item = table.get_item(Key=index_key)['Item']

    # Get the item using the encrypted table resource, transparently decyrpting it.
    decrypted_item = encrypted_table.get_item(Key=index_key)['Item']

    # Verify that all of the attributes are different in the encrypted item
    for name in encrypted_attributes:
        assert encrypted_item[name] != plaintext_item[name]
        assert decrypted_item[name] == plaintext_item[name]

    # Verify that all of the attributes that should not be encrypted were not.
    for name in unencrypted_attributes:
        assert decrypted_item[name] == encrypted_item[name] == plaintext_item[
            name]

    # Clean up the item
    encrypted_table.delete_item(Key=index_key)
 def __attrs_post_init__(self):
     # type: () -> None
     """Prepare the encrypted table resource from the provided table and materials provider."""
     self._encrypted_table = EncryptedTable(  # attrs confuses pylint: disable=attribute-defined-outside-init
         table=self._table,
         materials_provider=self._materials_provider)
class MetaStore(ProviderStore):
    """Create and retrieve wrapped cryptographic materials providers, storing their cryptographic
    materials using the provided encrypted table.

    :param table: Pre-configured boto3 DynamoDB Table object
    :type table: boto3.resources.base.ServiceResource
    :param CryptographicMaterialsProvider materials_provider: Cryptographic materials provider to use
    """

    _table = attr.ib(validator=attr.validators.instance_of(ServiceResource))
    _materials_provider = attr.ib(
        validator=attr.validators.instance_of(CryptographicMaterialsProvider))

    def __init__(self, table, materials_provider):  # noqa=D107
        # type: (ServiceResource, CryptographicMaterialsProvider) -> None
        # Workaround pending resolution of attrs/mypy interaction.
        # https://github.com/python/mypy/issues/2088
        # https://github.com/python-attrs/attrs/issues/215
        self._table = table
        self._materials_provider = materials_provider
        attr.validate(self)
        self.__attrs_post_init__()

    def __attrs_post_init__(self):
        # type: () -> None
        """Prepare the encrypted table resource from the provided table and materials provider."""
        self._encrypted_table = EncryptedTable(  # attrs confuses pylint: disable=attribute-defined-outside-init
            table=self._table,
            materials_provider=self._materials_provider)

    @classmethod
    def create_table(cls, client, table_name, read_units, write_units):
        # type: (botocore.client.BaseClient, Text, int, int) -> None
        """Create the table for this MetaStore.

        :param table: Pre-configured boto3 DynamoDB client object
        :type table: boto3.resources.base.BaseClient
        :param str table_name: Name of table to create
        :param int read_units: Read capacity units to provision
        :param int write_units: Write capacity units to provision
        """
        try:
            client.create_table(
                TableName=table_name,
                AttributeDefinitions=[
                    {
                        "AttributeName":
                        MetaStoreAttributeNames.PARTITION.value,
                        "AttributeType": "S"
                    },
                    {
                        "AttributeName": MetaStoreAttributeNames.SORT.value,
                        "AttributeType": "N"
                    },
                ],
                KeySchema=[
                    {
                        "AttributeName":
                        MetaStoreAttributeNames.PARTITION.value,
                        "KeyType": "HASH"
                    },
                    {
                        "AttributeName": MetaStoreAttributeNames.SORT.value,
                        "KeyType": "RANGE"
                    },
                ],
                ProvisionedThroughput={
                    "ReadCapacityUnits": read_units,
                    "WriteCapacityUnits": write_units
                },
            )
        except botocore.exceptions.ClientError:
            raise Exception("TODO: Could not create table")

    def _load_materials(self, material_name, version):
        # type: (Text, int) -> Tuple[JceNameLocalDelegatedKey, JceNameLocalDelegatedKey]
        """Load materials from table.

        :returns: Materials loaded into delegated keys
        :rtype: tuple(JceNameLocalDelegatedKey)
        """
        key = {
            MetaStoreAttributeNames.PARTITION.value: material_name,
            MetaStoreAttributeNames.SORT.value: version
        }
        response = self._encrypted_table.get_item(Key=key)
        try:
            item = response["Item"]
        except KeyError:
            raise InvalidVersionError('Version not found: "{}#{}"'.format(
                material_name, version))

        try:
            encryption_key_kwargs = dict(
                key=item[MetaStoreAttributeNames.ENCRYPTION_KEY.value].value,
                algorithm=item[
                    MetaStoreAttributeNames.ENCRYPTION_ALGORITHM.value],
                key_type=EncryptionKeyType.SYMMETRIC,
                key_encoding=KeyEncodingType.RAW,
            )
            signing_key_kwargs = dict(
                key=item[MetaStoreAttributeNames.INTEGRITY_KEY.value].value,
                algorithm=item[
                    MetaStoreAttributeNames.INTEGRITY_ALGORITHM.value],
                key_type=EncryptionKeyType.SYMMETRIC,
                key_encoding=KeyEncodingType.RAW,
            )
        except KeyError:
            raise Exception("TODO: Invalid record")

        # TODO: handle if the material type version is not in the item
        if item[MetaStoreAttributeNames.MATERIAL_TYPE_VERSION.
                value] != MetaStoreValues.MATERIAL_TYPE_VERSION.value:
            raise InvalidVersionError('Unsupported material type: "{}"'.format(
                item[MetaStoreAttributeNames.MATERIAL_TYPE_VERSION.value]))

        encryption_key = JceNameLocalDelegatedKey(**encryption_key_kwargs)
        signing_key = JceNameLocalDelegatedKey(**signing_key_kwargs)
        return encryption_key, signing_key

    def _save_materials(self, material_name, version, encryption_key,
                        signing_key):
        # type: (Text, int, JceNameLocalDelegatedKey, JceNameLocalDelegatedKey) -> None
        """Save materials to the table, raising an error if the version already exists.

        :param str material_name: Material to locate
        :param int version: Version of material to locate
        :raises VersionAlreadyExistsError: if the specified version already exists
        """
        item = {
            MetaStoreAttributeNames.PARTITION.value:
            material_name,
            MetaStoreAttributeNames.SORT.value:
            version,
            MetaStoreAttributeNames.MATERIAL_TYPE_VERSION.value:
            MetaStoreValues.MATERIAL_TYPE_VERSION.value,
            MetaStoreAttributeNames.ENCRYPTION_ALGORITHM.value:
            encryption_key.algorithm,
            MetaStoreAttributeNames.ENCRYPTION_KEY.value:
            Binary(encryption_key.key),
            MetaStoreAttributeNames.INTEGRITY_ALGORITHM.value:
            signing_key.algorithm,
            MetaStoreAttributeNames.INTEGRITY_KEY.value:
            Binary(signing_key.key),
        }
        try:
            self._encrypted_table.put_item(
                Item=item,
                ConditionExpression=(
                    Attr(MetaStoreAttributeNames.PARTITION.value).not_exists()
                    & Attr(MetaStoreAttributeNames.SORT.value).not_exists()),
            )
        except botocore.exceptions.ClientError as error:
            if error.response["Error"][
                    "Code"] == "ConditionalCheckFailedException":
                raise VersionAlreadyExistsError(
                    'Version already exists: "{}#{}"'.format(
                        material_name, version))

    def _save_or_load_materials(
            self,
            material_name,  # type: Text
            version,  # type: int
            encryption_key,  # type: JceNameLocalDelegatedKey
            signing_key,  # type: JceNameLocalDelegatedKey
    ):
        # type: (...) -> Tuple[JceNameLocalDelegatedKey, JceNameLocalDelegatedKey]
        """Attempt to save the materials to the table.

        If the specified version already exists, the existing materials will be loaded from
        the table and returned. Otherwise, the provided materials will be returned.

        :param str material_name: Material to locate
        :param int version: Version of material to locate
        :param JceNameLocalDelegatedKey encryption_key: Loaded encryption key
        :param JceNameLocalDelegatedKey signing_key: Loaded signing key
        """
        try:
            self._save_materials(material_name, version, encryption_key,
                                 signing_key)
            return encryption_key, signing_key
        except VersionAlreadyExistsError:
            return self._load_materials(material_name, version)

    @staticmethod
    def _material_description(material_name, version):
        # type: (Text, int) -> Dict[Text, Text]
        """Build a material description from a material name and version.

        :param str material_name: Material to locate
        :param int version: Version of material to locate
        """
        return {
            _MATERIAL_DESCRIPTION_META_FIELD:
            "{name}#{version}".format(name=material_name, version=version)
        }

    def _load_provider_from_table(self, material_name, version):
        # type: (Text, int) -> CryptographicMaterialsProvider
        """Load a provider from the table.

        If the requested version does not exist, an error will be raised.

        :param str material_name: Material to locate
        :param int version: Version of material to locate
        """
        encryption_key, signing_key = self._load_materials(
            material_name, version)
        return WrappedCryptographicMaterialsProvider(
            signing_key=signing_key,
            wrapping_key=encryption_key,
            unwrapping_key=encryption_key,
            material_description=self._material_description(
                material_name, version),
        )

    def get_or_create_provider(self, material_name, version):
        # type: (Text, int) -> CryptographicMaterialsProvider
        """Obtain a cryptographic materials provider identified by a name and version.

        If the requested version does not exist, a new one will be created.

        :param str material_name: Material to locate
        :param int version: Version of material to locate
        :returns: cryptographic materials provider
        :rtype: CryptographicMaterialsProvider
        :raises InvalidVersionError: if the requested version is not available and cannot be created
        """
        encryption_key = JceNameLocalDelegatedKey.generate(
            MetaStoreValues.ENCRYPTION_ALGORITHM.value,
            MetaStoreValues.KEY_BITS.value)
        signing_key = JceNameLocalDelegatedKey.generate(
            MetaStoreValues.INTEGRITY_ALGORITHM.value,
            MetaStoreValues.KEY_BITS.value)
        encryption_key, signing_key = self._save_or_load_materials(
            material_name, version, encryption_key, signing_key)
        return WrappedCryptographicMaterialsProvider(
            signing_key=signing_key,
            wrapping_key=encryption_key,
            unwrapping_key=encryption_key,
            material_description=self._material_description(
                material_name, version),
        )

    def provider(self, material_name, version=None):
        # type: (Text, Optional[int]) -> CryptographicMaterialsProvider
        """Obtain a cryptographic materials provider identified by a name and version.

        If the version is provided, an error will be raised if that version is not found.

        If the version is not provided, the maximum version will be used.

        :param str material_name: Material to locate
        :param int version: Version of material to locate (optional)
        :returns: cryptographic materials provider
        :rtype: CryptographicMaterialsProvider
        :raises InvalidVersionError: if the requested version is not found
        """
        if version is not None:
            return self._load_provider_from_table(material_name, version)

        return super(MetaStore, self).provider(material_name, version)

    def version_from_material_description(self, material_description):
        # (Dict[Text, Text]) -> int
        """Determine the version from the provided material description.

        :param dict material_description: Material description to use with this request
        :returns: version to use
        :rtype: int
        """
        try:
            info = material_description[_MATERIAL_DESCRIPTION_META_FIELD]
        except KeyError:
            raise Exception("TODO: No info found")

        try:
            return int(info.split("#", 1)[1])
        except (IndexError, ValueError):
            raise Exception("TODO: Malformed info")

    def max_version(self, material_name):
        # (Text) -> int
        """Find the maximum known version of the specified material.

        :param str material_name: Material to locate
        :returns: Maximum known version
        :rtype: int
        :raises NoKnownVersion: if no version can be found
        """
        response = self._encrypted_table.query(
            KeyConditionExpression=Key(
                MetaStoreAttributeNames.PARTITION.value).eq(material_name),
            ScanIndexForward=False,
            Limit=1,
        )

        if not response["Items"]:
            raise NoKnownVersionError(
                'No known version for name: "{}"'.format(material_name))

        return int(response["Items"][0][MetaStoreAttributeNames.SORT.value])
예제 #19
0
table = boto3.resource("dynamodb").Table(table_name)

# Create a KMS provider. Pass in a valid KMS customer master key.
aws_cmk_id = "1234abcd-12ab-34cd-56ef-1234567890ab"  # YOUR CMK HERE
aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)

# Tell the encrypted table to encrypt and sign all attributes except one.
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={"test": CryptoAction.DO_NOTHING},
)

# Use these objects to create an encrypted table resource.
encrypted_table = EncryptedTable(
    table=table, materials_provider=aws_kms_cmp, attribute_actions=actions
)

# Add an item to the table

plaintext_item = {
    "pk": "key1",
    "sk": "key2",
    "example": "data",
    "numbers": 42,
    "binary": Binary(b"\x0D\x0E\x0A\x0D\x0B\x0E\x0E\x0F"),
    "test": "don't encrypt me, bro!",
}

# Encrypt and sign item
encrypted_table.put_item(Item=plaintext_item)
예제 #20
0
def check_metastore_cache_use_encrypt(metastore, table_name, log_capture):
    try:
        table = boto3.resource("dynamodb").Table(table_name)
    except NoRegionError:
        table = boto3.resource("dynamodb",
                               region_name=TEST_REGION_NAME).Table(table_name)

    most_recent_provider = MostRecentProvider(provider_store=metastore,
                                              material_name="test",
                                              version_ttl=600.0)
    e_table = EncryptedTable(table=table,
                             materials_provider=most_recent_provider)

    item = diverse_item()
    item.update(TEST_KEY)
    e_table.put_item(Item=item)
    e_table.put_item(Item=item)
    e_table.put_item(Item=item)
    e_table.put_item(Item=item)

    try:
        primary_puts = _count_puts(log_capture.records, e_table.name)
        metastore_puts = _count_puts(log_capture.records,
                                     metastore._table.name)

        assert primary_puts == 4
        assert metastore_puts == 1

        e_table.get_item(Key=TEST_KEY)
        e_table.get_item(Key=TEST_KEY)
        e_table.get_item(Key=TEST_KEY)

        primary_gets = _count_gets(log_capture.records, e_table.name)
        metastore_gets = _count_gets(log_capture.records,
                                     metastore._table.name)
        metastore_puts = _count_puts(log_capture.records,
                                     metastore._table.name)

        assert primary_gets == 3
        assert metastore_gets == 0
        assert metastore_puts == 1

        most_recent_provider.refresh()

        e_table.get_item(Key=TEST_KEY)
        e_table.get_item(Key=TEST_KEY)
        e_table.get_item(Key=TEST_KEY)

        primary_gets = _count_gets(log_capture.records, e_table.name)
        metastore_gets = _count_gets(log_capture.records,
                                     metastore._table.name)

        assert primary_gets == 6
        assert metastore_gets == 1

    finally:
        e_table.delete_item(Key=TEST_KEY)
예제 #21
0
class User:
    db = boto3.resource("dynamodb").Table(config.DB_TABLE_NAME)
    secrets_table_name = boto3.resource("dynamodb").Table(config.SECRETS_TABLE_NAME)
    aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(config.DB_ENCRYPTION_KEY_ALIAS)


    secrets_table = EncryptedTable(
        table=secrets_table_name,
        materials_provider=aws_kms_cmp
    )

    pywaves.setNode(config.NODE_URL, config.NET_ID)
    pywaves.setThrowOnError()

    def __init__(self, user_id, seed=""):
        self.user_id = user_id
        if seed:
            self.seed = seed
            self.create_wallet(seed)
        else:
            self.initialise_wallet()

    @classmethod
    def retrieve(cls, user_id):
        """
        Creates a new User object by retrieving the user_id from database
        If the user_id does not exist in the database then this method
        will throw a KeyError
        """
        user = cls.db.get_item(Key={"user_id": str(user_id)})["Item"]
        seed = cls.retrieve_wallet(str(user["wallet_guid"]))
        return User(user_id=user["user_id"], seed=seed)

    def initialise_wallet(self):
        self.wallet_guid = str(uuid.uuid4())

        self.seed = pywaves.Address().seed 
        self.create_wallet(self.seed)
        self.secrets_table.put_item(
            Item={ "guid": self.wallet_guid, 
                   "seed": self.seed }
        )
        self.db.put_item(
            Item={"user_id": str(self.user_id), "wallet_guid": self.wallet_guid }
        )

    def create_wallet(self, seed=""):
        """
        Initializes the pywaves wallet for the User object.
        If seed is provided, the wallet is initialized from the seed,
        otherwise a wallet is generated from a new seed.
        """
        self.wallet = pywaves.Address(seed=seed)

    @classmethod 
    def retrieve_wallet(cls, wallet_guid):
        """
        Retrieves the wallet seed for the user from the encrypted secrets table
        """
        return cls.secrets_table.get_item(
           Key={"guid": wallet_guid} 
        )["Item"]["seed"]
예제 #22
0
def encrypt_item(table_name, aes_wrapping_key_bytes, hmac_signing_key_bytes):
    """Demonstrate use of EncryptedTable to transparently encrypt an item."""
    index_key = {"partition_attribute": "is this", "sort_attribute": 55}
    plaintext_item = {
        "example": "data",
        "some numbers": 99,
        "and some binary": Binary(b"\x00\x01\x02"),
        "leave me": "alone",  # We want to ignore this attribute
    }
    # Collect all of the attributes that will be encrypted (used later).
    encrypted_attributes = set(plaintext_item.keys())
    encrypted_attributes.remove("leave me")
    # Collect all of the attributes that will not be encrypted (used later).
    unencrypted_attributes = set(index_key.keys())
    unencrypted_attributes.add("leave me")
    # Add the index pairs to the item.
    plaintext_item.update(index_key)

    # Create a normal table resource.
    table = boto3.resource("dynamodb").Table(table_name)  # generated code confuse pylint: disable=no-member
    # Create a crypto materials provider using the provided wrapping and signing keys.
    wrapping_key = JceNameLocalDelegatedKey(
        key=aes_wrapping_key_bytes,
        algorithm="AES",
        key_type=EncryptionKeyType.SYMMETRIC,
        key_encoding=KeyEncodingType.RAW,
    )
    signing_key = JceNameLocalDelegatedKey(
        key=hmac_signing_key_bytes,
        algorithm="HmacSHA512",
        key_type=EncryptionKeyType.SYMMETRIC,
        key_encoding=KeyEncodingType.RAW,
    )
    wrapped_cmp = WrappedCryptographicMaterialsProvider(
        wrapping_key=wrapping_key,
        unwrapping_key=wrapping_key,
        signing_key=signing_key)
    # Create attribute actions that tells the encrypted table to encrypt all attributes except one.
    actions = AttributeActions(
        default_action=CryptoAction.ENCRYPT_AND_SIGN,
        attribute_actions={"leave me": CryptoAction.DO_NOTHING})
    # Use these objects to create an encrypted table resource.
    encrypted_table = EncryptedTable(table=table,
                                     materials_provider=wrapped_cmp,
                                     attribute_actions=actions)

    # Put the item to the table, using the encrypted table resource to transparently encrypt it.
    encrypted_table.put_item(Item=plaintext_item)

    # Get the encrypted item using the standard table resource.
    encrypted_item = table.get_item(Key=index_key)["Item"]

    # Get the item using the encrypted table resource, transparently decyrpting it.
    decrypted_item = encrypted_table.get_item(Key=index_key)["Item"]

    # Verify that all of the attributes are different in the encrypted item
    for name in encrypted_attributes:
        assert encrypted_item[name] != plaintext_item[name]
        assert decrypted_item[name] == plaintext_item[name]

    # Verify that all of the attributes that should not be encrypted were not.
    for name in unencrypted_attributes:
        assert decrypted_item[name] == encrypted_item[name] == plaintext_item[
            name]

    # Clean up the item
    encrypted_table.delete_item(Key=index_key)
예제 #23
0
def signup_login(request):
	global input_folder,output_folder
	for the_file in os.listdir(input_folder):
	    file_path = os.path.join(input_folder, the_file)
	    try:
	        if os.path.isfile(file_path):
	            os.unlink(file_path)
	    except Exception as e:
	        print(e)
	for the_file in os.listdir(output_folder):
	    file_path = os.path.join(output_folder, the_file)
	    try:
	        if os.path.isfile(file_path):
	            os.unlink(file_path)
	    except Exception as e:
	        print(e)
	if request.method == 'GET':
		return render(request,'index.html')
	if request.method == 'POST':
    	 dynamodb = boto3.resource('dynamodb',region_name='us-east-1')
    	 table = dynamodb.Table('users')
    	 aws_cmk_id=''
    	 aws_kms_cmp=AwsKmsCryptographicMaterialsProvider(key_id=aws_cmk_id)
    	 name2 = request.POST['login']
    	 name3=str(name2)
    	 actions = AttributeActions(
				    #default_action=CryptoAction.ENCRYPT_AND_SIGN,
				    default_action=CryptoAction.DO_NOTHING,
				    attribute_actions={
				    	'userid': CryptoAction.DO_NOTHING,
				        'first_name': CryptoAction.DO_NOTHING,
				        'last_name': CryptoAction.DO_NOTHING,
				        'password':CryptoAction.ENCRYPT_AND_SIGN
				        
				    }
				  )
    	 encrypted_table = EncryptedTable(
					    table=table,
					    materials_provider=aws_kms_cmp,
					    attribute_actions=actions
					)
    	 #signup='signup'
    	 #login='******'
    	 print("check*****",name2)
    	 if(name2=='send'):
    	 	 return render(request,"upload.html")
    	 if(name2=='signup'):
             	first_name=request.POST.get('first','')
             	last_name=request.POST.get('last','')
             	email = request.POST.get('newemail','')
             	password = request.POST.get('newpassword','')
             	print ("first name is ", first_name, "last name is ", last_name)
             	encrypted_table.put_item(Item={
	                        'userid': email,
	                        'first_name': first_name,
	                        'last_name': last_name,
	                        'password': password,
	                    })
             	logger.info('User Sign Up: {} - {}'.format(first_name,email))
             	return render(request,"upload.html")
    	 if(name2=='login'):
             email = request.POST.get('username','')
             password = request.POST.get('password','')
             print ("username is ", email, "password is ", password)
             email=str(email)
             password=str(password)
             s=''
             s=email+password
             response= encrypted_table.get_item(Key={
                        'userid': email
                    })
             if(len(response)==2): 
                item = response['Item']['password']
                if(password==item):
                	logger.info('Succesful Log-In: {}'.format(email))
                	return render(request,"upload.html")
                else:
                	logger.info('Unsuccesful Log-In(Password Invalid): {}'.format(email))
                	print("Invalid password")
                	return render(request,'index.html',{'s':["invalid password",'0']})
             else:
                print("Invalid Username")
                logger.info('Unsuccesful Log-In(Username Invalid): {}'.format(email))
                s1="invalid username"
                return render(request,'index.html',{'s':["invalid username",'0']})