Merge "Use Jan 1 2009 as timestamp in APKs and OTA update ZIPs."

am: 0d85dab09a

* commit '0d85dab09a09de48535e4139b858e5e4bef8565f':
  Use Jan 1 2009 as timestamp in APKs and OTA update ZIPs.
This commit is contained in:
Dan Willemsen 2016-01-30 02:47:35 +00:00 committed by android-build-merger
commit 10b4db6f0e
1 changed files with 20 additions and 12 deletions

View File

@ -74,6 +74,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.jar.Attributes; import java.util.jar.Attributes;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
@ -680,18 +681,20 @@ class SignApk {
private final File publicKeyFile; private final File publicKeyFile;
private final X509Certificate publicKey; private final X509Certificate publicKey;
private final PrivateKey privateKey; private final PrivateKey privateKey;
private final long timestamp;
private final int minSdkVersion; private final int minSdkVersion;
private final OutputStream outputStream; private final OutputStream outputStream;
private final ASN1ObjectIdentifier type; private final ASN1ObjectIdentifier type;
private WholeFileSignerOutputStream signer; private WholeFileSignerOutputStream signer;
public CMSSigner(JarFile inputJar, File publicKeyFile, public CMSSigner(JarFile inputJar, File publicKeyFile,
X509Certificate publicKey, PrivateKey privateKey, int minSdkVersion, X509Certificate publicKey, PrivateKey privateKey, long timestamp,
OutputStream outputStream) { int minSdkVersion, OutputStream outputStream) {
this.inputJar = inputJar; this.inputJar = inputJar;
this.publicKeyFile = publicKeyFile; this.publicKeyFile = publicKeyFile;
this.publicKey = publicKey; this.publicKey = publicKey;
this.privateKey = privateKey; this.privateKey = privateKey;
this.timestamp = timestamp;
this.minSdkVersion = minSdkVersion; this.minSdkVersion = minSdkVersion;
this.outputStream = outputStream; this.outputStream = outputStream;
this.type = new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()); this.type = new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId());
@ -729,6 +732,7 @@ class SignApk {
signFile(manifest, signFile(manifest,
new X509Certificate[]{ publicKey }, new X509Certificate[]{ publicKey },
new PrivateKey[]{ privateKey }, new PrivateKey[]{ privateKey },
timestamp,
minSdkVersion, minSdkVersion,
false, // Don't sign using APK Signature Scheme v2 false, // Don't sign using APK Signature Scheme v2
outputJar); outputJar);
@ -757,10 +761,10 @@ class SignApk {
private static void signWholeFile(JarFile inputJar, File publicKeyFile, private static void signWholeFile(JarFile inputJar, File publicKeyFile,
X509Certificate publicKey, PrivateKey privateKey, X509Certificate publicKey, PrivateKey privateKey,
int minSdkVersion, long timestamp, int minSdkVersion,
OutputStream outputStream) throws Exception { OutputStream outputStream) throws Exception {
CMSSigner cmsOut = new CMSSigner(inputJar, publicKeyFile, CMSSigner cmsOut = new CMSSigner(inputJar, publicKeyFile,
publicKey, privateKey, minSdkVersion, outputStream); publicKey, privateKey, timestamp, minSdkVersion, outputStream);
ByteArrayOutputStream temp = new ByteArrayOutputStream(); ByteArrayOutputStream temp = new ByteArrayOutputStream();
@ -826,12 +830,11 @@ class SignApk {
private static void signFile(Manifest manifest, private static void signFile(Manifest manifest,
X509Certificate[] publicKey, PrivateKey[] privateKey, X509Certificate[] publicKey, PrivateKey[] privateKey,
long timestamp,
int minSdkVersion, int minSdkVersion,
boolean additionallySignedUsingAnApkSignatureScheme, boolean additionallySignedUsingAnApkSignatureScheme,
JarOutputStream outputJar) JarOutputStream outputJar)
throws Exception { throws Exception {
// Assume the certificate is valid for at least an hour.
long timestamp = publicKey[0].getNotBefore().getTime() + 3600L * 1000;
// MANIFEST.MF // MANIFEST.MF
JarEntry je = new JarEntry(JarFile.MANIFEST_NAME); JarEntry je = new JarEntry(JarFile.MANIFEST_NAME);
@ -1087,10 +1090,12 @@ class SignApk {
System.exit(1); System.exit(1);
} }
// Set the ZIP file timestamp to the starting valid time // Set all ZIP file timestamps to Jan 1 2009 00:00:00.
// of the 0th certificate plus one hour (to match what long timestamp = 1230768000000L;
// we've historically done). // The Java ZipEntry API we're using converts milliseconds since epoch into MS-DOS
long timestamp = publicKey[0].getNotBefore().getTime() + 3600L * 1000; // timestamp using the current timezone. We thus adjust the milliseconds since epoch
// value to end up with MS-DOS timestamp of Jan 1 2009 00:00:00.
timestamp -= TimeZone.getDefault().getOffset(timestamp);
PrivateKey[] privateKey = new PrivateKey[numKeys]; PrivateKey[] privateKey = new PrivateKey[numKeys];
for (int i = 0; i < numKeys; ++i) { for (int i = 0; i < numKeys; ++i) {
@ -1105,7 +1110,9 @@ class SignApk {
// compression level for OTA update files and maximum compession level for APKs). // compression level for OTA update files and maximum compession level for APKs).
if (signWholeFile) { if (signWholeFile) {
SignApk.signWholeFile(inputJar, firstPublicKeyFile, SignApk.signWholeFile(inputJar, firstPublicKeyFile,
publicKey[0], privateKey[0], minSdkVersion, outputFile); publicKey[0], privateKey[0],
timestamp, minSdkVersion,
outputFile);
} else { } else {
// Generate, in memory, an APK signed using standard JAR Signature Scheme. // Generate, in memory, an APK signed using standard JAR Signature Scheme.
ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream(); ByteArrayOutputStream v1SignedApkBuf = new ByteArrayOutputStream();
@ -1117,7 +1124,8 @@ class SignApk {
copyFiles(manifest, inputJar, outputJar, timestamp, alignment); copyFiles(manifest, inputJar, outputJar, timestamp, alignment);
signFile( signFile(
manifest, manifest,
publicKey, privateKey, minSdkVersion, signUsingApkSignatureSchemeV2, publicKey, privateKey,
timestamp, minSdkVersion, signUsingApkSignatureSchemeV2,
outputJar); outputJar);
outputJar.close(); outputJar.close();
ByteBuffer v1SignedApk = ByteBuffer.wrap(v1SignedApkBuf.toByteArray()); ByteBuffer v1SignedApk = ByteBuffer.wrap(v1SignedApkBuf.toByteArray());