summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--applypatch/applypatch.c27
-rw-r--r--install.cpp100
-rw-r--r--minzip/Zip.c6
-rw-r--r--verifier.cpp102
-rw-r--r--verifier.h2
-rw-r--r--verifier_test.cpp11
6 files changed, 138 insertions, 110 deletions
diff --git a/applypatch/applypatch.c b/applypatch/applypatch.c
index 7b8a010e3..69f8633ab 100644
--- a/applypatch/applypatch.c
+++ b/applypatch/applypatch.c
@@ -585,6 +585,14 @@ int CacheSizeCheck(size_t bytes) {
}
}
+static void print_short_sha1(const uint8_t sha1[SHA_DIGEST_SIZE]) {
+ int i;
+ const char* hex = "0123456789abcdef";
+ for (i = 0; i < 4; ++i) {
+ putchar(hex[(sha1[i]>>4) & 0xf]);
+ putchar(hex[sha1[i] & 0xf]);
+ }
+}
// This function applies binary patches to files in a way that is safe
// (the original file is not touched until we have the desired
@@ -620,7 +628,7 @@ int applypatch(const char* source_filename,
char** const patch_sha1_str,
Value** patch_data,
Value* bonus_data) {
- printf("\napplying patch to %s\n", source_filename);
+ printf("patch %s: ", source_filename);
if (target_filename[0] == '-' &&
target_filename[1] == '\0') {
@@ -646,8 +654,9 @@ int applypatch(const char* source_filename,
if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
// The early-exit case: the patch was already applied, this file
// has the desired hash, nothing for us to do.
- printf("\"%s\" is already target; no patch needed\n",
- target_filename);
+ printf("already ");
+ print_short_sha1(target_sha1);
+ putchar('\n');
free(source_file.data);
return 0;
}
@@ -769,8 +778,10 @@ static int GenerateTarget(FileContents* source_file,
enough_space =
(free_space > (256 << 10)) && // 256k (two-block) minimum
(free_space > (target_size * 3 / 2)); // 50% margin of error
- printf("target %ld bytes; free space %ld bytes; retry %d; enough %d\n",
- (long)target_size, (long)free_space, retry, enough_space);
+ if (!enough_space) {
+ printf("target %ld bytes; free space %ld bytes; retry %d; enough %d\n",
+ (long)target_size, (long)free_space, retry, enough_space);
+ }
}
if (!enough_space) {
@@ -805,7 +816,7 @@ static int GenerateTarget(FileContents* source_file,
unlink(source_filename);
size_t free_space = FreeSpaceForFile(target_fs);
- printf("(now %ld bytes free for target)\n", (long)free_space);
+ printf("(now %ld bytes free for target) ", (long)free_space);
}
}
@@ -901,6 +912,10 @@ static int GenerateTarget(FileContents* source_file,
if (memcmp(current_target_sha1, target_sha1, SHA_DIGEST_SIZE) != 0) {
printf("patch did not produce expected sha1\n");
return 1;
+ } else {
+ printf("now ");
+ print_short_sha1(target_sha1);
+ putchar('\n');
}
if (output < 0) {
diff --git a/install.cpp b/install.cpp
index b8f478130..0f3298f1d 100644
--- a/install.cpp
+++ b/install.cpp
@@ -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)
{
diff --git a/minzip/Zip.c b/minzip/Zip.c
index c87f038c5..439e5d9cd 100644
--- a/minzip/Zip.c
+++ b/minzip/Zip.c
@@ -985,6 +985,7 @@ bool mzExtractRecursive(const ZipArchive *pArchive,
unsigned int i;
bool seenMatch = false;
int ok = true;
+ int extractCount = 0;
for (i = 0; i < pArchive->numEntries; i++) {
ZipEntry *pEntry = pArchive->pEntries + i;
if (pEntry->fileNameLen < zipDirLen) {
@@ -1150,13 +1151,16 @@ bool mzExtractRecursive(const ZipArchive *pArchive,
break;
}
- LOGD("Extracted file \"%s\"\n", targetFile);
+ LOGV("Extracted file \"%s\"\n", targetFile);
+ ++extractCount;
}
}
if (callback != NULL) callback(targetFile, cookie);
}
+ LOGD("Extracted %d file(s)\n", extractCount);
+
free(helper.buf);
free(zpath);
diff --git a/verifier.cpp b/verifier.cpp
index 1c5a41d1b..5f4c981e5 100644
--- a/verifier.cpp
+++ b/verifier.cpp
@@ -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;
+}
diff --git a/verifier.h b/verifier.h
index 1bdfca6dd..e9ef3b722 100644
--- a/verifier.h
+++ b/verifier.h
@@ -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
diff --git a/verifier_test.cpp b/verifier_test.cpp
index 01d092680..79c55783d 100644
--- a/verifier_test.cpp
+++ b/verifier_test.cpp
@@ -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;