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
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