am 64dbf369: (-s ours) Fake version number for AOSP master - do not merge
* commit '64dbf369a864bb34c029366ff177a8239002a8ee':
Fake version number for AOSP master - do not merge
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 30ebdea..6d43bc0 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -168,15 +168,12 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
-# So... funny story. Recall when I mentioned above the
-# "JB MR2" thing? I didn't mean that. In fact, while I was
-# writing JB MR, my head was thinking 4.2, and things got
-# cross-wired as they are wont to do, and we ended up with
-# JB MR2, which didn't actually exist.
-#
-# Well, didn't exist then.
-#
-# Now it does. Say hi, JB MR2!
+# And on to KLP...
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
+
+# KLP now based off API 18.
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
diff --git a/core/base_rules.mk b/core/base_rules.mk
index f0a6398..f92cf6a 100644
--- a/core/base_rules.mk
+++ b/core/base_rules.mk
@@ -98,23 +98,27 @@
endif
ifneq (true,$(LOCAL_UNINSTALLABLE_MODULE))
-ifdef LOCAL_IS_HOST_MODULE
- partition_tag :=
-else
-ifeq (true,$(LOCAL_PROPRIETARY_MODULE))
- partition_tag := _VENDOR
-else
- # The definition of should-install-to-system will be different depending
- # on which goal (e.g., sdk or just droid) is being built.
- partition_tag := $(if $(call should-install-to-system,$(LOCAL_MODULE_TAGS)),,_DATA)
-endif
-endif
-
LOCAL_MODULE_PATH := $(strip $(LOCAL_MODULE_PATH))
ifeq ($(LOCAL_MODULE_PATH),)
- LOCAL_MODULE_PATH := $($(my_prefix)OUT$(partition_tag)_$(LOCAL_MODULE_CLASS))
+ ifdef LOCAL_IS_HOST_MODULE
+ partition_tag :=
+ else
+ ifeq (true,$(LOCAL_PROPRIETARY_MODULE))
+ partition_tag := _VENDOR
+ else
+ # The definition of should-install-to-system will be different depending
+ # on which goal (e.g., sdk or just droid) is being built.
+ partition_tag := $(if $(call should-install-to-system,$(LOCAL_MODULE_TAGS)),,_DATA)
+ endif
+ endif
+ install_path_var := $(my_prefix)OUT$(partition_tag)_$(LOCAL_MODULE_CLASS)
+ ifeq (true,$(LOCAL_PRIVILEGED_MODULE))
+ install_path_var := $(install_path_var)_PRIVILEGED
+ endif
+
+ LOCAL_MODULE_PATH := $($(install_path_var))
ifeq ($(strip $(LOCAL_MODULE_PATH)),)
- $(error $(LOCAL_PATH): unhandled LOCAL_MODULE_CLASS "$(LOCAL_MODULE_CLASS)")
+ $(error $(LOCAL_PATH): unhandled install path "$(install_path_var)")
endif
endif
endif # not LOCAL_UNINSTALLABLE_MODULE
diff --git a/core/build_id.mk b/core/build_id.mk
index ffff91e..40bb35d 100644
--- a/core/build_id.mk
+++ b/core/build_id.mk
@@ -23,7 +23,7 @@
# (like "TC1-RC5"). It must be a single word, and is
# capitalized by convention.
#
-BUILD_ID := JB_MR2
+BUILD_ID := MASTER
# DISPLAY_BUILD_NUMBER should only be set for development branches,
# If set, the BUILD_NUMBER (cl) is appended to the BUILD_ID for
diff --git a/core/clear_vars.mk b/core/clear_vars.mk
index 8d84814..11f7f84 100644
--- a/core/clear_vars.mk
+++ b/core/clear_vars.mk
@@ -122,6 +122,7 @@
LOCAL_PROTOC_FLAGS:=
LOCAL_NO_CRT:=
LOCAL_PROPRIETARY_MODULE:=
+LOCAL_PRIVILEGED_MODULE:=
LOCAL_MODULE_OWNER:=
LOCAL_CTS_TEST_PACKAGE:=
LOCAL_CTS_TEST_RUNNER:=
diff --git a/core/combo/arch/arm/armv7-a-neon.mk b/core/combo/arch/arm/armv7-a-neon.mk
index f2c1ca7..057ce93 100644
--- a/core/combo/arch/arm/armv7-a-neon.mk
+++ b/core/combo/arch/arm/armv7-a-neon.mk
@@ -9,12 +9,16 @@
ifeq ($(strip $(TARGET_CPU_VARIANT)), cortex-a15)
arch_variant_cflags := -mcpu=cortex-a15
else
+ifeq ($(strip $(TARGET_CPU_VARIANT)),cortex-a8)
+ arch_variant_cflags := -mcpu=cortex-a8
+else
ifeq ($(strip $(TARGET_CPU_VARIANT)),cortex-a7)
arch_variant_cflags := -mcpu=cortex-a7
else
arch_variant_cflags := -march=armv7-a
endif
endif
+endif
arch_variant_cflags += \
-mfloat-abi=softfp \
diff --git a/core/envsetup.mk b/core/envsetup.mk
index f861586..8ac437e 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -196,6 +196,7 @@
TARGET_OUT_SHARED_LIBRARIES:= $(TARGET_OUT)/lib
TARGET_OUT_JAVA_LIBRARIES:= $(TARGET_OUT)/framework
TARGET_OUT_APPS:= $(TARGET_OUT)/app
+TARGET_OUT_APPS_PRIVILEGED := $(TARGET_OUT)/priv-app
TARGET_OUT_KEYLAYOUT := $(TARGET_OUT)/usr/keylayout
TARGET_OUT_KEYCHARS := $(TARGET_OUT)/usr/keychars
TARGET_OUT_ETC := $(TARGET_OUT)/etc
@@ -211,6 +212,7 @@
TARGET_OUT_DATA_KEYCHARS := $(TARGET_OUT_KEYCHARS)
TARGET_OUT_DATA_ETC := $(TARGET_OUT_ETC)
TARGET_OUT_DATA_NATIVE_TESTS := $(TARGET_OUT_DATA)/nativetest
+TARGET_OUT_DATA_FAKE := $(TARGET_OUT_DATA)/fake_packages
TARGET_OUT_CACHE := $(PRODUCT_OUT)/cache
diff --git a/core/main.mk b/core/main.mk
index e03801c..55de80f 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -183,6 +183,7 @@
$(error stop)
endif
+ifndef BUILD_EMULATOR
ifeq (darwin,$(HOST_OS))
GCC_REALPATH = $(realpath $(shell which $(HOST_CC)))
ifneq ($(findstring llvm-gcc,$(GCC_REALPATH)),)
@@ -199,10 +200,11 @@
else # HOST_OS is not darwin
BUILD_EMULATOR := true
endif # HOST_OS is darwin
+endif
$(shell echo 'VERSIONS_CHECKED := $(VERSION_CHECK_SEQUENCE_NUMBER)' \
> $(OUT_DIR)/versions_checked.mk)
-$(shell echo 'BUILD_EMULATOR := $(BUILD_EMULATOR)' \
+$(shell echo 'BUILD_EMULATOR ?= $(BUILD_EMULATOR)' \
>> $(OUT_DIR)/versions_checked.mk)
endif
diff --git a/core/pathmap.mk b/core/pathmap.mk
index b76e0ed..78d4f66 100644
--- a/core/pathmap.mk
+++ b/core/pathmap.mk
@@ -34,7 +34,6 @@
frameworks-native:frameworks/native/include \
graphics:external/skia/include/core \
libc:bionic/libc/include \
- libdrm1:frameworks/base/media/libdrm/mobile1/include \
libhardware:hardware/libhardware/include \
libhardware_legacy:hardware/libhardware_legacy/include \
libhost:build/libs/host/include \
diff --git a/core/version_defaults.mk b/core/version_defaults.mk
index b9e1456..8fa5081 100644
--- a/core/version_defaults.mk
+++ b/core/version_defaults.mk
@@ -41,7 +41,7 @@
# which is the version that we reveal to the end user.
# Update this value when the platform version changes (rather
# than overriding it somewhere else). Can be an arbitrary string.
- PLATFORM_VERSION := 4.3.2.1.000.000
+ PLATFORM_VERSION := KeyLimePie
endif
ifeq "" "$(PLATFORM_SDK_VERSION)"
@@ -59,7 +59,7 @@
ifeq "" "$(PLATFORM_VERSION_CODENAME)"
# This is the current development code-name, if the build is not a final
# release build. If this is a final release build, it is simply "REL".
- PLATFORM_VERSION_CODENAME := REL
+ PLATFORM_VERSION_CODENAME := KeyLimePie
endif
ifeq "" "$(DEFAULT_APP_TARGET_SDK)"
diff --git a/libs/host/Android.mk b/libs/host/Android.mk
index 9900f59..74afa55 100644
--- a/libs/host/Android.mk
+++ b/libs/host/Android.mk
@@ -2,8 +2,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- CopyFile.c \
- pseudolocalize.cpp
+ CopyFile.c
ifeq ($(HOST_OS),cygwin)
LOCAL_CFLAGS += -DWIN32_EXE
diff --git a/libs/host/include/host/pseudolocalize.h b/libs/host/include/host/pseudolocalize.h
deleted file mode 100644
index 94cb034..0000000
--- a/libs/host/include/host/pseudolocalize.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef HOST_PSEUDOLOCALIZE_H
-#define HOST_PSEUDOLOCALIZE_H
-
-#include <string>
-
-std::string pseudolocalize_string(const std::string& source);
-
-#endif // HOST_PSEUDOLOCALIZE_H
-
diff --git a/libs/host/pseudolocalize.cpp b/libs/host/pseudolocalize.cpp
deleted file mode 100644
index a2b3c2f..0000000
--- a/libs/host/pseudolocalize.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-#include <host/pseudolocalize.h>
-
-using namespace std;
-
-static const char*
-pseudolocalize_char(char c)
-{
- switch (c) {
- case 'a': return "\xc4\x83";
- case 'b': return "\xcf\x84";
- case 'c': return "\xc4\x8b";
- case 'd': return "\xc4\x8f";
- case 'e': return "\xc4\x99";
- case 'f': return "\xc6\x92";
- case 'g': return "\xc4\x9d";
- case 'h': return "\xd1\x9b";
- case 'i': return "\xcf\x8a";
- case 'j': return "\xc4\xb5";
- case 'k': return "\xc4\xb8";
- case 'l': return "\xc4\xba";
- case 'm': return "\xe1\xb8\xbf";
- case 'n': return "\xd0\xb8";
- case 'o': return "\xcf\x8c";
- case 'p': return "\xcf\x81";
- case 'q': return "\x51";
- case 'r': return "\xd2\x91";
- case 's': return "\xc5\xa1";
- case 't': return "\xd1\x82";
- case 'u': return "\xce\xb0";
- case 'v': return "\x56";
- case 'w': return "\xe1\xba\x85";
- case 'x': return "\xd1\x85";
- case 'y': return "\xe1\xbb\xb3";
- case 'z': return "\xc5\xba";
- case 'A': return "\xc3\x85";
- case 'B': return "\xce\xb2";
- case 'C': return "\xc4\x88";
- case 'D': return "\xc4\x90";
- case 'E': return "\xd0\x84";
- case 'F': return "\xce\x93";
- case 'G': return "\xc4\x9e";
- case 'H': return "\xc4\xa6";
- case 'I': return "\xd0\x87";
- case 'J': return "\xc4\xb5";
- case 'K': return "\xc4\xb6";
- case 'L': return "\xc5\x81";
- case 'M': return "\xe1\xb8\xbe";
- case 'N': return "\xc5\x83";
- case 'O': return "\xce\x98";
- case 'P': return "\xcf\x81";
- case 'Q': return "\x71";
- case 'R': return "\xd0\xaf";
- case 'S': return "\xc8\x98";
- case 'T': return "\xc5\xa6";
- case 'U': return "\xc5\xa8";
- case 'V': return "\xce\xbd";
- case 'W': return "\xe1\xba\x84";
- case 'X': return "\xc3\x97";
- case 'Y': return "\xc2\xa5";
- case 'Z': return "\xc5\xbd";
- default: return NULL;
- }
-}
-
-/**
- * Converts characters so they look like they've been localized.
- *
- * Note: This leaves escape sequences untouched so they can later be
- * processed by ResTable::collectString in the normal way.
- */
-string
-pseudolocalize_string(const string& source)
-{
- const char* s = source.c_str();
- string result;
- const size_t I = source.length();
- for (size_t i=0; i<I; i++) {
- char c = s[i];
- if (c == '\\') {
- if (i<I-1) {
- result += '\\';
- i++;
- c = s[i];
- switch (c) {
- case 'u':
- // this one takes up 5 chars
- result += string(s+i, 5);
- i += 4;
- break;
- case 't':
- case 'n':
- case '#':
- case '@':
- case '?':
- case '"':
- case '\'':
- case '\\':
- default:
- result += c;
- break;
- }
- } else {
- result += c;
- }
- } else {
- const char* p = pseudolocalize_char(c);
- if (p != NULL) {
- result += p;
- } else {
- result += c;
- }
- }
- }
-
- //printf("result=\'%s\'\n", result.c_str());
- return result;
-}
-
-
diff --git a/target/product/base.mk b/target/product/base.mk
index 129fb2a..d3c18fb 100644
--- a/target/product/base.mk
+++ b/target/product/base.mk
@@ -44,8 +44,6 @@
libcameraservice \
libchromium_net \
libdl \
- libdrm1 \
- libdrm1_jni \
libeffects \
libiprouteutil \
libjni_latinime \
diff --git a/target/product/embedded.mk b/target/product/embedded.mk
index a3047e3..4aab2c9 100644
--- a/target/product/embedded.mk
+++ b/target/product/embedded.mk
@@ -58,6 +58,7 @@
linker \
logcat \
logwrapper \
+ reboot \
service \
servicemanager \
surfaceflinger \
diff --git a/target/product/generic_no_telephony.mk b/target/product/generic_no_telephony.mk
index 194fb7a..784c2f9 100644
--- a/target/product/generic_no_telephony.mk
+++ b/target/product/generic_no_telephony.mk
@@ -25,12 +25,12 @@
Calculator \
Calendar \
CertInstaller \
- DrmProvider \
Email \
Exchange2 \
FusedLocation \
Gallery2 \
InputDevices \
+ Keyguard \
LatinIME \
Launcher2 \
Music \
@@ -41,6 +41,7 @@
QuickSearchBox \
Settings \
SystemUI \
+ Terminal \
CalendarProvider \
bluetooth-health \
hostapd \
diff --git a/target/product/large_emu_hw.mk b/target/product/large_emu_hw.mk
index 8a070b1..a918c1d 100644
--- a/target/product/large_emu_hw.mk
+++ b/target/product/large_emu_hw.mk
@@ -26,7 +26,6 @@
Calculator \
Calendar \
CertInstaller \
- DrmProvider \
Email \
Exchange2 \
Gallery2 \
diff --git a/target/product/mini.mk b/target/product/mini.mk
index a1f6317..b5b0ffb 100644
--- a/target/product/mini.mk
+++ b/target/product/mini.mk
@@ -222,6 +222,7 @@
PRODUCT_PACKAGES += \
TestingCamera \
Home \
+ Keyguard \
SystemUI \
Settings \
libsurfaceflinger_ddmconnection
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index 51b90f5..8208934 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -24,6 +24,7 @@
Exchange2 \
FusedLocation \
Gallery \
+ Keyguard \
Music \
Mms \
OpenWnn \
@@ -38,7 +39,6 @@
Launcher2 \
Development \
DevelopmentSettings \
- DrmProvider \
Fallback \
Settings \
SdkSetup \
diff --git a/tools/signapk/SignApk.java b/tools/signapk/SignApk.java
index adfe9a3..716ea3b 100644
--- a/tools/signapk/SignApk.java
+++ b/tools/signapk/SignApk.java
@@ -78,8 +78,26 @@
import javax.crypto.spec.PBEKeySpec;
/**
- * Command line tool to sign JAR files (including APKs and OTA updates) in
- * a way compatible with the mincrypt verifier, using SHA1 and RSA keys.
+ * HISTORICAL NOTE:
+ *
+ * Prior to the keylimepie release, SignApk ignored the signature
+ * algorithm specified in the certificate and always used SHA1withRSA.
+ *
+ * Starting with keylimepie, we support SHA256withRSA, and use the
+ * signature algorithm in the certificate to select which to use
+ * (SHA256withRSA or SHA1withRSA).
+ *
+ * Because there are old keys still in use whose certificate actually
+ * says "MD5withRSA", we treat these as though they say "SHA1withRSA"
+ * for compatibility with older releases. This can be changed by
+ * altering the getAlgorithm() function below.
+ */
+
+
+/**
+ * Command line tool to sign JAR files (including APKs and OTA
+ * updates) in a way compatible with the mincrypt verifier, using RSA
+ * keys and SHA1 or SHA-256.
*/
class SignApk {
private static final String CERT_SF_NAME = "META-INF/CERT.SF";
@@ -91,6 +109,27 @@
private static Provider sBouncyCastleProvider;
+ // bitmasks for which hash algorithms we need the manifest to include.
+ private static final int USE_SHA1 = 1;
+ private static final int USE_SHA256 = 2;
+
+ /**
+ * Return one of USE_SHA1 or USE_SHA256 according to the signature
+ * algorithm specified in the cert.
+ */
+ private static int getAlgorithm(X509Certificate cert) {
+ String sigAlg = cert.getSigAlgName();
+ if ("SHA1withRSA".equals(sigAlg) ||
+ "MD5withRSA".equals(sigAlg)) { // see "HISTORICAL NOTE" above.
+ return USE_SHA1;
+ } else if ("SHA256withRSA".equals(sigAlg)) {
+ return USE_SHA256;
+ } else {
+ throw new IllegalArgumentException("unsupported signature algorithm \"" + sigAlg +
+ "\" in cert [" + cert.getSubjectDN());
+ }
+ }
+
// Files matching this pattern are not copied to the output.
private static Pattern stripPattern =
Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA)|com/android/otacert))|(" +
@@ -182,8 +221,11 @@
}
}
- /** Add the SHA1 of every file to the manifest, creating it if necessary. */
- private static Manifest addDigestsToManifest(JarFile jar)
+ /**
+ * Add the hash(es) of every file to the manifest, creating it if
+ * necessary.
+ */
+ private static Manifest addDigestsToManifest(JarFile jar, int hashes)
throws IOException, GeneralSecurityException {
Manifest input = jar.getManifest();
Manifest output = new Manifest();
@@ -195,7 +237,15 @@
main.putValue("Created-By", "1.0 (Android SignApk)");
}
- MessageDigest md = MessageDigest.getInstance("SHA1");
+ MessageDigest md_sha1 = null;
+ MessageDigest md_sha256 = null;
+ if ((hashes & USE_SHA1) != 0) {
+ md_sha1 = MessageDigest.getInstance("SHA1");
+ }
+ if ((hashes & USE_SHA256) != 0) {
+ md_sha256 = MessageDigest.getInstance("SHA256");
+ }
+
byte[] buffer = new byte[4096];
int num;
@@ -216,14 +266,21 @@
(stripPattern == null || !stripPattern.matcher(name).matches())) {
InputStream data = jar.getInputStream(entry);
while ((num = data.read(buffer)) > 0) {
- md.update(buffer, 0, num);
+ if (md_sha1 != null) md_sha1.update(buffer, 0, num);
+ if (md_sha256 != null) md_sha256.update(buffer, 0, num);
}
Attributes attr = null;
if (input != null) attr = input.getAttributes(name);
attr = attr != null ? new Attributes(attr) : new Attributes();
- attr.putValue("SHA1-Digest",
- new String(Base64.encode(md.digest()), "ASCII"));
+ if (md_sha1 != null) {
+ attr.putValue("SHA1-Digest",
+ new String(Base64.encode(md_sha1.digest()), "ASCII"));
+ }
+ if (md_sha256 != null) {
+ attr.putValue("SHA-256-Digest",
+ new String(Base64.encode(md_sha256.digest()), "ASCII"));
+ }
output.getEntries().put(name, attr);
}
}
@@ -241,9 +298,10 @@
private static void addOtacert(JarOutputStream outputJar,
File publicKeyFile,
long timestamp,
- Manifest manifest)
+ Manifest manifest,
+ int hash)
throws IOException, GeneralSecurityException {
- MessageDigest md = MessageDigest.getInstance("SHA1");
+ MessageDigest md = MessageDigest.getInstance(hash == USE_SHA1 ? "SHA1" : "SHA256");
JarEntry je = new JarEntry(OTACERT_NAME);
je.setTime(timestamp);
@@ -258,7 +316,7 @@
input.close();
Attributes attr = new Attributes();
- attr.putValue("SHA1-Digest",
+ attr.putValue(hash == USE_SHA1 ? "SHA1-Digest" : "SHA-256-Digest",
new String(Base64.encode(md.digest()), "ASCII"));
manifest.getEntries().put(OTACERT_NAME, attr);
}
@@ -293,14 +351,16 @@
}
/** Write a .SF file with a digest of the specified manifest. */
- private static void writeSignatureFile(Manifest manifest, OutputStream out)
+ private static void writeSignatureFile(Manifest manifest, OutputStream out,
+ int hash)
throws IOException, GeneralSecurityException {
Manifest sf = new Manifest();
Attributes main = sf.getMainAttributes();
main.putValue("Signature-Version", "1.0");
main.putValue("Created-By", "1.0 (Android SignApk)");
- MessageDigest md = MessageDigest.getInstance("SHA1");
+ MessageDigest md = MessageDigest.getInstance(
+ hash == USE_SHA256 ? "SHA256" : "SHA1");
PrintStream print = new PrintStream(
new DigestOutputStream(new ByteArrayOutputStream(), md),
true, "UTF-8");
@@ -308,7 +368,7 @@
// Digest of the entire manifest
manifest.write(print);
print.flush();
- main.putValue("SHA1-Digest-Manifest",
+ main.putValue(hash == USE_SHA256 ? "SHA-256-Digest-Manifest" : "SHA1-Digest-Manifest",
new String(Base64.encode(md.digest()), "ASCII"));
Map<String, Attributes> entries = manifest.getEntries();
@@ -322,7 +382,7 @@
print.flush();
Attributes sfAttr = new Attributes();
- sfAttr.putValue("SHA1-Digest",
+ sfAttr.putValue(hash == USE_SHA256 ? "SHA-256-Digest" : "SHA1-Digest-Manifest",
new String(Base64.encode(md.digest()), "ASCII"));
sf.getEntries().put(entry.getKey(), sfAttr);
}
@@ -353,7 +413,8 @@
JcaCertStore certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
- ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA")
+ ContentSigner signer = new JcaContentSignerBuilder(
+ getAlgorithm(publicKey) == USE_SHA256 ? "SHA256withRSA" : "SHA1withRSA")
.setProvider(sBouncyCastleProvider)
.build(privateKey);
gen.addSignerInfoGenerator(
@@ -362,7 +423,7 @@
.setProvider(sBouncyCastleProvider)
.build())
.setDirectSignature(true)
- .build(sha1Signer, publicKey));
+ .build(signer, publicKey));
gen.addCertificates(certs);
CMSSignedData sigData = gen.generate(data, false);
@@ -499,14 +560,19 @@
signer = new WholeFileSignerOutputStream(out, outputStream);
JarOutputStream outputJar = new JarOutputStream(signer);
- Manifest manifest = addDigestsToManifest(inputJar);
+ int hash = getAlgorithm(publicKey);
+
+ // Assume the certificate is valid for at least an hour.
+ long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000;
+
+ Manifest manifest = addDigestsToManifest(inputJar, hash);
+ copyFiles(manifest, inputJar, outputJar, timestamp);
+ addOtacert(outputJar, publicKeyFile, timestamp, manifest, hash);
+
signFile(manifest, inputJar,
new X509Certificate[]{ publicKey },
new PrivateKey[]{ privateKey },
outputJar);
- // Assume the certificate is valid for at least an hour.
- long timestamp = publicKey.getNotBefore().getTime() + 3600L * 1000;
- addOtacert(outputJar, publicKeyFile, timestamp, manifest);
signer.notifyClosing();
outputJar.close();
@@ -605,13 +671,8 @@
// Assume the certificate is valid for at least an hour.
long timestamp = publicKey[0].getNotBefore().getTime() + 3600L * 1000;
- JarEntry je;
-
- // Everything else
- copyFiles(manifest, inputJar, outputJar, timestamp);
-
// MANIFEST.MF
- je = new JarEntry(JarFile.MANIFEST_NAME);
+ JarEntry je = new JarEntry(JarFile.MANIFEST_NAME);
je.setTime(timestamp);
outputJar.putNextEntry(je);
manifest.write(outputJar);
@@ -624,7 +685,7 @@
je.setTime(timestamp);
outputJar.putNextEntry(je);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- writeSignatureFile(manifest, baos);
+ writeSignatureFile(manifest, baos, getAlgorithm(publicKey[k]));
byte[] signedData = baos.toByteArray();
outputJar.write(signedData);
@@ -671,14 +732,21 @@
JarFile inputJar = null;
FileOutputStream outputFile = null;
+ int hashes = 0;
try {
File firstPublicKeyFile = new File(args[argstart+0]);
X509Certificate[] publicKey = new X509Certificate[numKeys];
- for (int i = 0; i < numKeys; ++i) {
- int argNum = argstart + i*2;
- publicKey[i] = readPublicKey(new File(args[argNum]));
+ try {
+ for (int i = 0; i < numKeys; ++i) {
+ int argNum = argstart + i*2;
+ publicKey[i] = readPublicKey(new File(args[argNum]));
+ hashes |= getAlgorithm(publicKey[i]);
+ }
+ } catch (IllegalArgumentException e) {
+ System.err.println(e);
+ System.exit(1);
}
// Set the ZIP file timestamp to the starting valid time
@@ -710,8 +778,9 @@
// (~0.1% on full OTA packages I tested).
outputJar.setLevel(9);
- signFile(addDigestsToManifest(inputJar), inputJar,
- publicKey, privateKey, outputJar);
+ Manifest manifest = addDigestsToManifest(inputJar, hashes);
+ copyFiles(manifest, inputJar, outputJar, timestamp);
+ signFile(manifest, inputJar, publicKey, privateKey, outputJar);
outputJar.close();
}
} catch (Exception e) {
diff --git a/tools/zipalign/Android.mk b/tools/zipalign/Android.mk
index 5542280..708c8bf 100644
--- a/tools/zipalign/Android.mk
+++ b/tools/zipalign/Android.mk
@@ -15,6 +15,7 @@
LOCAL_C_INCLUDES += external/zlib
LOCAL_STATIC_LIBRARIES := \
+ libandroidfw \
libutils \
libcutils \
liblog
diff --git a/tools/zipalign/ZipFile.cpp b/tools/zipalign/ZipFile.cpp
index 3994c31..8057068 100644
--- a/tools/zipalign/ZipFile.cpp
+++ b/tools/zipalign/ZipFile.cpp
@@ -20,8 +20,8 @@
#define LOG_TAG "zip"
+#include <androidfw/ZipUtils.h>
#include <utils/Log.h>
-#include <utils/ZipUtils.h>
#include "ZipFile.h"