示例#1
0
    def generate_asymmetric(self, generate_dto, kek_meta_dto, project_id):
        """Generate asymmetric keys based on below rules:

        - RSA, with passphrase (supported)
        - RSA, without passphrase (supported)
        - DSA, without passphrase (supported)
        - DSA, with passphrase (not supported)

        Note: PyCrypto is not capable of serializing DSA
        keys and DER formated keys. Such keys will be
        serialized to Base64 PEM to store in DB.

        TODO (atiwari/reaperhulk): PyCrypto is not capable to serialize
        DSA keys and DER formated keys, later we need to pick better
        crypto lib.
        """
        if (generate_dto.algorithm is None
                or generate_dto.algorithm.lower() == 'rsa'):
            private_key = RSA.generate(generate_dto.bit_length, None, None,
                                       65537)
        elif generate_dto.algorithm.lower() == 'dsa':
            private_key = DSA.generate(generate_dto.bit_length, None, None)
        else:
            raise c.CryptoPrivateKeyFailureException()

        public_key = private_key.publickey()

        # Note (atiwari): key wrapping format PEM only supported
        if generate_dto.algorithm.lower() == 'rsa':
            public_key, private_key = self._wrap_key(public_key, private_key,
                                                     generate_dto.passphrase)
        if generate_dto.algorithm.lower() == 'dsa':
            if generate_dto.passphrase:
                raise ValueError(u._('Passphrase not supported for DSA key'))
            public_key, private_key = self._serialize_dsa_key(
                public_key, private_key)
        private_dto = self.encrypt(c.EncryptDTO(private_key), kek_meta_dto,
                                   project_id)

        public_dto = self.encrypt(c.EncryptDTO(public_key), kek_meta_dto,
                                  project_id)

        passphrase_dto = None
        if generate_dto.passphrase:
            if isinstance(generate_dto.passphrase, six.text_type):
                generate_dto.passphrase = generate_dto.passphrase.encode(
                    'utf-8')

            passphrase_dto = self.encrypt(
                c.EncryptDTO(generate_dto.passphrase), kek_meta_dto,
                project_id)

        return private_dto, public_dto, passphrase_dto
示例#2
0
    def test_encrypt_bad_session(self):
        self.pkcs11.get_session.return_value = mock.DEFAULT
        self.pkcs11.get_session.side_effect = pkcs11.P11CryptoPluginException(
            'Testing error handling'
        )
        payload = b'test payload'
        encrypt_dto = plugin_import.EncryptDTO(payload)
        kek_meta = mock.MagicMock()
        kek_meta.kek_label = 'pkek'
        kek_meta.plugin_meta = ('{"iv": "iv==",'
                                '"hmac": "hmac",'
                                '"wrapped_key": "wrappedkey==",'
                                '"mkek_label": "mkek_label",'
                                '"hmac_label": "hmac_label"}')
        self.assertRaises(pkcs11.P11CryptoPluginException,
                          self.plugin.encrypt,
                          encrypt_dto,
                          kek_meta,
                          mock.MagicMock())

        self.assertEqual(self.pkcs11.get_key_handle.call_count, 2)
        self.assertEqual(self.pkcs11.get_session.call_count, 2)
        self.assertEqual(self.pkcs11.verify_hmac.call_count, 1)
        self.assertEqual(self.pkcs11.unwrap_key.call_count, 1)
        self.assertEqual(self.pkcs11.encrypt.call_count, 0)
        self.assertEqual(self.pkcs11.return_session.call_count, 0)
示例#3
0
    def test_encrypt_with_unicode_kek_must_pass(self):
        """Test plan:

                Generate a kek
                Encrypt with master kek
                Convert to unicode
                call plugin.encrypt on unencrypted
                decrypt response cypher_text
                Compare with unencrypted
        """
        project_kek = fernet.Fernet.generate_key()
        encryptor = fernet.Fernet(self.plugin.master_kek)
        ENC_project_kek = encryptor.encrypt(project_kek)
        UENC_project_kek = six.u(ENC_project_kek)
        kek_meta_dto = self._get_mocked_kek_meta_dto()
        kek_meta_dto.plugin_meta = UENC_project_kek

        unencrypted = b'PlainTextSecret'
        encrypt_dto = plugin.EncryptDTO(unencrypted)
        response_dto = self.plugin.encrypt(encrypt_dto, kek_meta_dto,
                                           mock.MagicMock())

        project_encryptor = fernet.Fernet(project_kek)
        decrypted = project_encryptor.decrypt(response_dto.cypher_text)
        self.assertEqual(unencrypted, decrypted)
示例#4
0
    def store_secret(self, secret_dto, context):
        """Store a secret.

        :param secret_dto: SecretDTO for secret
        :param context: StoreCryptoContext for secret
        :returns: an optional dictionary containing metadata about the secret
        """

        # Find HSM-style 'crypto' plugin.
        encrypting_plugin = manager.get_manager().get_plugin_store_generate(
            crypto.PluginSupportTypes.ENCRYPT_DECRYPT)

        # Find or create a key encryption key metadata.
        kek_datum_model, kek_meta_dto = _find_or_create_kek_objects(
            encrypting_plugin, context.project_model)

        # Secrets are base64 encoded before being passed to the secret stores.
        secret_bytes = base64.b64decode(secret_dto.secret)

        encrypt_dto = crypto.EncryptDTO(secret_bytes)

        # Enhance the context with content_type, This is needed to build
        # datum_model to store
        if not context.content_type:
            context.content_type = secret_dto.content_type

        # Create an encrypted datum instance and add the encrypted cyphertext.
        response_dto = encrypting_plugin.encrypt(
            encrypt_dto, kek_meta_dto, context.project_model.external_id)

        # Convert binary data into a text-based format.
        _store_secret_and_datum(context, context.secret_model, kek_datum_model,
                                response_dto)

        return None
示例#5
0
 def generate_symmetric(self, generate_dto, kek_meta_dto, project_id):
     byte_length = generate_dto.bit_length / 8
     session = self.pkcs11.create_working_session()
     buf = self.pkcs11.generate_random(byte_length, session)
     self.pkcs11.close_session(session)
     rand = self.pkcs11.ffi.buffer(buf)[:]
     assert len(rand) == byte_length
     return self.encrypt(plugin.EncryptDTO(rand), kek_meta_dto, project_id)
示例#6
0
 def test_byte_string_encryption(self):
     unencrypted = b'some_secret'
     encrypt_dto = plugin.EncryptDTO(unencrypted)
     kek_meta_dto = self._get_mocked_kek_meta_dto()
     response_dto = self.plugin.encrypt(encrypt_dto, kek_meta_dto,
                                        mock.MagicMock())
     decrypt_dto = plugin.DecryptDTO(response_dto.cypher_text)
     decrypted = self.plugin.decrypt(decrypt_dto, kek_meta_dto,
                                     response_dto.kek_meta_extended,
                                     mock.MagicMock())
     self.assertEqual(unencrypted, decrypted)
示例#7
0
 def test_random_bytes_encryption(self):
     unencrypted = os.urandom(10)
     encrypt_dto = plugin.EncryptDTO(unencrypted)
     kek_meta_dto = self._get_mocked_kek_meta_dto()
     response_dto = self.plugin.encrypt(encrypt_dto, kek_meta_dto,
                                        mock.MagicMock())
     decrypt_dto = plugin.DecryptDTO(response_dto.cypher_text)
     decrypted = self.plugin.decrypt(decrypt_dto, kek_meta_dto,
                                     response_dto.kek_meta_extended,
                                     mock.MagicMock())
     self.assertEqual(unencrypted, decrypted)
示例#8
0
    def test_encrypt(self):
        payload = 'encrypt me!!'
        self.lib.C_EncryptInit.return_value = p11_crypto.CKR_OK
        self.lib.C_Encrypt.return_value = p11_crypto.CKR_OK
        encrypt_dto = plugin_import.EncryptDTO(payload)
        with mock.patch.object(self.plugin, '_unwrap_key') as unwrap_key_mock:
            unwrap_key_mock.return_value = 'unwrapped_key'
            response_dto = self.plugin.encrypt(encrypt_dto, mock.MagicMock(),
                                               mock.MagicMock())

            self.assertEqual(self.lib.C_Encrypt.call_count, 1)
            self.assertEqual(response_dto.cypher_text, b"\x00" * 32)
示例#9
0
 def test_encrypt_unicode_raises_value_error(self):
     unencrypted = u'unicode_beer\U0001F37A'
     encrypt_dto = plugin.EncryptDTO(unencrypted)
     secret = mock.MagicMock()
     secret.mime_type = 'text/plain'
     kek_meta_dto = self._get_mocked_kek_meta_dto()
     self.assertRaises(
         ValueError,
         self.plugin.encrypt,
         encrypt_dto,
         kek_meta_dto,
         mock.MagicMock(),
     )
示例#10
0
    def test_encrypt(self):
        payload = 'encrypt me!!'
        self.lib.C_EncryptInit.return_value = pkcs11.CKR_OK
        self.lib.C_Encrypt.return_value = pkcs11.CKR_OK
        encrypt_dto = plugin_import.EncryptDTO(payload)
        kek_meta = mock.MagicMock()
        kek_meta.plugin_meta = ('{"iv":123,'
                                '"hmac": "hmac",'
                                '"wrapped_key": "wrapped_key",'
                                '"mkek_label": "mkek_label",'
                                '"hmac_label": "hmac_label"}')
        with mock.patch.object(self.plugin.pkcs11, 'unwrap_key') as key_mock:
            key_mock.return_value = 'unwrapped_key'
            response_dto = self.plugin.encrypt(encrypt_dto, kek_meta,
                                               mock.MagicMock())

            self.assertEqual(self.lib.C_Encrypt.call_count, 1)
            self.assertEqual(response_dto.cypher_text, b"\x00" * 32)
示例#11
0
    def test_encrypt(self):
        payload = b'test payload'
        encrypt_dto = plugin_import.EncryptDTO(payload)
        kek_meta = mock.MagicMock()
        kek_meta.kek_label = 'pkek'
        kek_meta.plugin_meta = ('{"iv": "iv==",'
                                '"hmac": "hmac",'
                                '"wrapped_key": "wrappedkey==",'
                                '"mkek_label": "mkek_label",'
                                '"hmac_label": "hmac_label"}')
        response_dto = self.plugin.encrypt(encrypt_dto, kek_meta,
                                           mock.MagicMock())

        self.assertEqual(b'0', response_dto.cypher_text)
        self.assertIn('iv', response_dto.kek_meta_extended)

        self.assertEqual(2, self.pkcs11.get_key_handle.call_count)
        self.assertEqual(2, self.pkcs11.get_session.call_count)
        self.assertEqual(1, self.pkcs11.verify_hmac.call_count)
        self.assertEqual(1, self.pkcs11.unwrap_key.call_count)
        self.assertEqual(1, self.pkcs11.encrypt.call_count)
        self.assertEqual(1, self.pkcs11.return_session.call_count)
示例#12
0
 def generate_symmetric(self, generate_dto, kek_meta_dto, project_id):
     byte_length = generate_dto.bit_length / 8
     buf = self._generate_random(byte_length)
     rand = self.ffi.buffer(buf)[:]
     assert len(rand) == byte_length
     return self.encrypt(plugin.EncryptDTO(rand), kek_meta_dto, project_id)
示例#13
0
    def generate_symmetric(self, generate_dto, kek_meta_dto, project_id):
        byte_length = int(generate_dto.bit_length) // 8
        unencrypted = os.urandom(byte_length)

        return self.encrypt(c.EncryptDTO(unencrypted), kek_meta_dto,
                            project_id)