Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.

Commit 0a791b9

Browse files
joeleongHalastra
andcommitted
Refactor android_pubkey.py struct usage
With help from @Halastra suggestions from code review of #144 - Define ANDROID_RSAPUBLICKEY_STRUCT - Remove use of six package - Fix some flake8 warnings Co-Authored-By: Halastra <[email protected]>
1 parent efa2a49 commit 0a791b9

File tree

2 files changed

+29
-30
lines changed

2 files changed

+29
-30
lines changed

adb/android_pubkey.py

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@
88
https://github.com/aosp-mirror/platform_system_core/blob/c55fab4a59cfa461857c6a61d8a0f1ae4591900c/libcrypto_utils/android_pubkey.c
99
1010
typedef struct RSAPublicKey {
11-
// Modulus length. This must be ANDROID_PUBKEY_MODULUS_SIZE.
11+
// Modulus length. This must be ANDROID_PUBKEY_MODULUS_SIZE_WORDS
1212
uint32_t modulus_size_words;
1313
1414
// Precomputed montgomery parameter: -1 / n[0] mod 2^32
1515
uint32_t n0inv;
1616
17-
// RSA modulus as a little-endian array.
17+
// RSA modulus as a little-endian array
1818
uint8_t modulus[ANDROID_PUBKEY_MODULUS_SIZE];
1919
20-
// Montgomery parameter R^2 as a little-endian array of little-endian words.
20+
// Montgomery parameter R^2 as a little-endian array of little-endian words
2121
uint8_t rr[ANDROID_PUBKEY_MODULUS_SIZE];
2222
2323
// RSA modulus: 3 or 65537
@@ -28,7 +28,6 @@
2828
from __future__ import print_function
2929

3030
import os
31-
import six
3231
import base64
3332
import socket
3433
import struct
@@ -40,10 +39,16 @@
4039
# Size of an RSA modulus such as an encrypted block or a signature.
4140
ANDROID_PUBKEY_MODULUS_SIZE = (2048 // 8)
4241

43-
# Size of an encoded RSA key.
44-
ANDROID_PUBKEY_ENCODED_SIZE = \
45-
(3 * 4 + 2 * ANDROID_PUBKEY_MODULUS_SIZE)
46-
# (3 * sizeof(uint32_t) + 2 * ANDROID_PUBKEY_MODULUS_SIZE)
42+
# Python representation of "struct RSAPublicKey":
43+
ANDROID_RSAPUBLICKEY_STRUCT = (
44+
'<' # Little-endian
45+
'L' # uint32_t modulus_size_words;
46+
'L' # uint32_t n0inv;
47+
'{modulus_size}s' # uint8_t modulus[ANDROID_PUBKEY_MODULUS_SIZE];
48+
'{modulus_size}s' # uint8_t rr[ANDROID_PUBKEY_MODULUS_SIZE];
49+
'L' # uint32_t exponent;
50+
).format(modulus_size=ANDROID_PUBKEY_MODULUS_SIZE)
51+
4752

4853
# Size of the RSA modulus in words.
4954
ANDROID_PUBKEY_MODULUS_SIZE_WORDS = (ANDROID_PUBKEY_MODULUS_SIZE // 4)
@@ -52,7 +57,7 @@
5257
def _to_bytes(n, length, endianess='big'):
5358
"""partial python2 compatibility with int.to_bytes
5459
https://stackoverflow.com/a/20793663"""
55-
if six.PY2:
60+
if not hasattr(n, 'to_bytes'):
5661
h = '{:x}'.format(n)
5762
s = ('0' * (len(h) % 2) + h).zfill(length * 2).decode('hex')
5863
return s if endianess == 'big' else s[::-1]
@@ -62,16 +67,11 @@ def _to_bytes(n, length, endianess='big'):
6267
def decode_pubkey(public_key):
6368
"""decodes a public RSA key stored in Android's custom binary format"""
6469
binary_key_data = base64.b64decode(public_key)
65-
key_struct = struct.unpack(('<LL' +
66-
'B' * ANDROID_PUBKEY_MODULUS_SIZE +
67-
'B' * ANDROID_PUBKEY_MODULUS_SIZE +
68-
'L'), binary_key_data)
69-
modulus_size_words = key_struct[0]
70-
n0inv = key_struct[1]
71-
modulus = reversed(key_struct[2: 2 + ANDROID_PUBKEY_MODULUS_SIZE])
72-
rr = reversed(key_struct[2 + ANDROID_PUBKEY_MODULUS_SIZE:
73-
2 + 2 * ANDROID_PUBKEY_MODULUS_SIZE])
74-
exponent = key_struct[-1]
70+
modulus_size_words, n0inv, modulus_bytes, rr_bytes, exponent = \
71+
struct.unpack(ANDROID_RSAPUBLICKEY_STRUCT, binary_key_data)
72+
assert modulus_size_words == ANDROID_PUBKEY_MODULUS_SIZE_WORDS
73+
modulus = reversed(modulus_bytes)
74+
rr = reversed(rr_bytes)
7575
print('modulus_size_words:', hex(modulus_size_words))
7676
print('n0inv:', hex(n0inv))
7777
print('modulus: ', end='')
@@ -83,15 +83,13 @@ def decode_pubkey(public_key):
8383

8484
def decode_pubkey_file(public_key_path):
8585
with open(public_key_path, 'rb') as fd:
86-
decode_pubkey(fd.read())
86+
decode_pubkey(fd.read())
8787

8888

8989
def encode_pubkey(private_key_path):
9090
"""encodes a public RSA key into Android's custom binary format"""
9191
key = Crypto.PublicKey.RSA.import_key(private_key_path)
9292

93-
# Store the modulus size.
94-
key_buffer = struct.pack('<L', ANDROID_PUBKEY_MODULUS_SIZE_WORDS)
9593
# Compute and store n0inv = -1 / N[0] mod 2^32.
9694
# BN_set_bit(r32, 32)
9795
r32 = 1 << 32
@@ -101,19 +99,21 @@ def encode_pubkey(private_key_path):
10199
n0inv = Crypto.Util.number.inverse(n0inv, r32)
102100
# BN_sub(n0inv, r32, n0inv)
103101
n0inv = r32 - n0inv
104-
key_buffer += struct.pack('<L', n0inv)
105102

106-
# Store the modulus.
107-
key_buffer += _to_bytes(key.n, ANDROID_PUBKEY_MODULUS_SIZE, 'little')
108103
# Compute and store rr = (2^(rsa_size)) ^ 2 mod N.
109104
# BN_set_bit(rr, ANDROID_PUBKEY_MODULUS_SIZE * 8)
110105
rr = 1 << (ANDROID_PUBKEY_MODULUS_SIZE * 8)
111106
# BN_mod_sqr(rr, rr, key->n, ctx)
112107
rr = (rr ** 2) % key.n
113-
key_buffer += _to_bytes(rr, ANDROID_PUBKEY_MODULUS_SIZE, 'little')
114108

115-
key_buffer += struct.pack('<L', key.e)
116-
return key_buffer
109+
return struct.pack(
110+
ANDROID_RSAPUBLICKEY_STRUCT,
111+
ANDROID_PUBKEY_MODULUS_SIZE_WORDS,
112+
n0inv,
113+
_to_bytes(key.n, ANDROID_PUBKEY_MODULUS_SIZE, 'little'),
114+
_to_bytes(rr, ANDROID_PUBKEY_MODULUS_SIZE, 'little'),
115+
key.e
116+
)
117117

118118

119119
def get_user_info():
@@ -135,7 +135,7 @@ def write_public_keyfile(private_key_path, public_key_path):
135135
private_key = private_key_file.read()
136136

137137
public_key = encode_pubkey(private_key)
138-
assert len(public_key) == ANDROID_PUBKEY_ENCODED_SIZE
138+
assert len(public_key) == struct.calcsize(ANDROID_RSAPUBLICKEY_STRUCT)
139139
with open(public_key_path, 'wb') as public_key_file:
140140
public_key_file.write(base64.b64encode(public_key))
141141
public_key_file.write(get_user_info().encode())

setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
install_requires = [
5757
'libusb1>=1.0.16',
5858
'pycryptodome',
59-
'six',
6059
rsa_signer_library
6160
],
6261

0 commit comments

Comments
 (0)