Merge branch 'readonly-p4-master'
This commit is contained in:
		 Doug Zongker
					Doug Zongker
				
			
				
					committed by
					
						 The Android Open Source Project
						The Android Open Source Project
					
				
			
			
				
	
			
			
			
					commit
					275acbe70a
				
			
							
								
								
									
										13
									
								
								Android.mk
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								Android.mk
									
									
									
									
									
								
							| @@ -33,21 +33,8 @@ LOCAL_STATIC_LIBRARIES := libminzip libunz libamend libmtdutils libmincrypt | ||||
| LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libpng libcutils | ||||
| LOCAL_STATIC_LIBRARIES += libstdc++ libc | ||||
|  | ||||
| # Specify a C-includable file containing the OTA public keys. | ||||
| # This is built in config/Makefile. | ||||
| # *** THIS IS A TOTAL HACK; EXECUTABLES MUST NOT CHANGE BETWEEN DIFFERENT | ||||
| #     PRODUCTS/BUILD TYPES. *** | ||||
| # TODO: make recovery read the keys from an external file. | ||||
| RECOVERY_INSTALL_OTA_KEYS_INC := \ | ||||
| 	$(call intermediates-dir-for,PACKAGING,ota_keys_inc)/keys.inc | ||||
| # Let install.c say #include "keys.inc" | ||||
| LOCAL_C_INCLUDES += $(dir $(RECOVERY_INSTALL_OTA_KEYS_INC)) | ||||
|  | ||||
| include $(BUILD_EXECUTABLE) | ||||
|  | ||||
| # Depend on the generated keys.inc containing the OTA public keys. | ||||
| $(intermediates)/install.o: $(RECOVERY_INSTALL_OTA_KEYS_INC) | ||||
|  | ||||
| include $(commands_recovery_local_path)/minui/Android.mk | ||||
|  | ||||
| endif   # TARGET_ARCH == arm | ||||
|   | ||||
							
								
								
									
										96
									
								
								install.c
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								install.c
									
									
									
									
									
								
							| @@ -31,12 +31,8 @@ | ||||
| #include "roots.h" | ||||
| #include "verifier.h" | ||||
|  | ||||
| /* List of public keys */ | ||||
| static const RSAPublicKey keys[] = { | ||||
| #include "keys.inc" | ||||
| }; | ||||
|  | ||||
| #define ASSUMED_UPDATE_SCRIPT_NAME  "META-INF/com/google/android/update-script" | ||||
| #define PUBLIC_KEYS_FILE "/res/keys" | ||||
|  | ||||
| static const ZipEntry * | ||||
| find_update_script(ZipArchive *zip) | ||||
| @@ -114,7 +110,8 @@ handle_update_script(ZipArchive *zip, const ZipEntry *update_script_entry) | ||||
| } | ||||
|  | ||||
| static int | ||||
| handle_update_package(const char *path, ZipArchive *zip) | ||||
| handle_update_package(const char *path, ZipArchive *zip, | ||||
|                       const RSAPublicKey *keys, int numKeys) | ||||
| { | ||||
|     // Give verification half the progress bar... | ||||
|     ui_print("Verifying update package...\n"); | ||||
| @@ -122,7 +119,7 @@ handle_update_package(const char *path, ZipArchive *zip) | ||||
|             VERIFICATION_PROGRESS_FRACTION, | ||||
|             VERIFICATION_PROGRESS_TIME); | ||||
|  | ||||
|     if (!verify_jar_signature(zip, keys, sizeof(keys) / sizeof(keys[0]))) { | ||||
|     if (!verify_jar_signature(zip, keys, numKeys)) { | ||||
|         LOGE("Verification failed\n"); | ||||
|         return INSTALL_CORRUPT; | ||||
|     } | ||||
| @@ -147,6 +144,80 @@ handle_update_package(const char *path, ZipArchive *zip) | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| // 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}}" | ||||
| // | ||||
| // (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 = realloc(out, *numKeys * sizeof(RSAPublicKey)); | ||||
|         RSAPublicKey* key = out + (*numKeys - 1); | ||||
|         if (fscanf(f, " { %i , %i , { %i", | ||||
|                    &(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, " , %i", &(key->n[i])) != 1) goto exit; | ||||
|         } | ||||
|         if (fscanf(f, " } , { %i", &(key->rr[0])) != 1) goto exit; | ||||
|         for (i = 1; i < key->len; ++i) { | ||||
|             if (fscanf(f, " , %i", &(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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fclose(f); | ||||
|     return out; | ||||
|  | ||||
| exit: | ||||
|     if (f) fclose(f); | ||||
|     free(out); | ||||
|     *numKeys = 0; | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| int | ||||
| install_package(const char *root_path) | ||||
| { | ||||
| @@ -169,6 +240,14 @@ install_package(const char *root_path) | ||||
|     ui_print("Opening update package...\n"); | ||||
|     LOGI("Update file path: %s\n", path); | ||||
|  | ||||
|     int numKeys; | ||||
|     RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); | ||||
|     if (loadedKeys == NULL) { | ||||
|         LOGE("Failed to load keys\n"); | ||||
|         return INSTALL_CORRUPT; | ||||
|     } | ||||
|     LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); | ||||
|  | ||||
|     /* Try to open the package. | ||||
|      */ | ||||
|     ZipArchive zip; | ||||
| @@ -180,7 +259,8 @@ install_package(const char *root_path) | ||||
|  | ||||
|     /* Verify and install the contents of the package. | ||||
|      */ | ||||
|     int status = handle_update_package(path, &zip); | ||||
|     int status = handle_update_package(path, &zip, loadedKeys, numKeys); | ||||
|     mzCloseZipArchive(&zip); | ||||
|     free(loadedKeys); | ||||
|     return status; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user