move key loading to verifier code
Add an option to verifier_test to load keys from a file, the way the recovery does. Change-Id: Icba0e391164f2c1a9fefeab4b0bcb878e91d17b4
This commit is contained in:
-100
@@ -174,106 +174,6 @@ try_update_binary(const char *path, ZipArchive *zip, int* wipe_cache) {
|
||||
return INSTALL_SUCCESS;
|
||||
}
|
||||
|
||||
// Reads a file containing one or more public keys as produced by
|
||||
// DumpPublicKey: this is an RSAPublicKey struct as it would appear
|
||||
// as a C source literal, eg:
|
||||
//
|
||||
// "{64,0xc926ad21,{1795090719,...,-695002876},{-857949815,...,1175080310}}"
|
||||
//
|
||||
// For key versions newer than the original 2048-bit e=3 keys
|
||||
// supported by Android, the string is preceded by a version
|
||||
// identifier, eg:
|
||||
//
|
||||
// "v2 {64,0xc926ad21,{1795090719,...,-695002876},{-857949815,...,1175080310}}"
|
||||
//
|
||||
// (Note that the braces and commas in this example are actual
|
||||
// characters the parser expects to find in the file; the ellipses
|
||||
// indicate more numbers omitted from this example.)
|
||||
//
|
||||
// The file may contain multiple keys in this format, separated by
|
||||
// commas. The last key must not be followed by a comma.
|
||||
//
|
||||
// Returns NULL if the file failed to parse, or if it contain zero keys.
|
||||
static RSAPublicKey*
|
||||
load_keys(const char* filename, int* numKeys) {
|
||||
RSAPublicKey* out = NULL;
|
||||
*numKeys = 0;
|
||||
|
||||
FILE* f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
LOGE("opening %s: %s\n", filename, strerror(errno));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
++*numKeys;
|
||||
out = (RSAPublicKey*)realloc(out, *numKeys * sizeof(RSAPublicKey));
|
||||
RSAPublicKey* key = out + (*numKeys - 1);
|
||||
|
||||
char start_char;
|
||||
if (fscanf(f, " %c", &start_char) != 1) goto exit;
|
||||
if (start_char == '{') {
|
||||
// a version 1 key has no version specifier.
|
||||
key->exponent = 3;
|
||||
} else if (start_char == 'v') {
|
||||
int version;
|
||||
if (fscanf(f, "%d {", &version) != 1) goto exit;
|
||||
if (version == 2) {
|
||||
key->exponent = 65537;
|
||||
} else {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (fscanf(f, " %i , 0x%x , { %u",
|
||||
&(key->len), &(key->n0inv), &(key->n[0])) != 3) {
|
||||
goto exit;
|
||||
}
|
||||
if (key->len != RSANUMWORDS) {
|
||||
LOGE("key length (%d) does not match expected size\n", key->len);
|
||||
goto exit;
|
||||
}
|
||||
for (i = 1; i < key->len; ++i) {
|
||||
if (fscanf(f, " , %u", &(key->n[i])) != 1) goto exit;
|
||||
}
|
||||
if (fscanf(f, " } , { %u", &(key->rr[0])) != 1) goto exit;
|
||||
for (i = 1; i < key->len; ++i) {
|
||||
if (fscanf(f, " , %u", &(key->rr[i])) != 1) goto exit;
|
||||
}
|
||||
fscanf(f, " } } ");
|
||||
|
||||
// if the line ends in a comma, this file has more keys.
|
||||
switch (fgetc(f)) {
|
||||
case ',':
|
||||
// more keys to come.
|
||||
break;
|
||||
|
||||
case EOF:
|
||||
done = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGE("unexpected character between keys\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
LOGI("read key e=%d\n", key->exponent);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return out;
|
||||
|
||||
exit:
|
||||
if (f) fclose(f);
|
||||
free(out);
|
||||
*numKeys = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
really_install_package(const char *path, int* wipe_cache)
|
||||
{
|
||||
|
||||
+102
@@ -179,9 +179,111 @@ int verify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKey
|
||||
LOGI("whole-file signature verified against key %d\n", i);
|
||||
free(eocd);
|
||||
return VERIFY_SUCCESS;
|
||||
} else {
|
||||
LOGI("failed to verify against key %d\n", i);
|
||||
}
|
||||
}
|
||||
free(eocd);
|
||||
LOGE("failed to verify whole-file signature\n");
|
||||
return VERIFY_FAILURE;
|
||||
}
|
||||
|
||||
// Reads a file containing one or more public keys as produced by
|
||||
// DumpPublicKey: this is an RSAPublicKey struct as it would appear
|
||||
// as a C source literal, eg:
|
||||
//
|
||||
// "{64,0xc926ad21,{1795090719,...,-695002876},{-857949815,...,1175080310}}"
|
||||
//
|
||||
// For key versions newer than the original 2048-bit e=3 keys
|
||||
// supported by Android, the string is preceded by a version
|
||||
// identifier, eg:
|
||||
//
|
||||
// "v2 {64,0xc926ad21,{1795090719,...,-695002876},{-857949815,...,1175080310}}"
|
||||
//
|
||||
// (Note that the braces and commas in this example are actual
|
||||
// characters the parser expects to find in the file; the ellipses
|
||||
// indicate more numbers omitted from this example.)
|
||||
//
|
||||
// The file may contain multiple keys in this format, separated by
|
||||
// commas. The last key must not be followed by a comma.
|
||||
//
|
||||
// Returns NULL if the file failed to parse, or if it contain zero keys.
|
||||
RSAPublicKey*
|
||||
load_keys(const char* filename, int* numKeys) {
|
||||
RSAPublicKey* out = NULL;
|
||||
*numKeys = 0;
|
||||
|
||||
FILE* f = fopen(filename, "r");
|
||||
if (f == NULL) {
|
||||
LOGE("opening %s: %s\n", filename, strerror(errno));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
++*numKeys;
|
||||
out = (RSAPublicKey*)realloc(out, *numKeys * sizeof(RSAPublicKey));
|
||||
RSAPublicKey* key = out + (*numKeys - 1);
|
||||
|
||||
char start_char;
|
||||
if (fscanf(f, " %c", &start_char) != 1) goto exit;
|
||||
if (start_char == '{') {
|
||||
// a version 1 key has no version specifier.
|
||||
key->exponent = 3;
|
||||
} else if (start_char == 'v') {
|
||||
int version;
|
||||
if (fscanf(f, "%d {", &version) != 1) goto exit;
|
||||
if (version == 2) {
|
||||
key->exponent = 65537;
|
||||
} else {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (fscanf(f, " %i , 0x%x , { %u",
|
||||
&(key->len), &(key->n0inv), &(key->n[0])) != 3) {
|
||||
goto exit;
|
||||
}
|
||||
if (key->len != RSANUMWORDS) {
|
||||
LOGE("key length (%d) does not match expected size\n", key->len);
|
||||
goto exit;
|
||||
}
|
||||
for (i = 1; i < key->len; ++i) {
|
||||
if (fscanf(f, " , %u", &(key->n[i])) != 1) goto exit;
|
||||
}
|
||||
if (fscanf(f, " } , { %u", &(key->rr[0])) != 1) goto exit;
|
||||
for (i = 1; i < key->len; ++i) {
|
||||
if (fscanf(f, " , %u", &(key->rr[i])) != 1) goto exit;
|
||||
}
|
||||
fscanf(f, " } } ");
|
||||
|
||||
// if the line ends in a comma, this file has more keys.
|
||||
switch (fgetc(f)) {
|
||||
case ',':
|
||||
// more keys to come.
|
||||
break;
|
||||
|
||||
case EOF:
|
||||
done = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGE("unexpected character between keys\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
LOGI("read key e=%d\n", key->exponent);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return out;
|
||||
|
||||
exit:
|
||||
if (f) fclose(f);
|
||||
free(out);
|
||||
*numKeys = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
*/
|
||||
int verify_file(const char* path, const RSAPublicKey *pKeys, unsigned int numKeys);
|
||||
|
||||
RSAPublicKey* load_keys(const char* filename, int* numKeys);
|
||||
|
||||
#define VERIFY_SUCCESS 0
|
||||
#define VERIFY_FAILURE 1
|
||||
|
||||
|
||||
+8
-3
@@ -129,21 +129,26 @@ class FakeUI : public RecoveryUI {
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 2 && argc != 3) {
|
||||
fprintf(stderr, "Usage: %s [-f4] <package>\n", argv[0]);
|
||||
if (argc < 2 || argc > 4) {
|
||||
fprintf(stderr, "Usage: %s [-f4 | -file <keys>] <package>\n", argv[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
RSAPublicKey* key = &test_key;
|
||||
int num_keys = 1;
|
||||
++argv;
|
||||
if (strcmp(argv[0], "-f4") == 0) {
|
||||
++argv;
|
||||
key = &test_f4_key;
|
||||
} else if (strcmp(argv[0], "-file") == 0) {
|
||||
++argv;
|
||||
key = load_keys(argv[0], &num_keys);
|
||||
++argv;
|
||||
}
|
||||
|
||||
ui = new FakeUI();
|
||||
|
||||
int result = verify_file(*argv, key, 1);
|
||||
int result = verify_file(*argv, key, num_keys);
|
||||
if (result == VERIFY_SUCCESS) {
|
||||
printf("SUCCESS\n");
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user