/** * Returns a new {@code DefaultApkSignerEngine} instance configured based on the * configuration of this builder. */ public DefaultApkSignerEngine build() throws InvalidKeyException { return new DefaultApkSignerEngine( mSignerConfigs, mMinSdkVersion, mV1SigningEnabled, mV2SigningEnabled, mOtherSignersSignaturesPreserved, mCreatedBy); }
@Override public void outputDone() { checkNotClosed(); checkV1SigningDoneIfEnabled(); checkV2SigningDoneIfEnabled(); }
@Override public InputJarEntryInstructions.OutputPolicy inputJarEntryRemoved(String entryName) { checkNotClosed(); return getInputJarEntryOutputPolicy(entryName); }
@Override public void outputJarEntryRemoved(String entryName) { checkNotClosed(); invalidateV2Signature(); if (!mV1SigningEnabled) { return; } if (V1SchemeSigner.isJarEntryDigestNeededInManifest(entryName)) { // This entry is covered by v1 signature. invalidateV1Signature(); mOutputJarEntryDigests.remove(entryName); mOutputJarEntryDigestRequests.remove(entryName); mOutputSignatureJarEntryDataRequests.remove(entryName); return; } if (mSignatureExpectedOutputJarEntryNames.contains(entryName)) { // This entry is part of the v1 signature generated by this engine. invalidateV1Signature(); return; } }
@Override public OutputApkSigningBlockRequest outputZipSections( DataSource zipEntries, DataSource zipCentralDirectory, DataSource zipEocd) throws IOException, InvalidKeyException, SignatureException, NoSuchAlgorithmException { checkNotClosed(); checkV1SigningDoneIfEnabled(); if (!mV2SigningEnabled) { return null; } invalidateV2Signature(); byte[] apkSigningBlock = V2SchemeSigner.generateApkSigningBlock( zipEntries, zipCentralDirectory, zipEocd, mV2SignerConfigs); mAddV2SignatureRequest = new OutputApkSigningBlockRequestImpl(apkSigningBlock); return mAddV2SignatureRequest; }
@Override public void inputApkSigningBlock(DataSource apkSigningBlock) { checkNotClosed(); if ((apkSigningBlock == null) || (apkSigningBlock.size() == 0)) { return; } if (mOtherSignersSignaturesPreserved) { // TODO: Preserve blocks other than APK Signature Scheme v2 blocks of signers configured // in this engine. return; } // TODO: Preserve blocks other than APK Signature Scheme v2 blocks. }
private void invalidateV1Signature() { if (mV1SigningEnabled) { mV1SignaturePending = true; } invalidateV2Signature(); }
@Override public InspectJarEntryRequest outputJarEntry(String entryName) { checkNotClosed(); invalidateV2Signature(); if (!mV1SigningEnabled) { invalidateV1Signature(); GetJarEntryDataDigestRequest dataDigestRequest = new GetJarEntryDataDigestRequest( invalidateV1Signature(); GetJarEntryDataRequest dataRequest; if (V1SchemeSigner.MANIFEST_ENTRY_NAME.equals(entryName)) {
throws ApkFormatException, InvalidKeyException, SignatureException, NoSuchAlgorithmException { checkNotClosed();
@Override public InputJarEntryInstructions inputJarEntry(String entryName) { checkNotClosed(); InputJarEntryInstructions.OutputPolicy outputPolicy = getInputJarEntryOutputPolicy(entryName); switch (outputPolicy) { case SKIP: return new InputJarEntryInstructions(InputJarEntryInstructions.OutputPolicy.SKIP); case OUTPUT: return new InputJarEntryInstructions(InputJarEntryInstructions.OutputPolicy.OUTPUT); case OUTPUT_BY_ENGINE: if (V1SchemeSigner.MANIFEST_ENTRY_NAME.equals(entryName)) { // We copy the main section of the JAR manifest from input to output. Thus, this // invalidates v1 signature and we need to see the entry's data. mInputJarManifestEntryDataRequest = new GetJarEntryDataRequest(entryName); return new InputJarEntryInstructions( InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE, mInputJarManifestEntryDataRequest); } return new InputJarEntryInstructions( InputJarEntryInstructions.OutputPolicy.OUTPUT_BY_ENGINE); default: throw new RuntimeException("Unsupported output policy: " + outputPolicy); } }