Skip to content

Commit ef893cb

Browse files
committed
repl_installer: Upload hashes as file
Now, the upload and install are completely separate. This means you can now upload all files without pybricksdev and just call install from the REPL.
1 parent 69ea0e1 commit ef893cb

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

pybricksdev/repl_installer.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ async def install(self, firmware_archive_path):
119119
# Read Pybricks dual boot build
120120
archive = ZipFile(firmware_archive_path)
121121
pybricks_blob = archive.open('firmware-dual-boot-base.bin').read()
122-
pybricks_hash = sha256(pybricks_blob).digest()
122+
pybricks_hash = sha256(pybricks_blob).hexdigest().encode('utf-8')
123123

124124
# Upload firmware file.
125125
await self.upload_file('_pybricks/firmware.bin', pybricks_blob)
@@ -129,12 +129,16 @@ async def install(self, firmware_archive_path):
129129

130130
# Upload installation script.
131131
with open('pybricksdev/resources/install_pybricks.py', "rb") as install_script:
132-
await self.upload_file('_pybricks/install.py', install_script.read())
132+
install_blob = install_script.read()
133+
install_hash = sha256(install_blob).hexdigest().encode('utf-8')
134+
await self.upload_file('_pybricks/install.py', install_blob)
135+
136+
# Upload file with hashes to verify uploaded file integrity.
137+
await self.upload_file('_pybricks/hash.txt', pybricks_hash + b"\n" + install_hash + b"\n")
133138

134139
# Run the installation script
135140
self.print_output = True
136-
await self.exec_line("from _pybricks.install import install")
137-
await self.exec_line("install({0})".format(repr(pybricks_hash)))
141+
await self.exec_line("from _pybricks.install import install; install()")
138142

139143
# Remove installation files
140144
await self.exec_line("import uos")

pybricksdev/resources/install_pybricks.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -112,27 +112,42 @@ def get_padding(padding_length):
112112
yield FF * (padding_length % BLOCK_WRITE_SIZE)
113113

114114

115-
def install(pybricks_hash):
116-
"""Main installation routine."""
115+
def get_file_size_and_hash(path):
116+
"""Gets file size and sha256 hash."""
117117

118-
# Start firmware binary verification.
119-
print("Starting installation script.")
120-
print("Checking uploaded firmware file.")
121-
pybricks_hash_calc = uhashlib.sha256()
122-
pybricks_size = 0
118+
hash_calc = uhashlib.sha256()
119+
size = 0
123120

124-
with open("_pybricks/firmware.bin", "rb") as pybricks_bin_file:
121+
with open(path, "rb") as bin_file:
125122
data = b'START'
126123
while len(data) > 0:
127-
data = pybricks_bin_file.read(128)
128-
pybricks_size += len(data)
129-
pybricks_hash_calc.update(data)
124+
data = bin_file.read(128)
125+
size += len(data)
126+
hash_calc.update(data)
127+
128+
return (size, ubinascii.hexlify(hash_calc.digest()).decode())
129+
130+
131+
def install():
132+
"""Main installation routine."""
133+
134+
print("Starting installation script.")
135+
136+
# Get hash of uploaded files.
137+
print("Checking installation files.")
138+
pybricks_size, pybricks_hash_calc = get_file_size_and_hash("_pybricks/firmware.bin")
139+
script_size, script_hash_calc = get_file_size_and_hash("_pybricks/install.py")
140+
141+
# Read what the hashes should be.
142+
with open("_pybricks/hash.txt") as hash_file:
143+
pybricks_hash_read = hash_file.readline().strip()
144+
script_hash_read = hash_file.readline().strip()
130145

131-
# Compare hash against given value.
132-
if pybricks_hash_calc.digest() == pybricks_hash:
133-
print("Firmware checksum is correct!")
146+
# Check if hashes match.
147+
if pybricks_hash_read == pybricks_hash_calc and script_hash_read == script_hash_calc:
148+
print("Files looking good!")
134149
else:
135-
print("Bad firmware file. Stopping.")
150+
print("The installation files are corrupt.")
136151
return
137152

138153
# Get firmware information.

0 commit comments

Comments
 (0)