Exemplo n.º 1
0
    def setUp(self):
        self.profile = "facilitydata"

        self.root_scope_def = ScopeDefinition.objects.create(
            id="rootcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="mainpartition",
            description="Root cert for ${mainpartition}.",
            read_filter_template="",
            write_filter_template="",
            read_write_filter_template="${mainpartition}",
        )

        self.subset_scope_def = ScopeDefinition.objects.create(
            id="subcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="",
            description=
            "Subset cert under ${mainpartition} for ${subpartition}.",
            read_filter_template="${mainpartition}",
            write_filter_template="${mainpartition}:${subpartition}",
            read_write_filter_template="",
        )

        self.root_cert = Certificate.generate_root_certificate(
            self.root_scope_def.id)

        self.subset_cert = Certificate(
            parent=self.root_cert,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.root_cert.id,
                "subpartition": "abracadabra"
            }),
            private_key=Key(),
        )
        self.root_cert.sign_certificate(self.subset_cert)
        self.subset_cert.save()

        self.unsaved_cert = Certificate(
            parent=self.root_cert,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.root_cert.id,
                "subpartition": "other"
            }),
            public_key=Key(),
        )
        self.root_cert.sign_certificate(self.unsaved_cert)

        self.controller = MorangoProfileController('facilitydata')
        self.network_connection = self.controller.create_network_connection(
            self.live_server_url)
        self.key = SharedKey.get_or_create_shared_key()
Exemplo n.º 2
0
class CertificateTestCaseMixin(object):
    def setUp(self):

        self.profile = "testprofile"

        self.root_scope_def = ScopeDefinition.objects.create(
            id="rootcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="mainpartition",
            description="Root cert for ${mainpartition}.",
            read_filter_template="",
            write_filter_template="",
            read_write_filter_template="${mainpartition}",
        )

        self.subset_scope_def = ScopeDefinition.objects.create(
            id="subcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="",
            description=
            "Subset cert under ${mainpartition} for ${subpartition}.",
            read_filter_template="${mainpartition}",
            write_filter_template="${mainpartition}:${subpartition}",
            read_write_filter_template="",
        )

        self.root_cert = Certificate.generate_root_certificate(
            self.root_scope_def.id)

        self.subset_cert = Certificate(
            parent=self.root_cert,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.root_cert.id,
                "subpartition": "abracadabra"
            }),
            private_key=Key(),
        )
        self.root_cert.sign_certificate(self.subset_cert)
        self.subset_cert.save()
Exemplo n.º 3
0
    def certificate_signing_request(self,
                                    parent_cert,
                                    scope_definition_id,
                                    scope_params,
                                    userargs=None,
                                    password=None):
        # if server cert does not exist locally, retrieve it from server
        if not Certificate.objects.filter(id=parent_cert.id).exists():
            cert_chain_response = self._get_certificate_chain(parent_cert)

            # upon receiving cert chain from server, we attempt to save the chain into our records
            Certificate.save_certificate_chain(cert_chain_response.json(),
                                               expected_last_id=parent_cert.id)

        csr_key = Key()
        # build up data for csr
        data = {
            "parent": parent_cert.id,
            "profile": parent_cert.profile,
            "scope_definition": scope_definition_id,
            "scope_version": parent_cert.scope_version,
            "scope_params": json.dumps(scope_params),
            "public_key": csr_key.get_public_key_string()
        }
        csr_resp = self._request(api_urls.CERTIFICATE,
                                 method="POST",
                                 data=data,
                                 userargs=userargs,
                                 password=password)
        csr_data = csr_resp.json()

        # verify cert returned from server, and proceed to save into our records
        csr_cert = Certificate.deserialize(csr_data["serialized"],
                                           csr_data["signature"])
        csr_cert.private_key = csr_key
        csr_cert.check_certificate()
        csr_cert.save()
        return csr_cert
Exemplo n.º 4
0
    def get_remote_certificates(self, primary_partition, scope_def_id=None):
        remote_certs = []
        # request certs for this primary partition, where the server also has a private key for
        remote_certs_resp = self._request(api_urls.CERTIFICATE, params={'primary_partition': primary_partition})

        # inflate remote certs into a list of unsaved models
        for cert in remote_certs_resp.json():
            remote_certs.append(Certificate.deserialize(cert["serialized"], cert["signature"]))

        # filter certs by scope definition id, if provided
        if scope_def_id:
            remote_certs = [cert for cert in remote_certs if cert.scope_definition_id == scope_def_id]

        return remote_certs
Exemplo n.º 5
0
    def test_bad_scope_subset_does_not_validate(self):

        bad_subset_cert = Certificate(
            parent=self.root_cert,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": "a" * 32,
                "subpartition": "abracadabra"
            }),
            private_key=Key(),
        )
        self.root_cert.sign_certificate(bad_subset_cert)
        bad_subset_cert.save()

        with self.assertRaises(CertificateScopeNotSubset):
            bad_subset_cert.check_certificate()
Exemplo n.º 6
0
    def push_signed_client_certificate_chain(self, local_parent_cert,
                                             scope_definition_id,
                                             scope_params):
        # grab shared public key of server
        publickey_response = self._get_public_key()

        # request the server for a one-time-use nonce
        nonce_response = self._get_nonce()

        # build up data for csr
        certificate = Certificate(
            parent_id=local_parent_cert.id,
            profile=local_parent_cert.profile,
            scope_definition_id=scope_definition_id,
            scope_version=local_parent_cert.scope_version,
            scope_params=json.dumps(scope_params),
            public_key=Key(
                public_key_string=publickey_response.json()[0]['public_key']),
            salt=nonce_response.json()[
                "id"]  # for pushing signed certs, we use nonce as salt
        )

        # add ID and signature to the certificate
        certificate.id = certificate.calculate_uuid()
        certificate.parent.sign_certificate(certificate)

        # serialize the chain for sending to server
        certificate_chain = list(
            local_parent_cert.get_descendants(
                include_self=True)) + [certificate]
        data = json.dumps(
            CertificateSerializer(certificate_chain, many=True).data)

        # client sends signed certificate chain to server
        self._push_certificate_chain(data)

        # if there are no errors, we can save the pushed certificate
        certificate.save()
        return certificate
Exemplo n.º 7
0
 def calculate_source_id(self):
     # if we don't already have a source ID, get one by generating a new root certificate, and using its ID
     if not self._morango_source_id:
         self._morango_source_id = Certificate.generate_root_certificate(
             FULL_FACILITY).id
     return self._morango_source_id
Exemplo n.º 8
0
class NetworkSyncConnectionTestCase(LiveServerTestCase):
    def setUp(self):
        self.profile = "facilitydata"

        self.root_scope_def = ScopeDefinition.objects.create(
            id="rootcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="mainpartition",
            description="Root cert for ${mainpartition}.",
            read_filter_template="",
            write_filter_template="",
            read_write_filter_template="${mainpartition}",
        )

        self.subset_scope_def = ScopeDefinition.objects.create(
            id="subcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="",
            description=
            "Subset cert under ${mainpartition} for ${subpartition}.",
            read_filter_template="${mainpartition}",
            write_filter_template="${mainpartition}:${subpartition}",
            read_write_filter_template="",
        )

        self.root_cert = Certificate.generate_root_certificate(
            self.root_scope_def.id)

        self.subset_cert = Certificate(
            parent=self.root_cert,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.root_cert.id,
                "subpartition": "abracadabra"
            }),
            private_key=Key(),
        )
        self.root_cert.sign_certificate(self.subset_cert)
        self.subset_cert.save()

        self.unsaved_cert = Certificate(
            parent=self.root_cert,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.root_cert.id,
                "subpartition": "other"
            }),
            public_key=Key(),
        )
        self.root_cert.sign_certificate(self.unsaved_cert)

        self.controller = MorangoProfileController('facilitydata')
        self.network_connection = self.controller.create_network_connection(
            self.live_server_url)
        self.key = SharedKey.get_or_create_shared_key()

    @mock.patch.object(SyncSession.objects, 'create', return_value=None)
    def test_creating_sync_session_successful(self, mock_object):
        self.assertEqual(SyncSession.objects.filter(active=True).count(), 0)
        self.network_connection.create_sync_session(self.subset_cert,
                                                    self.root_cert)
        self.assertEqual(SyncSession.objects.filter(active=True).count(), 1)

    @mock.patch.object(NetworkSyncConnection, '_create_sync_session')
    @mock.patch.object(Certificate, 'verify', return_value=False)
    def test_creating_sync_session_cert_fails_to_verify(
            self, mock_verify, mock_create):
        mock_create.return_value.json.return_value = {}
        with self.assertRaises(CertificateSignatureInvalid):
            self.network_connection.create_sync_session(
                self.subset_cert, self.root_cert)

    def test_get_remote_certs(self):
        certs = self.subset_cert.get_ancestors(include_self=True)
        remote_certs = self.network_connection.get_remote_certificates(
            self.root_cert.id)
        self.assertSetEqual(set(certs), set(remote_certs))

    @mock.patch.object(NetworkSyncConnection, '_request')
    def test_csr(self, mock_request):
        # mock a "signed" cert being returned by server
        cert_serialized = json.dumps(
            CertificateSerializer(self.subset_cert).data)
        mock_request.return_value.json.return_value = json.loads(
            cert_serialized)
        self.subset_cert.delete()

        # we only want to make sure the "signed" cert is saved
        with mock.patch.object(Key,
                               "get_private_key_string",
                               return_value=self.subset_cert.private_key.
                               get_private_key_string()):
            self.network_connection.certificate_signing_request(
                self.root_cert, '', '')
        self.assertTrue(
            Certificate.objects.filter(
                id=json.loads(cert_serialized)['id']).exists())

    @override_settings(ALLOW_CERTIFICATE_PUSHING=True)
    def test_push_signed_client_certificate_chain(self):
        cert = self.network_connection.push_signed_client_certificate_chain(
            self.root_cert, self.subset_scope_def.id, {
                "mainpartition": self.root_cert.id,
                "subpartition": "abracadabra"
            })
        self.assertEqual(cert.private_key, None)
        self.assertTrue(Certificate.objects.filter(id=cert.id).exists())

    @override_settings(ALLOW_CERTIFICATE_PUSHING=True)
    def test_push_signed_client_certificate_chain_publickey_error(self):
        with mock.patch.object(NetworkSyncConnection, '_get_public_key'):
            NetworkSyncConnection._get_public_key.return_value.json.return_value = [
                {
                    'public_key': Key().get_public_key_string()
                }
            ]
            with self.assertRaises(HTTPError) as e:
                self.network_connection.push_signed_client_certificate_chain(
                    self.root_cert, self.subset_scope_def.id, {
                        "mainpartition": self.root_cert.id,
                        "subpartition": "abracadabra"
                    })
            self.assertEqual(e.exception.response.status_code, 400)

    @override_settings(ALLOW_CERTIFICATE_PUSHING=True)
    def test_push_signed_client_certificate_chain_bad_cert(self):
        with self.assertRaises(HTTPError) as e:
            self.network_connection.push_signed_client_certificate_chain(
                self.root_cert, self.subset_scope_def.id,
                {"bad": "scope_params"})
        self.assertEqual(e.exception.response.status_code, 400)

    @override_settings(ALLOW_CERTIFICATE_PUSHING=True)
    @mock.patch.object(NetworkSyncConnection, '_get_nonce')
    def test_push_signed_client_certificate_chain_nonce_error(
            self, mock_nonce):
        mock_nonce.return_value.json.return_value = {'id': uuid.uuid4().hex}
        with self.assertRaises(HTTPError) as e:
            self.network_connection.push_signed_client_certificate_chain(
                self.root_cert, self.subset_scope_def.id, {
                    "mainpartition": self.root_cert.id,
                    "subpartition": "abracadabra"
                })
        self.assertEqual(e.exception.response.status_code, 403)

    def test_push_signed_client_certificate_chain_not_allowed(self):
        with self.assertRaises(MorangoServerDoesNotAllowNewCertPush) as e:
            self.network_connection.push_signed_client_certificate_chain(
                self.root_cert, self.subset_scope_def.id, {
                    "mainpartition": self.root_cert.id,
                    "subpartition": "abracadabra"
                })
            self.assertEqual(e.exception.response.status_code, 403)

    def test_get_cert_chain(self):
        response = self.network_connection._get_certificate_chain(
            self.subset_cert)
        data = response.json()
        self.assertEqual(len(data), Certificate.objects.count())
        self.assertEqual(data[0]['id'], self.root_cert.id)
        self.assertEqual(data[1]['id'], self.subset_cert.id)
Exemplo n.º 9
0
    def setUp(self):

        self.user = MyUser(username="******")
        self.user.actual_password = "******"
        self.user.set_password(self.user.actual_password)
        self.user.save()

        self.superuser = MyUser(username="******", is_superuser=True)
        self.superuser.actual_password = "******"
        self.superuser.set_password(self.superuser.actual_password)
        self.superuser.save()

        self.fakeuser = MyUser(username="******")
        self.fakeuser.actual_password = "******"

        self.profile = "facilitydata"

        self.root_scope_def = ScopeDefinition.objects.create(
            id="rootcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="mainpartition",
            description="Root cert for ${mainpartition}.",
            read_filter_template="",
            write_filter_template="",
            read_write_filter_template="${mainpartition}",
        )

        self.subset_scope_def = ScopeDefinition.objects.create(
            id="subcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="",
            description=
            "Subset cert under ${mainpartition} for ${subpartition}.",
            read_filter_template=
            "${mainpartition}:shared\n${mainpartition}:${subpartition}",
            write_filter_template="${mainpartition}:${subpartition}",
            read_write_filter_template="",
        )

        self.root_cert1_with_key = Certificate.generate_root_certificate(
            self.root_scope_def.id)

        self.subset_cert1_without_key = Certificate(
            parent=self.root_cert1_with_key,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.root_cert1_with_key.id,
                "subpartition": "abracadabra"
            }),
            private_key=Key(),
        )
        self.root_cert1_with_key.sign_certificate(
            self.subset_cert1_without_key)
        self.subset_cert1_without_key.save()

        self.sub_subset_cert1_with_key = Certificate(
            parent=self.subset_cert1_without_key,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=self.subset_cert1_without_key.scope_params,
            private_key=Key(),
        )
        self.subset_cert1_without_key.sign_certificate(
            self.sub_subset_cert1_with_key)
        self.sub_subset_cert1_with_key.save()

        self.subset_cert1_without_key._private_key = None
        self.subset_cert1_without_key.save()

        self.root_cert2_without_key = Certificate.generate_root_certificate(
            self.root_scope_def.id)

        self.subset_cert2_with_key = Certificate(
            parent=self.root_cert2_without_key,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition":
                self.root_cert2_without_key.id,
                "subpartition":
                "abracadabra"
            }),
            private_key=Key(),
        )
        self.root_cert2_without_key.sign_certificate(
            self.subset_cert2_with_key)
        self.subset_cert2_with_key.save()
        self.root_cert2_without_key._private_key = None
        self.root_cert2_without_key.save()

        self.original_cert_count = Certificate.objects.count()

        self.sharedkey = SharedKey.get_or_create_shared_key()

        # create a root cert
        self.unsaved_root_cert = Certificate(
            scope_definition=self.root_scope_def,
            scope_version=self.root_scope_def.version,
            profile=self.profile,
            private_key=Key())
        self.unsaved_root_cert.id = self.unsaved_root_cert.calculate_uuid()
        self.unsaved_root_cert.scope_params = json.dumps({
            self.root_scope_def.primary_scope_param_key:
            self.unsaved_root_cert.id
        })
        self.unsaved_root_cert.sign_certificate(self.unsaved_root_cert)

        # create a child cert
        self.unsaved_subset_cert = Certificate(
            parent=self.unsaved_root_cert,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.unsaved_root_cert.id,
                "subpartition": "hooplah"
            }),
            public_key=self.sharedkey.public_key,
        )
Exemplo n.º 10
0
class CertificateTestCaseMixin(object):
    def setUp(self):

        self.user = MyUser(username="******")
        self.user.actual_password = "******"
        self.user.set_password(self.user.actual_password)
        self.user.save()

        self.superuser = MyUser(username="******", is_superuser=True)
        self.superuser.actual_password = "******"
        self.superuser.set_password(self.superuser.actual_password)
        self.superuser.save()

        self.fakeuser = MyUser(username="******")
        self.fakeuser.actual_password = "******"

        self.profile = "facilitydata"

        self.root_scope_def = ScopeDefinition.objects.create(
            id="rootcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="mainpartition",
            description="Root cert for ${mainpartition}.",
            read_filter_template="",
            write_filter_template="",
            read_write_filter_template="${mainpartition}",
        )

        self.subset_scope_def = ScopeDefinition.objects.create(
            id="subcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="",
            description=
            "Subset cert under ${mainpartition} for ${subpartition}.",
            read_filter_template=
            "${mainpartition}:shared\n${mainpartition}:${subpartition}",
            write_filter_template="${mainpartition}:${subpartition}",
            read_write_filter_template="",
        )

        self.root_cert1_with_key = Certificate.generate_root_certificate(
            self.root_scope_def.id)

        self.subset_cert1_without_key = Certificate(
            parent=self.root_cert1_with_key,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.root_cert1_with_key.id,
                "subpartition": "abracadabra"
            }),
            private_key=Key(),
        )
        self.root_cert1_with_key.sign_certificate(
            self.subset_cert1_without_key)
        self.subset_cert1_without_key.save()

        self.sub_subset_cert1_with_key = Certificate(
            parent=self.subset_cert1_without_key,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=self.subset_cert1_without_key.scope_params,
            private_key=Key(),
        )
        self.subset_cert1_without_key.sign_certificate(
            self.sub_subset_cert1_with_key)
        self.sub_subset_cert1_with_key.save()

        self.subset_cert1_without_key._private_key = None
        self.subset_cert1_without_key.save()

        self.root_cert2_without_key = Certificate.generate_root_certificate(
            self.root_scope_def.id)

        self.subset_cert2_with_key = Certificate(
            parent=self.root_cert2_without_key,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition":
                self.root_cert2_without_key.id,
                "subpartition":
                "abracadabra"
            }),
            private_key=Key(),
        )
        self.root_cert2_without_key.sign_certificate(
            self.subset_cert2_with_key)
        self.subset_cert2_with_key.save()
        self.root_cert2_without_key._private_key = None
        self.root_cert2_without_key.save()

        self.original_cert_count = Certificate.objects.count()

        self.sharedkey = SharedKey.get_or_create_shared_key()

        # create a root cert
        self.unsaved_root_cert = Certificate(
            scope_definition=self.root_scope_def,
            scope_version=self.root_scope_def.version,
            profile=self.profile,
            private_key=Key())
        self.unsaved_root_cert.id = self.unsaved_root_cert.calculate_uuid()
        self.unsaved_root_cert.scope_params = json.dumps({
            self.root_scope_def.primary_scope_param_key:
            self.unsaved_root_cert.id
        })
        self.unsaved_root_cert.sign_certificate(self.unsaved_root_cert)

        # create a child cert
        self.unsaved_subset_cert = Certificate(
            parent=self.unsaved_root_cert,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.unsaved_root_cert.id,
                "subpartition": "hooplah"
            }),
            public_key=self.sharedkey.public_key,
        )

    def make_cert_endpoint_request(self, params={}, method="GET"):
        fn = getattr(self.client, method.lower())
        response = fn(reverse('certificates-list'), params, format='json')
        data = json.loads(response.content.decode())
        return (response, data)

    def perform_basic_authentication(self, user):
        basic_auth_header = b'Basic ' + base64.encodestring(
            ("username=%s:%s" %
             (user.username, user.actual_password)).encode())
        self.client.credentials(HTTP_AUTHORIZATION=basic_auth_header)

    def create_syncsession(self,
                           client_certificate=None,
                           server_certificate=None):

        if not client_certificate:
            client_certificate = self.sub_subset_cert1_with_key

        if not server_certificate:
            server_certificate = self.root_cert1_with_key

        # fetch a nonce value to use in creating the syncsession
        response = self.client.post(reverse('nonces-list'), {}, format='json')
        nonce = json.loads(response.content.decode())["id"]

        # prepare the data to send in the syncsession creation request
        data = {
            "id":
            uuid.uuid4().hex,
            "server_certificate_id":
            server_certificate.id,
            "client_certificate_id":
            client_certificate.id,
            "profile":
            client_certificate.profile,
            "certificate_chain":
            json.dumps(
                CertificateSerializer(
                    client_certificate.get_ancestors(include_self=True),
                    many=True).data),
            "connection_path":
            "http://127.0.0.1:8000",
            "instance":
            json.dumps(
                InstanceIDSerializer(
                    InstanceIDModel.get_or_create_current_instance()[0]).data),
            "nonce":
            nonce,
        }

        # sign the nonce/ID combo to attach to the request
        data["signature"] = client_certificate.sign(
            "{nonce}:{id}".format(**data))

        # make the API call to create the SyncSession
        response = self.client.post(reverse('syncsessions-list'),
                                    data,
                                    format='json')
        self.assertEqual(response.status_code, 201)

        return SyncSession.objects.get(id=data["id"])

    def make_transfersession_creation_request(self,
                                              filter,
                                              push,
                                              syncsession=None,
                                              expected_status=201,
                                              expected_message=None,
                                              **kwargs):

        if not syncsession:
            syncsession = self.create_syncsession()

        data = {
            "id": uuid.uuid4().hex,
            "filter": filter,
            "push": push,
            "records_total": 0,
            "sync_session_id": syncsession.id,
        }

        # make the API call to attempt to create the TransferSession
        response = self.client.post(reverse('transfersessions-list'),
                                    data,
                                    format='json')
        self.assertEqual(response.status_code, expected_status)

        if expected_status == 201:
            # check that the syncsession was created
            transfersession = TransferSession.objects.get(
                id=json.loads(response.content.decode())["id"])
            self.assertTrue(transfersession.active)
        else:
            # check that the syncsession was not created
            self.assertEqual(TransferSession.objects.count(), 0)

        if expected_message:
            self.assertIn(expected_message, response.content.decode())

        return response
Exemplo n.º 11
0
 def test_setting_public_key_does_not_set_private_key(self):
     cert = Certificate()
     cert.public_key = Key()
     self.assertEqual(cert.private_key, None)
Exemplo n.º 12
0
 def test_setting_private_key_sets_public_key(self):
     cert = Certificate()
     cert.private_key = Key()
     self.assertTrue(
         cert.public_key.verify("testval",
                                cert.private_key.sign("testval")))
Exemplo n.º 13
0
 def setUp(self):
     super(CertificateSerializationTestCase, self).setUp()
     self.root_cert_deserialized = Certificate.deserialize(
         self.root_cert.serialized, self.root_cert.signature)
     self.subset_cert_deserialized = Certificate.deserialize(
         self.subset_cert.serialized, self.subset_cert.signature)
Exemplo n.º 14
0
    def _get_certificate_chain(self, server_cert):
        # get ancestors certificate chain for this server cert
        cert_chain_resp = self._request(api_urls.CERTIFICATE, params={'ancestors_of': server_cert.id})

        # upon receiving cert chain from server, we attempt to save the chain into our records
        Certificate.save_certificate_chain(cert_chain_resp.json(), expected_last_id=server_cert.id)
Exemplo n.º 15
0
 def calculate_source_id(self):
     # if we don't already have a source ID, get one by generating a new root certificate, and using its ID
     if not self._morango_source_id:
         self._morango_source_id = Certificate.generate_root_certificate(FULL_FACILITY).id
     return self._morango_source_id
Exemplo n.º 16
0
class NetworkSyncConnectionTestCase(TestCase):
    def setUp(self):
        self.profile = "facilitydata"

        self.root_scope_def = ScopeDefinition.objects.create(
            id="rootcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="mainpartition",
            description="Root cert for ${mainpartition}.",
            read_filter_template="",
            write_filter_template="",
            read_write_filter_template="${mainpartition}",
        )

        self.subset_scope_def = ScopeDefinition.objects.create(
            id="subcert",
            profile=self.profile,
            version=1,
            primary_scope_param_key="",
            description=
            "Subset cert under ${mainpartition} for ${subpartition}.",
            read_filter_template="${mainpartition}",
            write_filter_template="${mainpartition}:${subpartition}",
            read_write_filter_template="",
        )

        self.root_cert = Certificate.generate_root_certificate(
            self.root_scope_def.id)

        self.subset_cert = Certificate(
            parent=self.root_cert,
            profile=self.profile,
            scope_definition=self.subset_scope_def,
            scope_version=self.subset_scope_def.version,
            scope_params=json.dumps({
                "mainpartition": self.root_cert.id,
                "subpartition": "abracadabra"
            }),
            private_key=Key(),
        )
        self.root_cert.sign_certificate(self.subset_cert)
        self.subset_cert.save()

        self.controller = MorangoProfileController('facilitydata')
        self.network_connection = self.controller.create_network_connection(
            '127.0.0.1')

    @mock_patch_decorator
    def test_creating_sync_session_successful(self):
        self.assertEqual(SyncSession.objects.filter(active=True).count(), 0)
        NetworkSyncConnection._request.return_value.json.return_value = {
            'signature': 'sig',
            'local_fsic': '{}'
        }
        self.network_connection.create_sync_session(self.subset_cert,
                                                    self.root_cert)
        self.assertEqual(SyncSession.objects.filter(active=True).count(), 1)

    @mock_patch_decorator
    def test_creating_sync_session_cert_fails_to_verify(self):
        Certificate.verify.return_value = False
        with self.assertRaises(CertificateSignatureInvalid):
            self.network_connection.create_sync_session(
                self.subset_cert, self.root_cert)

    @mock_patch_decorator
    def test_get_remote_certs(self):
        # mock certs being returned by server
        certs = self.subset_cert.get_ancestors(include_self=True)
        cert_serialized = json.dumps(
            CertificateSerializer(certs, many=True).data)
        NetworkSyncConnection._request.return_value.json.return_value = json.loads(
            cert_serialized)

        # we want to see if the models are created (not saved) successfully
        remote_certs = self.network_connection.get_remote_certificates('abc')
        self.assertSetEqual(set(certs), set(remote_certs))

    @mock_patch_decorator
    def test_csr(self):
        # mock a "signed" cert being returned by server
        cert_serialized = json.dumps(
            CertificateSerializer(self.subset_cert).data)
        NetworkSyncConnection._request.return_value.json.return_value = json.loads(
            cert_serialized)
        self.subset_cert.delete()

        # we only want to make sure the "signed" cert is saved
        with mock.patch.object(Key,
                               "get_private_key_string",
                               return_value=self.subset_cert.private_key.
                               get_private_key_string()):
            self.network_connection.certificate_signing_request(
                self.root_cert, '', '')
        self.assertTrue(
            Certificate.objects.filter(
                id=json.loads(cert_serialized)['id']).exists())

    @mock_patch_decorator
    def test_get_cert_chain(self):
        # mock a cert chain being returned by server
        certs = self.subset_cert.get_ancestors(include_self=True)
        original_cert_count = certs.count()
        cert_serialized = json.dumps(
            CertificateSerializer(certs, many=True).data)
        NetworkSyncConnection._request.return_value.json.return_value = json.loads(
            cert_serialized)
        Certificate.objects.all().delete()

        # we only want to make sure the cert chain is saved
        self.network_connection._get_certificate_chain(certs[1])
        self.assertEqual(Certificate.objects.count(), original_cert_count)
Exemplo n.º 17
0
    def create_sync_session(self, client_cert, server_cert):
        # if server cert does not exist locally, retrieve it from server
        if not Certificate.objects.filter(id=server_cert.id).exists():
            cert_chain_response = self._get_certificate_chain(server_cert)

            # upon receiving cert chain from server, we attempt to save the chain into our records
            Certificate.save_certificate_chain(cert_chain_response.json(),
                                               expected_last_id=server_cert.id)

        # request the server for a one-time-use nonce
        nonce_resp = self._get_nonce()
        nonce = json.loads(nonce_resp.content.decode())["id"]

        # if no hostname then url is actually an ip
        url = urlparse(self.base_url)
        hostname = url.hostname or self.base_url
        port = url.port or (80 if url.scheme == 'http' else 443)

        # prepare the data to send in the syncsession creation request
        data = {
            "id":
            uuid.uuid4().hex,
            "server_certificate_id":
            server_cert.id,
            "client_certificate_id":
            client_cert.id,
            "profile":
            client_cert.profile,
            "certificate_chain":
            json.dumps(
                CertificateSerializer(
                    client_cert.get_ancestors(include_self=True),
                    many=True).data),
            "connection_path":
            self.base_url,
            "instance":
            json.dumps(
                InstanceIDSerializer(
                    InstanceIDModel.get_or_create_current_instance()[0]).data),
            "nonce":
            nonce,
            "client_ip":
            _get_client_ip_for_server(hostname, port),
            "server_ip":
            _get_server_ip(hostname),
        }

        # sign the nonce/ID combo to attach to the request
        message = "{nonce}:{id}".format(**data)
        data["signature"] = client_cert.sign(message)

        # Sync Session creation request
        session_resp = self._create_sync_session(data)

        # check that the nonce/id were properly signed by the server cert
        if not server_cert.verify(message,
                                  session_resp.json().get("signature")):
            raise CertificateSignatureInvalid()

        # build the data to be used for creating our own syncsession
        data = {
            "id":
            data['id'],
            "start_timestamp":
            timezone.now(),
            "last_activity_timestamp":
            timezone.now(),
            "active":
            True,
            "is_server":
            False,
            "client_certificate":
            client_cert,
            "server_certificate":
            server_cert,
            "profile":
            client_cert.profile,
            "connection_kind":
            "network",
            "connection_path":
            self.base_url,
            "client_ip":
            data['client_ip'],
            "server_ip":
            data['server_ip'],
            "client_instance":
            json.dumps(
                InstanceIDSerializer(
                    InstanceIDModel.get_or_create_current_instance()[0]).data),
            "server_instance":
            session_resp.json().get("server_instance") or "{}",
        }
        sync_session = SyncSession.objects.create(**data)

        return SyncClient(self, sync_session)