예제 #1
0
 def _get_mocked_kek_meta_dto(self):
     # For SimpleCryptoPlugin, per-project KEKs are stored in
     # kek_meta_dto.plugin_meta. SimpleCryptoPlugin does a get-or-create
     # on the plugin_meta field, so plugin_meta should be None initially.
     kek_meta_dto = plugin.KEKMetaDTO(mock.MagicMock())
     kek_meta_dto.plugin_meta = None
     return self.plugin.bind_kek_metadata(kek_meta_dto)
예제 #2
0
    def get_secret(self, secret_metadata, context):
        """Retrieve a secret.

        :param secret_metadata: secret metadata
        :param context: StoreCryptoContext for secret
        :returns: SecretDTO that contains secret
        """
        if (not context.secret_model
                or not context.secret_model.encrypted_data):
            raise sstore.SecretNotFoundException()

        # TODO(john-wood-w) Need to revisit 1 to many datum relationship.
        datum_model = context.secret_model.encrypted_data[0]

        # Find HSM-style 'crypto' plugin.
        decrypting_plugin = manager.get_manager().get_plugin_retrieve(
            datum_model.kek_meta_project.plugin_name)

        # wrap the KEKDatum instance in our DTO
        kek_meta_dto = crypto.KEKMetaDTO(datum_model.kek_meta_project)

        # Convert from text-based storage format to binary.
        encrypted = base64.b64decode(datum_model.cypher_text)
        decrypt_dto = crypto.DecryptDTO(encrypted)

        # Decrypt the secret.
        secret = decrypting_plugin.decrypt(decrypt_dto, kek_meta_dto,
                                           datum_model.kek_meta_extended,
                                           context.project_model.external_id)
        key_spec = sstore.KeySpec(alg=context.secret_model.algorithm,
                                  bit_length=context.secret_model.bit_length,
                                  mode=context.secret_model.mode)

        return sstore.SecretDTO(sstore.SecretType.SYMMETRIC, secret, key_spec,
                                datum_model.content_type)
예제 #3
0
 def test_bind_kek_metadata_without_existing_key(self):
     with mock.patch.object(self.plugin.pkcs11, 'generate_wrapped_kek'):
         kek_datum = models.KEKDatum()
         dto = plugin_import.KEKMetaDTO(kek_datum)
         dto = self.plugin.bind_kek_metadata(dto)
         self.assertEqual(dto.algorithm, "AES")
         self.assertEqual(dto.bit_length, 256)
         self.assertEqual(dto.mode, "CBC")
예제 #4
0
    def test_bind_kek_metadata_with_existing_key(self):
        kek_datum = models.KEKDatum()
        dto = plugin_import.KEKMetaDTO(kek_datum)
        dto.plugin_meta = '{}'
        dto = self.plugin.bind_kek_metadata(dto)

        self.assertEqual(self.pkcs11.generate_key.call_count, 0)
        self.assertEqual(self.pkcs11.wrap_key.call_count, 0)
        self.assertEqual(self.pkcs11.compute_hmac.call_count, 0)
예제 #5
0
    def test_bind_kek_metadata_without_existing_key(self):
        kek_datum = models.KEKDatum()
        dto = plugin_import.KEKMetaDTO(kek_datum)
        dto = self.plugin.bind_kek_metadata(dto)

        self.assertEqual(dto.algorithm, 'AES')
        self.assertEqual(dto.bit_length, 256)
        self.assertEqual(dto.mode, 'CBC')

        self.assertEqual(self.pkcs11.get_key_handle.call_count, 2)
        self.assertEqual(self.pkcs11.generate_key.call_count, 1)
        self.assertEqual(self.pkcs11.wrap_key.call_count, 1)
        self.assertEqual(self.pkcs11.compute_hmac.call_count, 1)
예제 #6
0
    def test_bind_operation(self):
        kek_meta_dto = crypto.KEKMetaDTO(self.kek_meta_project_model)
        self.kek_meta_project_model.bind_completed = False

        store_crypto._indicate_bind_completed(kek_meta_dto,
                                              self.kek_meta_project_model)

        self.assertTrue(self.kek_meta_project_model.bind_completed)
        self.assertEqual(self.kek_meta_project_model.algorithm,
                         kek_meta_dto.algorithm)
        self.assertEqual(self.kek_meta_project_model.bit_length,
                         kek_meta_dto.bit_length)
        self.assertEqual(self.kek_meta_project_model.mode, kek_meta_dto.mode)
        self.assertEqual(self.kek_meta_project_model.plugin_meta,
                         kek_meta_dto.plugin_meta)
예제 #7
0
def _find_or_create_kek_objects(plugin_inst, project_model):
    kek_repo = repositories.get_kek_datum_repository()

    # Find or create a key encryption key.
    full_plugin_name = utils.generate_fullname_for(plugin_inst)
    kek_datum_model = kek_repo.find_or_create_kek_datum(
        project_model, full_plugin_name)

    # Bind to the plugin's key management.
    # TODO(jwood): Does this need to be in a critical section? Should the
    # bind operation just be declared idempotent in the plugin contract?
    kek_meta_dto = crypto.KEKMetaDTO(kek_datum_model)
    if not kek_datum_model.bind_completed:
        kek_meta_dto = plugin_inst.bind_kek_metadata(kek_meta_dto)

        # By contract, enforce that plugins return a
        # (typically modified) DTO.
        if kek_meta_dto is None:
            raise crypto.CryptoKEKBindingException(full_plugin_name)

        _indicate_bind_completed(kek_meta_dto, kek_datum_model)
        kek_repo.save(kek_datum_model)

    return kek_datum_model, kek_meta_dto