# Copyright 2017 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import os
import subprocess
import tempfile

from zuul.lib import encryption

from tests.base import BaseTestCase


class TestEncryption(BaseTestCase):

    def setUp(self):
        super(TestEncryption, self).setUp()
        self.private, self.public = encryption.generate_rsa_keypair()

    def test_serialization(self):
        "Verify key serialization"
        pem_private = encryption.serialize_rsa_private_key(self.private)
        private2, public2 = encryption.deserialize_rsa_keypair(pem_private)

        # cryptography public / private key objects don't implement
        # equality testing, so we make sure they have the same numbers.
        self.assertEqual(self.private.private_numbers(),
                         private2.private_numbers())
        self.assertEqual(self.public.public_numbers(),
                         public2.public_numbers())

    def test_pkcs1(self):
        "Verify encryption and decryption"
        orig_plaintext = "some text to encrypt"
        ciphertext = encryption.encrypt_pkcs1(orig_plaintext, self.public)
        plaintext = encryption.decrypt_pkcs1(ciphertext, self.private)
        self.assertEqual(orig_plaintext, plaintext)

    def test_openssl_pkcs1(self):
        "Verify that we can decrypt something encrypted with OpenSSL"
        orig_plaintext = "some text to encrypt"
        pem_public = encryption.serialize_rsa_public_key(self.public)
        public_file = tempfile.NamedTemporaryFile(delete=False)
        try:
            public_file.write(pem_public)
            public_file.close()

            p = subprocess.Popen(['openssl', 'rsautl', '-encrypt',
                                  '-oaep', '-pubin', '-inkey',
                                  public_file.name],
                                 stdin=subprocess.PIPE,
                                 stdout=subprocess.PIPE)
            (stdout, stderr) = p.communicate(orig_plaintext)
            ciphertext = stdout
        finally:
            os.unlink(public_file.name)

        plaintext = encryption.decrypt_pkcs1(ciphertext, self.private)
        self.assertEqual(orig_plaintext, plaintext)
