diff options
Diffstat (limited to 'src/main/java/com/android/apkzlib/sign/package-info.java')
-rw-r--r-- | src/main/java/com/android/apkzlib/sign/package-info.java | 153 |
1 files changed, 0 insertions, 153 deletions
diff --git a/src/main/java/com/android/apkzlib/sign/package-info.java b/src/main/java/com/android/apkzlib/sign/package-info.java deleted file mode 100644 index 6bb692c..0000000 --- a/src/main/java/com/android/apkzlib/sign/package-info.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - -The {@code sign} package provides extensions for the {@code zip} package that allow: -<ul> - <li>Adding a {@code MANIFEST.MF} file to a zip making a jar.</li> - <li>Signing a jar.</li> - <li>Fully signing a jar using v2 apk signature.</li> -</ul> -<p> -Because the {@code zip} package is completely independent of the {@code sign} package, the -actual coordination between the two is complex. The {@code sign} package works by registering -extensions with the {@code zip} package. These extensions are notified in changes made in the zip -and will change the zip file itself. -<p> -The {@link com.android.apkzlib.sign.ManifestGenerationExtension} extension will -ensure the zip has a manifest file and is, therefore, a valid jar. -The {@link com.android.apkzlib.sign.SigningExtension} extension will -ensure the jar is signed. -<p> -The extension mechanism used is the one provided in the {@code zip} package (see -{@link com.android.apkzlib.zip.ZFile} -and {@link com.android.apkzlib.zip.ZFileExtension}. Building the zip and then -operating the extensions is not done sequentially, as we don't want to build a zip and then sign it. -We want to build a zip that is automatically signed. Extension are basically observers that -register on the zip and are notified when things happen in the zip. They will then modify the zip -accordingly. -<p> -The zip file notifies extensions in 4 critical moments: when a file is added or removed from the -zip, when the zip is about to be flushed to disk and when the zip's entries have been flushed but -the central directory not. At these moments, the extensions can act to update the zip in any way -they need. -<p> -To see how this works, consider the manifest generation extension: when the extension is created, -it checks the zip file to see if there is a manifest. If a manifest exists and does not need -updating, it does not change anything, otherwise it generates a new manifest for the zip file. At -this point, the extension could write the manifest to the zip, but we opted not to. It would be -irrelevant anyway as the zip will only be written when flushed. -<p> -Now, when the {@code ZFile} notifies the extension that it is about to start writing the zip file, -the manifest extension, if it has noted that the manifest needs to be rewritten, will -- before the -{@code ZFile} actually writes anything -- modify the zip and add or replace the existing manifest -file. So, process-wise, the zip is written only once with the correct manifest. The flow is as -follows (if only the manifest generation extension was added to the {@code ZFile}): -<ol> - <li>{@code ZFile.update()} is called.</li> - <li>{@code ZFile} calls {@code beforeUpdate()} for all {@code ZFileExtensions} registered, in - this case, only the instance of the anonymous inner class generated in the - {@code ManifestGenerationExtension} constructor is invoked.</li> - <li>{@code ManifestGenerationExtension.updateManifest()} is called.</li> - <li>If the manifest does not need to be updated, {@code updateManifest()} returns - immediately.</li> - <li>If the manifest needs updating, {@code ZFile.add()} is invoked to add or replace the - manifest.</li> - <li>{@code ManifestGenerationExtension.updateManifest()} returns.</li> - <li>{@code ZFile.update()} continues and writes the zip file, containing the manifest.</li> - <li>The zip is finally written with an updated manifest.</li> -</ol> -<p> -To generate a signed apk, we need to add a second extension, the {@code SigningExtension}. -This extension will also register listeners with the {@code ZFile}. -<p> -In this case the flow would be (starting a bit earlier for clarity and assuming a package task -in the build process): -<ol> - <li>Package task creates a {@code ZFile} on the target apk (or non-existing file, if there is - no target apk in the output directory).</li> - <li>Package task configures the {@code ZFile} with alignment rules.</li> - <li>Package task creates a {@code ManifestGenerationExtension}.</li> - <li>Package task registers the {@code ManifestGenerationExtension} with the {@code ZFile}.</li> - <li>The {@code ManifestGenerationExtension} looks at the {@code ZFile} to see if there is valid - manifest. No changes are done to the {@code ZFile}.</li> - <li>Package task creates a {@code SigningExtension}.</li> - <li>Package task registers the {@code SigningExtension} with the {@code ZFile}.</li> - <li>The {@code SigningExtension} registers a {@code ZFileExtension} with the {@code ZFile} - and look at the {@code ZFile} to see if there is a valid signature file.</li> - <li>If there are changes to the digital signature file needed, these are marked internally in - the extension. If there are changes needed to the digests, the manifest is updated (by calling - {@code ManifestGenerationExtension}.<br> - <em>(note that this point, the apk file, if any existed, has not been touched, the manifest is - only updated in memory and the digests of all files in the apk, if any, have been computed and - stored in memory only; the digital signature of the {@code SF} file has not been computed.) - </em></li> - <li>The Package task now adds all files to the {@code ZFile}.</li> - <li>For each file that is added (*), {@code ZFile} calls the added {@code ZFileExtension.added} - method of all registered extensions.</li> - <li>The {@code ManifestGenerationExtension} ignores added invocations.</li> - <li>The {@code SigningExtension} computes the digest for the added file and stores them in - the manifest.<br> - <em>(when all files are added to the apk, all digests are computed and the manifest is updated - but only in memory; the apk file has not been touched; also note that {@code ZFile} has not - actually written anything to disk at this point, all files added are kept in memory).</em></li> - <li>Package task calls {@code ZFile.update()} to update the apk.</li> - <li>{@code ZFile} calls {@code before()} for all {@code ZFileExtensions} registered. This is - done before anything is written. In this case both the {@code ManifestGenerationExtension} and - {@code SigningExtension} are invoked.</li> - <li>The {@code ManifestGenerationExtension} will update the {@code ZFile} with the new manifest, - unless nothing has changed, in which case it does nothing.</li> - <li>The {@code SigningExtension} will add the SF file (unless nothing has changed), will - compute the digital signature of the SF file and write it to the {@code ZFile}.<br> - <em>(note that the order by which the {@code ManifestGenerationExtension} and - {@code SigningExtension} are called is non-deterministic; however, this is not a problem - because the manifest is already computed by the {@code ManifestGenerationExtension} at this - time and the {@code SigningExtension} will obtain the manifest data from the - {@code ManifestGenerationExtension} and not from the {@code ZFile}; this means that the - {@code SF} file may be added to the {@code ZFile} before the {@code MF} file, but that is - irrelevant.)</em></li> - <li>Once both extensions have finished doing the {@code beforeUpdate()} method, the - {@code ZFile.update()} method continues.</li> - <li>{@code ZFile.update()} writes all changes and new entries to the zip file.</li> - <li>{@code ZFile.update()} calls {@code ZFileExtension.entriesWritten()} for all - registered extensions. {@code SigningExtension} will kick in at this point, if v2 signature - has changed.</li> - <li>{@code ZFile} writes the central directory and EOCD.</li> - <li>{@code ZFile.update()} returns control to the package task.</li> - <li>The package task finishes.</li> -</ol> -<em>(*) There is a number of optimizations if we're adding files from another {@code ZFile}, which -is the case when we add the output of aapt to the apk. In particular, files from the aapt are -ignored if they are already in the apk (same name, same CRC32) and also files copied from -the aapt's output are not recompressed (the binary compressed data is directly copied to the -zip).</em> -<p> -If there are no changes to the {@code ZFile} made by the package task and the file's manifest and v1 -signatures are correct, neither the {@code ManifestGenerationExtension} nor the -{@code SigningExtension} will not do anything on the {@code beforeUpdate()} and the -{@code ZFile} won't even be open for writing. -<p> -This implementation provides perfect incremental updates. -<p> -Additionally, by adding/removing extensions we can configure what type of apk we want: -<ul> - <li>No SigningExtension ⇒ Aligned, unsigned apk.</li> - <li>SigningExtension ⇒ Aligned, signed apk. -</ul> -So, by configuring which extensions to add, the package task can decide what type of apk we want. -*/ -package com.android.apkzlib.sign;
\ No newline at end of file |