Initially dont encrypt communication, allows for efficient transmission of large blobs

This commit is contained in:
Kovid Goyal 2016-03-25 11:35:24 +05:30
parent e15f53cdf2
commit 7c050209e5
3 changed files with 63 additions and 36 deletions

View File

@ -6,9 +6,9 @@ from read_book.globals import set_boss
class Boss:
def __init__(self, gcm):
self.gcm = gcm
def __init__(self):
self.ready_sent = False
self.encrypted_communications = False
window.addEventListener('message', self.handle_message.bind(self), False)
window.addEventListener('load', def():
if not self.ready_sent:
@ -16,27 +16,37 @@ class Boss:
self.ready_sent = True
)
set_boss(self)
self.handlers = {
'keys':self.create_gcm.bind(self),
}
def handle_message(self, event):
if event.source is not window.parent:
return
data = event.data
if self.encrypted_communications:
try:
data = JSON.parse(self.gcm.decrypt(event.data))
data = JSON.parse(self.gcm_from_parent.decrypt(data))
except Exception as e:
print('Could not process message from parent:')
console.log(e)
if data.action is 'load':
pass
return
func = self.handlers[data.action]
if func:
func(data)
else:
print('Unknown action in message to iframe from parent: ' + data.action)
def create_gcm(self, data):
self.gcm_from_parent, self.gcm_to_parent = GCM(data.secret.subarray(0, 32)), GCM(data.secret.subarray(32))
def send_message(self, data):
data = self.gcm.encrypt(JSON.stringify(data))
if self.encrypted_communications:
data = self.gcm_to_parent.encrypt(JSON.stringify(data))
window.parent.postMessage(data, '*')
def init():
script = document.getElementById('bootstrap')
gcm = GCM(eval(script.getAttribute('data-key')))
script.removeAttribute('data-key')
script.parentNode.removeChild(script)
script = None
Boss(gcm)
script.parentNode.removeChild(script) # free up some memory
Boss()

View File

@ -11,18 +11,16 @@ def decode_url(x):
parts = x.split(',,')
return decode_component(parts[0]), decode_component(parts[1] or '')
secret_key = Uint8Array(32)
window.crypto.getRandomValues(secret_key)
secret_key_as_js = repr(secret_key)
gcm = GCM(secret_key)
secret = Uint8Array(64)
window.crypto.getRandomValues(secret)
gcm_to_iframe, gcm_from_iframe = GCM(secret.subarray(0, 32)), GCM(secret.subarray(32))
iframe_id = 'read-book-iframe'
def send_message(data):
data = gcm.encrypt(JSON.stringify(data))
document.getElementById(iframe_id).contentWindow.postMessage(data, '*')
def encrypt_message(data):
return gcm_to_iframe.encrypt(JSON.stringify(data))
def decrypt_message(data):
return JSON.parse(gcm.decrypt(data))
return JSON.parse(gcm_from_iframe.decrypt(data))
class Resource:

View File

@ -3,13 +3,13 @@
from elementmaker import E
from gettext import gettext as _
from read_book.resources import ResourceManager, secret_key_as_js, iframe_id, decrypt_message
from read_book.resources import ResourceManager, encrypt_message, iframe_id, decrypt_message, secret
LOADING_DOC = '''
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" id="bootstrap" data-key="__KEY__">
<script type="text/javascript" id="bootstrap">
__SCRIPT__
end_script
</head>
@ -35,8 +35,12 @@ class View:
self.src_doc = None
self.iframe_ready = False
self.pending_spine_load = None
self.encrypted_communications = False
self.create_src_doc()
window.addEventListener('message', self.handle_message.bind(self), False)
self.handlers = {
'ready': self.on_iframe_ready.bind(self),
}
@property
def iframe(self):
@ -47,21 +51,36 @@ class View:
self.ui.interface_data.main_js = None
self.src_doc = self.iframe.srcdoc = LOADING_DOC.replace(
'__SCRIPT__', iframe_script).replace(
'__BS__', _('Bootstrapping book reader...')).replace(
'__KEY__', 'new ' + secret_key_as_js)
'__BS__', _('Bootstrapping book reader...'))
def init_iframe(self, iframe_script):
self.encrypted_communications = False
self.iframe.srcdoc = self.src_doc
def send_message(self, data):
if self.encrypted_communications:
data = encrypt_message(data)
self.iframe.contentWindow.postMessage(data, '*')
def handle_message(self, event):
if event.source is not self.iframe.contentWindow:
return
data = event.data
if self.encrypted_communications:
try:
data = decrypt_message(event.data)
data = decrypt_message(data)
except Exception as e:
print('Could not process message from iframe:')
console.log(e)
if data.action is 'ready':
return
func = self.handlers[data.action]
if func:
func(data)
else:
print('Unknown action in message from iframe to parent: ' + data.action)
def on_iframe_ready(self, data):
self.send_message({'action':'keys', 'secret':secret})
self.iframe_ready = True
if self.pending_spine_load:
self.show_spine_item_stage2()