def encrypt_file(self, request, file_chunks, key=None): if (not self._key): self._key = key or decrypt_cipherkey(request, self) padded_file = file_chunks + ' ' * ((16 - (len(file_chunks) % 16)) % 16) a = AES.new(self._key) return a.encrypt(padded_file)
def encrypt_file(self, request, file_chunks, key=None): if (not self._key): self._key = key or decrypt_cipherkey(request, self) padded_file = file_chunks if isinstance(file_chunks, str): padded_file = file_chunks + ' ' * ((16 - (len(file_chunks) % 16)) % 16) else: assembled_file = ''.join(file_chunks) padded_file = [' ' for i in range((16 - (len(assembled_file) % 16)) % 16)] padded_file.insert(0, assembled_file) padded_file = ''.join(padded_file) a = AES.new(self._key) encrypted_data = a.encrypt(padded_file) """ name = '.'.join([settings.CONTAINER_PREFIX, "attachments"]) container = settings.CLOUDCONNECTION.create_container(name) file = container.create_object(self.uuid) retries = 2 while retries > 0: try: file.write(encrypted_data) retries = 0 except SSLError as e: retries -= 1 if(retries <= 0): raise e """ f = create_file('attachments/%s' % (self.uuid,)) if not f: raise IOError f.set_contents(encrypted_data) f.close()
def saveAttachmentsForForwardReferPdf(request, msg, exist_refer, ss): """ Save attachments when user forward a exist refer manually. :param request: request the key 'key' must be in request.session :param msg: message object which contain these attachments :param exist_refer: used for forwarding refer pdf Example:: { 'message_id': message_id(used for validating the refer), 'refer_id': refer_id } :param ss: sender's private key ss is used for decrypting exist attachments for mobile app. :returns: MessageAttachment list """ attachments = [] if exist_refer and msg: origin_message_id = exist_refer['message_id'] refer_id = exist_refer['refer_id'] refer = get_object_or_404(MessageRefer, uuid=refer_id, message__uuid=origin_message_id) clearkey = None if ss: clearkey = decrypt_cipherkey(request, refer, ss=ss) decrypt_file_str = refer.decrypt_file(request, key=clearkey) file_data = { 'name': 'refer.pdf', 'file_chunks': decrypt_file_str, 'size': len(decrypt_file_str), 'charset': '' } attachment = saveSingleAttachment(request, msg, file_data) attachments.append(attachment) return attachments
def decrypt(self, request, key, ivr=False): """ Decrypts and returns the url of the object. To get the URL, you need to use KMS.utils.decrypt_cipherkey. """ if (self._url): return self._url if (not self._key): if (not key and not request): raise Exception(_("Decryption requires either a key or the HttpRequest object!")) self._key = key or decrypt_cipherkey(request, self, ivr) # Mark the message as read. if (self.read_flag == False): self.read_flag = True self.read_timestamp = int(time.time()) self.save() a = AES.new(self._key) url = base64.b64decode(self.url) try: url = cPickle.loads(url) except Exception: raise KeyInvalidException() self._url = a.decrypt(url) return self._url
def get_file(self, request, response, key=None, ivr=False): """ Gets the attachment and properly stuffs it into the passed response, decrypting if appropriate. """ if (not self._key): self._key = key or decrypt_cipherkey(request, self, ivr) response['Cache-Control'] = 'no-cache' response['Content-Disposition'] = 'attachment; filename="%s"' % \ (self.decrypt_filename(request)) response['Content-Length'] = self.size """ name = '.'.join([settings.CONTAINER_PREFIX, "attachments"]) container = settings.CLOUDCONNECTION.create_container(name) file = container[self.uuid] """ f = get_file('attachments/%s' % (self.uuid,)) if not f: raise IOError data = f.read() f.close() if (self.encrypted): a = AES.new(self._key) data = a.decrypt(data).rstrip() response['Cache-Control'] = 'no-cache' response['Content-Disposition'] = 'attachment; filename="%s"' % \ (self.decrypt_filename(request)) response['Content-Length'] = len(data) response.write(data)
def getAttachmentLogic(request, message_id, attachment_id, ss=None): if (request.method != 'POST'): return err_GE002() attachment = get_object_or_404(MessageAttachment, message__uuid=message_id, uuid=attachment_id) message = attachment.message if ((message.sender and request.user.pk != message.sender.pk) and not ((request.user.pk,) in message.recipients.values_list('id') or (request.user.pk,) in message.ccs.values_list('id'))): return err403(request, err_msg="You don't seem to be a valid recipient for this file.") # Get/set up data for KMS. request.session['key'] = request.device_assn.secret try: clearkey = decrypt_cipherkey(request, attachment, ss=ss) except KeyInvalidException: return err_GE021() url = attachment.decrypt_url(request, key=clearkey) if (url[0:4] == 'file'): response = HttpResponse(content_type=attachment.content_type) attachment.get_file(request, response, key=clearkey) return response elif (url[0:4] == 'http'): # This is likely a fully qualified URL if (not attachment.encrypted): return HttpResponseRedirect(url) else: # Download and decrypt this attachment. pass else: raise Exception('A seemingly invalid URL has been stored: %s, for ' 'MessageAttachment %s.' % (url, attachment_id,))
def decrypt_file(self, request, key=None, ivr=False): key = key or decrypt_cipherkey(request, self, ivr) f = get_file('refer/pdf/%s' % (self.uuid,)) if f: data = f.read() f.close() a = AES.new(key) return a.decrypt(data).rstrip() return ''
def createReferFowarding(refers, request, sender, sender_role_user, refer_data=None, ss=None): """ create refer's forwarding :param request: request :param sender: message's sender as auth_user :param sender_role_user: message's sender as Provider/Office Staff/Broker :param refer_data: refer information dictionary :param ss: sender's private key api_secret and ss are used for decrypting pdf file. :returns: Message """ if refers: if not isinstance(refers, list): refers = [refers] for refer in refers: # forward refer pdf clearkey = decrypt_cipherkey(request, refer, ss=ss) pdf_data = refer.decrypt_file(request, key=clearkey) forward_recipients = refer_data['user_to_recipients'] forward_ccs = refer_data['user_cc_recipients'] if pdf_data and (forward_recipients or forward_ccs): file_data = { 'name': _('Refer Forwarding') + '.pdf', 'file_chunks': [pdf_data], 'size': len(pdf_data), 'charset': '' } forward_body = _(""" %s has forwarded you a refer, please see details in attachment. Best, DoctorCom """) % ' '.join([request.user.first_name, request.user.last_name]) forward_subject = u'Refer Forwarding' # refer_data must be None here, avoid infinite loop # TODO, test this logic carefully, when implement refer feature for app. forward_recipients = forward_recipients.split( ',') if forward_recipients else None forward_ccs = forward_ccs.split(',') if forward_ccs else None return createNewMessage(request, sender, sender_role_user, forward_recipients, forward_body, ccs=forward_ccs, subject=forward_subject, file_data_list=[file_data], refer_data=None)
def encrypt_url(self, request, url, key=None): if (not self._key): self._key = key or decrypt_cipherkey(request, self) padded_url = [' ' for i in range((16 - (len(url) % 16)) % 16)] padded_url.insert(0, url) padded_url = ''.join(padded_url) a = AES.new(self._key) self._url = a.encrypt(padded_url) self._url = cPickle.dumps(self._url) self.url = base64.b64encode(self._url)
def encrypt_filename(self, request, filename, key=None): if (not self._key): self._key = key or decrypt_cipherkey(request, self) filename = filename.encode('utf-8') padded_filename = [' ' for i in range((16 - (len(filename) % 16)) % 16)] padded_filename.insert(0, filename) padded_filename = ''.join(padded_filename) a = AES.new(self._key) self._filename = a.encrypt(padded_filename) self._filename = cPickle.dumps(self._filename) self.filename = base64.b64encode(self._filename)
def getReferPDFLogic(request, refer_id, ss=None): """ get_refer_pdf :param request: Request info :type request: django.core.handlers.wsgi.WSGIRequest :param refer_id: referall id :type refer_id: uuid :returns: django.http.HttpResponse -- the result in an HttpResonse object """ if (request.method != 'POST'): return err_GE002() form = MsgGetForm(request.POST) if (not form.is_valid()): return err_GE031(form) refer = get_object_or_404(MessageRefer, uuid=refer_id) message = refer.message if ((message.sender and request.user.pk != message.sender.pk) and not ((request.user.pk, ) in message.recipients.values_list('id') or (request.user.pk, ) in message.ccs.values_list('id'))): return err403( request, err_msg=_("You don't seem to be a valid recipient for this file.")) # special for mobile app api # Get/set up data for KMS. request.session['key'] = request.device_assn.secret try: clearkey = decrypt_cipherkey(request, refer, ss=ss) except KeyInvalidException: return err_GE021() try: response = refer.get_file(request, key=clearkey) return response except Exception as e: err_email_body = '\n'.join([ ('PDF file not exist!'), ''.join(['Server: ', settings.SERVER_ADDRESS]), ''.join(['Session: ', str(request.session.session_key)]), ''.join(['Message: ', (u'PDF file not exist in media/refer/pdf')]), ''.join(['Exception: ', str(e)]), ''.join(['Exception data: ', str(e.args)]), ]) mail_admins(_('PDF folder not exist'), err_email_body) raise Exception( _('A seemingly invalid URL has been stored for Refer Pdf.'))
def get_content_file(self, request, key=None, ivr=False): if (not self._key): self._key = key or decrypt_cipherkey(request, self, ivr) f = get_file('attachments/%s' % (self.uuid,)) if not f: raise IOError data = f.read() f.close() if (self.encrypted): a = AES.new(self._key) data = a.decrypt(data).rstrip() return data
def get_file_content(self, request, suffix, index, key=None, ivr=False): if (not self._key): self._key = key or decrypt_cipherkey(request, self, ivr) f = get_file('attachments/%s_dicom/%s_%d.%s' % ( self.attachment.uuid, self.attachment.uuid, index, suffix)) if not f: raise IOError data = f.read() f.close() a = AES.new(self._key) data = a.decrypt(data).rstrip() return data
def decrypt_url(self, request, key=None, ivr=False): if (self._url): return self._url if (not self._key): self._key = key or decrypt_cipherkey(request, self, ivr) a = AES.new(self._key) url = base64.b64decode(self.url) try: url = cPickle.loads(url) except Exception: raise KeyInvalidException() self._url = a.decrypt(url).rstrip() return self._url
def decrypt_filename(self, request, key=None, ivr=False): if (self._filename): return self._filename if (not self._key): self._key = key or decrypt_cipherkey(request, self, ivr) a = AES.new(self._key) filename = base64.b64decode(self.filename) try: filename = cPickle.loads(filename) except Exception: raise KeyInvalidException() self._filename = a.decrypt(filename).rstrip().decode('utf-8') return self._filename
def checkDicom(request, message_id, attachment_id, secret=None): """ Check dicom jpg exsit or not. :param request: The HTTP request :type request: django.core.handlers.wsgi.WSGIRequest :param message_id: Message uuid :type message_id: uuid :param attachment_id: Attachment uuid :type attachment_id: uuid :param secret: secret for decrypting jpg(used for app). :type secret: string :returns: JSON Data :raises: Exception """ attachment = get_object_or_404(MessageAttachment, message__uuid=message_id, uuid=attachment_id) exist = True try: attachment_dicom = MessageAttachmentDicom.objects.get( attachment=attachment) exist = attachment_dicom.check_files( ) and attachment_dicom.check_keys_for_users() except MessageAttachmentDicom.DoesNotExist: exist = False send_if_not_exist = False if "send_if_not_exist" in request.POST: send_if_not_exist = True if send_if_not_exist and not exist: clearkey = None if secret: # request must has the right 'key' value in session clearkey = decrypt_cipherkey(request, attachment, ss=secret) file_display_name = get_attachment_filename(request, attachment, ss=secret) decrypt_str = attachment.get_content_file(request, key=clearkey) thread.start_new_thread(sendToDicomServer, ({ "name": file_display_name, "token": attachment.uuid, "content": decrypt_str }, )) return {"exist": exist}
def getReferPDFLogic(request, refer_id, ss=None): """ get_refer_pdf :param request: Request info :type request: django.core.handlers.wsgi.WSGIRequest :param refer_id: referall id :type refer_id: uuid :returns: django.http.HttpResponse -- the result in an HttpResonse object """ if (request.method != 'POST'): return err_GE002() form = MsgGetForm(request.POST) if (not form.is_valid()): return err_GE031(form) refer = get_object_or_404(MessageRefer, uuid=refer_id) message = refer.message if ((message.sender and request.user.pk != message.sender.pk) and not ((request.user.pk,) in message.recipients.values_list('id') or (request.user.pk,) in message.ccs.values_list('id'))): return err403(request, err_msg=_("You don't seem to be a valid recipient for this file.")) # special for mobile app api # Get/set up data for KMS. request.session['key'] = request.device_assn.secret try: clearkey = decrypt_cipherkey(request, refer, ss=ss) except KeyInvalidException: return err_GE021() try: response = refer.get_file(request, key=clearkey) return response except Exception as e: err_email_body = '\n'.join([ ('PDF file not exist!'), ''.join(['Server: ', settings.SERVER_ADDRESS]), ''.join(['Session: ', str(request.session.session_key)]), ''.join(['Message: ', (u'PDF file not exist in media/refer/pdf')]), ''.join(['Exception: ', str(e)]), ''.join(['Exception data: ', str(e.args)]), ]) mail_admins(_('PDF folder not exist'), err_email_body) raise Exception(_('A seemingly invalid URL has been stored for Refer Pdf.'))
def getDicomJPG(request, message_id, attachment_id, index, secret=None): """ Handles download dicom jpg request. :param request: The HTTP request :type request: django.core.handlers.wsgi.WSGIRequest :param message_id: Message uuid :type message_id: uuid :param attachment_id: Attachment uuid :type attachment_id: uuid :param index: index of dicom jpg :type index: int :param secret: secret for decrypting jpg(used for app). :type secret: string :returns: django.http.HttpResponse -- the result in an HttpResonse object :raises: Exception """ attachment = get_object_or_404(MessageAttachment, message__uuid=message_id, uuid=attachment_id) attachment_dicom = get_object_or_404(MessageAttachmentDicom, attachment=attachment) if int(index) >= attachment_dicom.jpg_count: raise Http404 message = attachment.message if ((message.sender and request.user.pk != message.sender.pk) and not ((request.user.pk, ) in message.recipients.values_list('id') or (request.user.pk, ) in message.ccs.values_list('id'))): return err403( request, err_msg=_("You don't seem to be a valid recipient for this file.")) clearkey = None if secret: # request must has the right 'key' value in session clearkey = decrypt_cipherkey(request, attachment_dicom, ss=secret) index = int(index) return attachment_dicom.get_dicom_jpg_to_response(request, index, key=clearkey)
def createReferFowarding(refers, request, sender, sender_role_user, refer_data=None, ss=None): """ create refer's forwarding :param request: request :param sender: message's sender as auth_user :param sender_role_user: message's sender as Provider/Office Staff/Broker :param refer_data: refer information dictionary :param ss: sender's private key api_secret and ss are used for decrypting pdf file. :returns: Message """ if refers: if not isinstance(refers, list): refers = [refers] for refer in refers: # forward refer pdf clearkey = decrypt_cipherkey(request, refer, ss=ss) pdf_data = refer.decrypt_file(request, key=clearkey) forward_recipients = refer_data['user_to_recipients'] forward_ccs = refer_data['user_cc_recipients'] if pdf_data and (forward_recipients or forward_ccs): file_data = { 'name': _('Refer Forwarding') + '.pdf', 'file_chunks': [pdf_data], 'size': len(pdf_data), 'charset': '' } forward_body = _(""" %s has forwarded you a refer, please see details in attachment. Best, DoctorCom """) % ' '.join([request.user.first_name, request.user.last_name]) forward_subject = u'Refer Forwarding' # refer_data must be None here, avoid infinite loop # TODO, test this logic carefully, when implement refer feature for app. forward_recipients = forward_recipients.split(',') if forward_recipients else None forward_ccs = forward_ccs.split(',') if forward_ccs else None return createNewMessage(request, sender, sender_role_user, forward_recipients, forward_body, ccs=forward_ccs, subject=forward_subject, file_data_list=[file_data], refer_data=None)
def getAttachmentLogic(request, message_id, attachment_id, ss=None): if (request.method != 'POST'): return err_GE002() attachment = get_object_or_404(MessageAttachment, message__uuid=message_id, uuid=attachment_id) message = attachment.message if ((message.sender and request.user.pk != message.sender.pk) and not ((request.user.pk, ) in message.recipients.values_list('id') or (request.user.pk, ) in message.ccs.values_list('id'))): return err403( request, err_msg="You don't seem to be a valid recipient for this file.") # Get/set up data for KMS. request.session['key'] = request.device_assn.secret try: clearkey = decrypt_cipherkey(request, attachment, ss=ss) except KeyInvalidException: return err_GE021() url = attachment.decrypt_url(request, key=clearkey) if (url[0:4] == 'file'): response = HttpResponse(content_type=attachment.content_type) attachment.get_file(request, response, key=clearkey) return response elif (url[0:4] == 'http'): # This is likely a fully qualified URL if (not attachment.encrypted): return HttpResponseRedirect(url) else: # Download and decrypt this attachment. pass else: raise Exception('A seemingly invalid URL has been stored: %s, for ' 'MessageAttachment %s.' % ( url, attachment_id, ))
def saveAttachmentsUsingExistAttachments(request, msg, exist_attchments, ss): """ save attachments using exist attachments(message forwarding can use this function) :param request: key 'key' must be in request.session :param msg: message object which contain these attachments :param exist_attchments: attachment information, structure like Example:: { 'message_id': message_id(used for validating the attachment), 'attachment_ids': attachment_id list } :param ss: senders private key ss is used for decrypting exist attachments for mobile app. :returns: MessageAttachment list :raises: Http404, KeyInvalidException """ attachments = [] # compose exist file using exist attachment if exist_attchments: message_id = exist_attchments['message_id'] attachment_ids = exist_attchments['attachment_ids'] for attachment_id in attachment_ids: attachment = get_object_or_404(MessageAttachment, message__uuid=message_id, uuid=attachment_id) clearkey = None if ss: clearkey = decrypt_cipherkey(request, attachment, ss=ss) content = attachment.get_content_file(request, key=clearkey) file_name = get_attachment_filename(request, attachment, ss) file_data = { 'name': file_name, 'file_chunks': [content], 'size': attachment.size, 'charset': attachment.charset } attachment = saveSingleAttachment(request, msg, file_data) attachments.append(attachment) return attachments
def decrypt(self, request, key=None, ivr=False): if (self.clear_data): return self.clear_data key = key or decrypt_cipherkey(request, self, ivr) if (not self.user): self.user = request.user # TODO, make this function have single responsibility, move the # following two lines to read_message if (self.read_flag == False): self.read_flag = True a = AES.new(key) body = base64.b64decode(self.body) try: body = cPickle.loads(body) except Exception: raise KeyInvalidException() self.clear_data = a.decrypt(body).rstrip().decode('utf-8') # strip trailing spaces return self.clear_data
def encrypt_files(self, request, src_files, suffix, key=None): if src_files: if (not self._key): self._key = key or decrypt_cipherkey(request, self) if not isinstance(src_files, list): src_files = [src_files] for index in xrange(len(src_files)): src_file = src_files[index] content = src_file.read() assembled_file = ''.join(content) padded_file = [' ' for i in range((16 - (len(assembled_file) % 16)) % 16)] padded_file.insert(0, assembled_file) padded_file = ''.join(padded_file) a = AES.new(self._key) encrypted_data = a.encrypt(padded_file) saved_file = create_file('attachments/%s_dicom/%s_%d.%s' % ( self.attachment.uuid, self.attachment.uuid, index, suffix)) if not saved_file: raise IOError saved_file.set_contents(encrypted_data) saved_file.close()
def test_secure_message(self): cleartext = "I drive a Dodge Stratus, don't tell anyone." c = self.client response = c.post('/login/', { 'username': '******', 'password': '******' }) c.COOKIES = {'ss': response.cookies['ss'].value} self.assertEqual(response.status_code, 302) # just extra verification we can get user from django auth c.user = authenticate(username='******', password='******') c.user = MHLUser.objects.get(id=c.user.id) # verify we are logged in self.assertEqual(c.session['_auth_user_id'], c.user.id) # These should match: self.assertEqual(b64encode(get_user_key(c)), b64encode(strengthen_key('healme'))) # query our KeyPair we created in setup opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) with self.assertRaises(AttributeError): encrypt_object(str, {}, "boo") # NOTE: encrypt_object leaks m._key but using that fact to test this for now msg = encrypt_object(SecureTestMessage, {}, cleartext) # verify keys don't exist: exists = check_keys_exist_for_users(msg, [c.user]) self.assertEqual(exists, False) with self.assertRaises(Exception): gen_keys_for_users(msg, [c.user], None, None) gen_keys_for_users(msg, [c.user], None, c, ivr=True) # does both default & ivr # test with cache gen_keys_for_users(msg, [self.drbob], msg._key, c) msg._key = None # uncache, test with diff user gen_keys_for_users(msg, [self.adminguy], None, c) # verify keys do exist: exists = check_keys_exist_for_users(msg, [c.user]) self.assertEqual(exists, True) exists = check_keys_exist_for_users(msg, [c.user, self.adminguy]) self.assertEqual(exists, True) # time passes by .... now decrypt it encobj = EncryptedObject.objects.get_object(msg, opub) # do step by step instead of helper decrypt_object opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) upriv = UserPrivateKey.objects.get(user=c.user, opub=opub) creds = get_user_key(c, response.cookies['ss'].value) clearkey = encobj.decrypt_cipherkey(upriv, creds) self.assertEqual(clearkey, decrypt_cipherkey(c, msg)) # now call the object's decrypt method decrypted_cleartext = msg.decrypt(c, clearkey) # verify they do match after decryption self.assertTrue(decrypted_cleartext == cleartext) # now try calling top level helper decrypt_object and verify decrypted_cleartext = decrypt_object(c, msg) # verify they do match after decryption self.assertTrue(decrypted_cleartext == cleartext) # try calling encobj's decrypt with invalid creds with self.assertRaises(KeyInvalidException): decrypt_object(c, msg, ss="malarkey") # create encrypted object without encrypting msg2 = encrypt_object(SecureTestMessage, {}) self.assertTrue(len(msg2.ciphertext) == 0) # now logout, we can alternatively call c.post('/logout/') response = c.logout() self.assertTrue('_auth_user_id' not in c.session) # test str rep of opub self.assertEqual( unicode(opub), u"%s, key type: %s" % (c.user, RSA_TYPES[opub.keytype]), opub) ### tickle the admin interface with all the objs created in this UT ### response = c.post('/login/', { 'username': '******', 'password': '******' }) user = authenticate(username='******', password='******') opub = OwnerPublicKey.objects.get_pubkey(owner=user) url = reverse("admin:%s_%s_change" % (opub._meta.app_label, opub._meta.module_name), args=[opub.id]) response = c.get(url) upriv = opub.userprivatekey.get() url = reverse("admin:%s_%s_change" % (upriv._meta.app_label, upriv._meta.module_name), args=[upriv.id]) response = c.get(url) encobj = EncryptedObject.objects.all()[0] url = reverse("admin:%s_%s_change" % (encobj._meta.app_label, encobj._meta.module_name), args=[encobj.id]) response = c.get(url) response = c.logout()
def getDicomInfo( request, message_id, attachment_id, dicom_jpg_func_name='MHLogin.DoctorCom.Messaging.views_dicom.dicom_view_jpg', secret=None): """ Handles dicom viewer. :param request: The HTTP request :type request: django.core.handlers.wsgi.WSGIRequest :param message_id: Message uuid :type message_id: uuid :param attachment_id: Attachment uuid :type attachment_id: uuid :param dicom_jpg_func_name: function full path for getting dicom jpg file. :type dicom_jpg_func_name: string :param secret: secret for decrypting jpg(used for app). :type secret: string :returns: dict :raises: Exception """ attachment = get_object_or_404(MessageAttachment, message__uuid=message_id, uuid=attachment_id) attachment_dicom = get_object_or_404(MessageAttachmentDicom, attachment=attachment) message = attachment.message if ((message.sender and request.user.pk != message.sender.pk) and not ((request.user.pk, ) in message.recipients.values_list('id') or (request.user.pk, ) in message.ccs.values_list('id'))): return err403( request, err_msg=_("You don't seem to be a valid recipient for this file.")) clearkey = None if secret: # request must has the right 'key' value in session clearkey = decrypt_cipherkey(request, attachment_dicom, ss=secret) dicom_xml_string = attachment_dicom.get_xml_content(request, 0, key=clearkey) jpg_count = attachment_dicom.jpg_count xml = StringIO.StringIO(dicom_xml_string) doc = ET.parse(xml) context = {} context["jpgs"] = [{ 'index': i, 'url': reverse(dicom_jpg_func_name, kwargs={ 'message_id': message_id, 'attachment_id': attachment_id, 'index': i }) } for i in xrange(jpg_count)] if jpg_count else [] context["jpg_count"] = jpg_count context["message_id"] = message_id context["attachment_id"] = attachment_id context["patient"] = { "name": getDicomInfoFromXML(doc, "00100010"), "id": getDicomInfoFromXML(doc, "00100020"), "birthday": getDicomInfoFromXML(doc, "00100030"), "sex": getDicomInfoFromXML(doc, "00100040"), "weight": getDicomInfoFromXML(doc, "00101030"), } acq_date = getDicomInfoFromXML(doc, "00080022") acquisition_date = acq_date[:4] + '-' + acq_date[4:6] + '-' + acq_date[6:8] \ if 8 == len(acq_date) else acq_date acq_time = getDicomInfoFromXML(doc, "00080032") acquisition_time = acq_time[:2] + ':' + acq_time[2:4] + ':' + acq_time[4:6] \ if 13 == len(acq_time) else acq_time context["dcm"] = { "file_name": get_attachment_filename(request, attachment, ss=secret), "acquisition_date": acquisition_date, "acquisition_time": acquisition_time, "institution_name": getDicomInfoFromXML(doc, "00080080"), "station_name": getDicomInfoFromXML(doc, "00081010"), "study_id": getDicomInfoFromXML(doc, "00200010"), "study_description": getDicomInfoFromXML(doc, "00081030"), "series_number": getDicomInfoFromXML(doc, "00200011"), "series_description": getDicomInfoFromXML(doc, "0008103E"), "slice_thickness": getDicomInfoFromXML(doc, "00180050"), "slice_location": getDicomInfoFromXML(doc, "00201041"), } return context
def get_attachment_filename(request, attachment, ss=None): clearkey = None if ss: clearkey = decrypt_cipherkey(request, attachment, ss=ss) return attachment.decrypt_filename(request, key=clearkey)
def test_secure_message(self): cleartext = "I drive a Dodge Stratus, don't tell anyone." c = self.client response = c.post('/login/', {'username': '******', 'password': '******'}) c.COOKIES = {'ss': response.cookies['ss'].value} self.assertEqual(response.status_code, 302) # just extra verification we can get user from django auth c.user = authenticate(username='******', password='******') c.user = MHLUser.objects.get(id=c.user.id) # verify we are logged in self.assertEqual(c.session['_auth_user_id'], c.user.id) # These should match: self.assertEqual(b64encode(get_user_key(c)), b64encode(strengthen_key('healme'))) # query our KeyPair we created in setup opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) with self.assertRaises(AttributeError): encrypt_object(str, {}, "boo") # NOTE: encrypt_object leaks m._key but using that fact to test this for now msg = encrypt_object(SecureTestMessage, {}, cleartext) # verify keys don't exist: exists = check_keys_exist_for_users(msg, [c.user]) self.assertEqual(exists, False) with self.assertRaises(Exception): gen_keys_for_users(msg, [c.user], None, None) gen_keys_for_users(msg, [c.user], None, c, ivr=True) # does both default & ivr # test with cache gen_keys_for_users(msg, [self.drbob], msg._key, c) msg._key = None # uncache, test with diff user gen_keys_for_users(msg, [self.adminguy], None, c) # verify keys do exist: exists = check_keys_exist_for_users(msg, [c.user]) self.assertEqual(exists, True) exists = check_keys_exist_for_users(msg, [c.user, self.adminguy]) self.assertEqual(exists, True) # time passes by .... now decrypt it encobj = EncryptedObject.objects.get_object(msg, opub) # do step by step instead of helper decrypt_object opub = OwnerPublicKey.objects.get_pubkey(owner=c.user) upriv = UserPrivateKey.objects.get(user=c.user, opub=opub) creds = get_user_key(c, response.cookies['ss'].value) clearkey = encobj.decrypt_cipherkey(upriv, creds) self.assertEqual(clearkey, decrypt_cipherkey(c, msg)) # now call the object's decrypt method decrypted_cleartext = msg.decrypt(c, clearkey) # verify they do match after decryption self.assertTrue(decrypted_cleartext == cleartext) # now try calling top level helper decrypt_object and verify decrypted_cleartext = decrypt_object(c, msg) # verify they do match after decryption self.assertTrue(decrypted_cleartext == cleartext) # try calling encobj's decrypt with invalid creds with self.assertRaises(KeyInvalidException): decrypt_object(c, msg, ss="malarkey") # create encrypted object without encrypting msg2 = encrypt_object(SecureTestMessage, {}) self.assertTrue(len(msg2.ciphertext) == 0) # now logout, we can alternatively call c.post('/logout/') response = c.logout() self.assertTrue('_auth_user_id' not in c.session) # test str rep of opub self.assertEqual(unicode(opub), u"%s, key type: %s" % (c.user, RSA_TYPES[opub.keytype]), opub) ### tickle the admin interface with all the objs created in this UT ### response = c.post('/login/', {'username': '******', 'password': '******'}) user = authenticate(username='******', password='******') opub = OwnerPublicKey.objects.get_pubkey(owner=user) url = reverse("admin:%s_%s_change" % (opub._meta.app_label, opub._meta.module_name), args=[opub.id]) response = c.get(url) upriv = opub.userprivatekey.get() url = reverse("admin:%s_%s_change" % (upriv._meta.app_label, upriv._meta.module_name), args=[upriv.id]) response = c.get(url) encobj = EncryptedObject.objects.all()[0] url = reverse("admin:%s_%s_change" % (encobj._meta.app_label, encobj._meta.module_name), args=[encobj.id]) response = c.get(url) response = c.logout()
def _get_attachment_filename(request, attachment, ss=None): request.session['key'] = request.device_assn.secret clearkey = decrypt_cipherkey(request, attachment, ss=ss) return attachment.decrypt_filename(request, key=clearkey)