8
8
https://github.com/aosp-mirror/platform_system_core/blob/c55fab4a59cfa461857c6a61d8a0f1ae4591900c/libcrypto_utils/android_pubkey.c
9
9
10
10
typedef struct RSAPublicKey {
11
- // Modulus length. This must be ANDROID_PUBKEY_MODULUS_SIZE .
11
+ // Modulus length. This must be ANDROID_PUBKEY_MODULUS_SIZE_WORDS .
12
12
uint32_t modulus_size_words;
13
13
14
14
// Precomputed montgomery parameter: -1 / n[0] mod 2^32
28
28
from __future__ import print_function
29
29
30
30
import os
31
- import six
32
31
import base64
33
32
import socket
34
33
import struct
40
39
# Size of an RSA modulus such as an encrypted block or a signature.
41
40
ANDROID_PUBKEY_MODULUS_SIZE = (2048 // 8 )
42
41
42
+ # Python representation of "struct RSAPublicKey":
43
+ ANDROID_PUBKEY_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
+
52
+
43
53
# Size of an encoded RSA key.
44
54
ANDROID_PUBKEY_ENCODED_SIZE = \
45
55
(3 * 4 + 2 * ANDROID_PUBKEY_MODULUS_SIZE )
52
62
def _to_bytes (n , length , endianess = 'big' ):
53
63
"""partial python2 compatibility with int.to_bytes
54
64
https://stackoverflow.com/a/20793663"""
55
- if six . PY2 :
65
+ if not hasattr ( n , 'to_bytes' ) :
56
66
h = '{:x}' .format (n )
57
67
s = ('0' * (len (h ) % 2 ) + h ).zfill (length * 2 ).decode ('hex' )
58
68
return s if endianess == 'big' else s [::- 1 ]
@@ -71,7 +81,12 @@ def decode_pubkey(public_key):
71
81
modulus = reversed (key_struct [2 : 2 + ANDROID_PUBKEY_MODULUS_SIZE ])
72
82
rr = reversed (key_struct [2 + ANDROID_PUBKEY_MODULUS_SIZE :
73
83
2 + 2 * ANDROID_PUBKEY_MODULUS_SIZE ])
74
- exponent = key_struct [- 1 ]
84
+
85
+ key_struct = struct .unpack (ANDROID_PUBKEY_STRUCT , binary_key_data )
86
+ modulus_size_words , n0inv , modulus_bytes , rr_bytes , exponent = key_struct
87
+ assert modulus_size_words == ANDROID_PUBKEY_MODULUS_SIZE_WORDS # Verify modulus length
88
+ modulus = reversed (modulus_bytes )
89
+ rr = reversed (rr_bytes )
75
90
print ('modulus_size_words:' , hex (modulus_size_words ))
76
91
print ('n0inv:' , hex (n0inv ))
77
92
print ('modulus: ' , end = '' )
@@ -113,7 +128,17 @@ def encode_pubkey(private_key_path):
113
128
key_buffer += _to_bytes (rr , ANDROID_PUBKEY_MODULUS_SIZE , 'little' )
114
129
115
130
key_buffer += struct .pack ('<L' , key .e )
116
- return key_buffer
131
+
132
+ n_bytes = _to_bytes (key .n , ANDROID_PUBKEY_MODULUS_SIZE , 'little' )
133
+ rr_bytes = _to_bytes (rr , ANDROID_PUBKEY_MODULUS_SIZE , 'little' )
134
+ return struct .pack (
135
+ ANDROID_PUBKEY_STRUCT ,
136
+ ANDROID_PUBKEY_MODULUS_SIZE_WORDS ,
137
+ n0inv ,
138
+ n_bytes ,
139
+ rr_bytes ,
140
+ key .e
141
+ )
117
142
118
143
119
144
def get_user_info ():
0 commit comments