private static byte[] generateApkSignatureSchemeV2Block( List<SignerConfig> signerConfigs, Map<ContentDigestAlgorithm, byte[]> contentDigests) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { // FORMAT: // * length-prefixed sequence of length-prefixed signer blocks. List<byte[]> signerBlocks = new ArrayList<>(signerConfigs.size()); int signerNumber = 0; for (SignerConfig signerConfig : signerConfigs) { signerNumber++; byte[] signerBlock; try { signerBlock = generateSignerBlock(signerConfig, contentDigests); } catch (InvalidKeyException e) { throw new InvalidKeyException("Signer #" + signerNumber + " failed", e); } catch (SignatureException e) { throw new SignatureException("Signer #" + signerNumber + " failed", e); } signerBlocks.add(signerBlock); } return encodeAsSequenceOfLengthPrefixedElements( new byte[][] { encodeAsSequenceOfLengthPrefixedElements(signerBlocks), }); }
private static byte[] generateApkSigningBlock(byte[] apkSignatureSchemeV2Block) { // FORMAT: // uint64: size (excluding this field) // repeated ID-value pairs: // uint64: size (excluding this field) // uint32: ID // (size - 4) bytes: value // uint64: size (same as the one above) // uint128: magic int resultSize = 8 // size + 8 + 4 + apkSignatureSchemeV2Block.length // v2Block as ID-value pair + 8 // size + 16 // magic ; ByteBuffer result = ByteBuffer.allocate(resultSize); result.order(ByteOrder.LITTLE_ENDIAN); long blockSizeFieldValue = resultSize - 8; result.putLong(blockSizeFieldValue); long pairSizeFieldValue = 4 + apkSignatureSchemeV2Block.length; result.putLong(pairSizeFieldValue); result.putInt(APK_SIGNATURE_SCHEME_V2_BLOCK_ID); result.put(apkSignatureSchemeV2Block); result.putLong(blockSizeFieldValue); result.put(APK_SIGNING_BLOCK_MAGIC); return result.array(); }
byte[] encodedPublicKey = encodePublicKey(publicKey); signedData.certificates = encodeCertificates(signerConfig.certificates); } catch (CertificateEncodingException e) { throw new SignatureException("Failed to encode certificates", e); signer.signedData = encodeAsSequenceOfLengthPrefixedElements(new byte[][] { encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes(signedData.digests), encodeAsSequenceOfLengthPrefixedElements(signedData.certificates), return encodeAsSequenceOfLengthPrefixedElements( new byte[][] { signer.signedData, encodeAsSequenceOfLengthPrefixedPairsOfIntAndLengthPrefixedBytes( signer.signatures), signer.publicKey,
try { contentDigests = computeContentDigests( contentDigestAlgorithms, new DataSource[] { return generateApkSigningBlock(signerConfigs, contentDigests);
for (DataSource input : contents) { chunkCountLong += getChunkCount(input.size(), CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES); new byte[5 + chunkCount * digestOutputSizeBytes]; concatenationOfChunkCountAndChunkDigests[0] = 0x5a; setUnsignedInt32LittleEndian( chunkCount, concatenationOfChunkCountAndChunkDigests, 1); digestsOfChunks[i] = concatenationOfChunkCountAndChunkDigests; int chunkSize = (int) Math.min(inputRemaining, CONTENT_DIGESTED_CHUNK_MAX_SIZE_BYTES); setUnsignedInt32LittleEndian(chunkSize, chunkContentPrefix, 1); for (int i = 0; i < mds.length; i++) { mds[i].update(chunkContentPrefix);
private static byte[] encodeAsSequenceOfLengthPrefixedElements(List<byte[]> sequence) { return encodeAsSequenceOfLengthPrefixedElements( sequence.toArray(new byte[sequence.size()][])); }
v2SignerConfig.certificates = certificates; v2SignerConfig.signatureAlgorithms = V2SchemeSigner.getSuggestedSignatureAlgorithms(publicKey, minSdkVersion); mV2SignerConfigs.add(v2SignerConfig);
try { actualContentDigests = V2SchemeSigner.computeContentDigests( contentDigestAlgorithms, new DataSource[] {
@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; }