1cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root/* 2cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * Copyright (C) 2011 The Android Open Source Project 3cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * 4cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * you may not use this file except in compliance with the License. 6cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * You may obtain a copy of the License at 7cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * 8cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * 10cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * Unless required by applicable law or agreed to in writing, software 11cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * See the License for the specific language governing permissions and 14cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root * limitations under the License. 15cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root */ 16cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 17cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootpackage com.android.server.pm; 18cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 19cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootimport com.android.internal.util.XmlUtils; 20cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 21cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootimport org.xmlpull.v1.XmlPullParser; 22cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootimport org.xmlpull.v1.XmlPullParserException; 23cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootimport org.xmlpull.v1.XmlSerializer; 24cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 2577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashmanimport android.annotation.NonNull; 26420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumannimport android.content.pm.PackageParser; 27420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumannimport android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion; 28cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootimport android.content.pm.Signature; 29cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootimport android.util.Log; 30cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 31cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootimport java.io.IOException; 3277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashmanimport java.security.cert.CertificateException; 33cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootimport java.util.ArrayList; 34cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 35cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Rootclass PackageSignatures { 3677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman 3777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman @NonNull PackageParser.SigningDetails mSigningDetails; 38cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 39cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root PackageSignatures(PackageSignatures orig) { 4077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (orig != null && orig.mSigningDetails != PackageParser.SigningDetails.UNKNOWN) { 4177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman mSigningDetails = new PackageParser.SigningDetails(orig.mSigningDetails); 4277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } else { 4377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman mSigningDetails = PackageParser.SigningDetails.UNKNOWN; 44cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 45cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 46cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 47420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumann PackageSignatures(PackageParser.SigningDetails signingDetails) { 4877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman mSigningDetails = signingDetails; 49cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 50cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 51cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root PackageSignatures() { 5277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman mSigningDetails = PackageParser.SigningDetails.UNKNOWN; 53cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 54cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 55cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root void writeXml(XmlSerializer serializer, String tagName, 5677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman ArrayList<Signature> writtenSignatures) throws IOException { 5777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (mSigningDetails.signatures == null) { 58cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return; 59cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 60cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root serializer.startTag(null, tagName); 6177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman serializer.attribute(null, "count", Integer.toString(mSigningDetails.signatures.length)); 6277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman serializer.attribute(null, "schemeVersion", 6377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Integer.toString(mSigningDetails.signatureSchemeVersion)); 6477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman writeCertsListXml(serializer, writtenSignatures, mSigningDetails.signatures, null); 6577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman 6677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman // if we have past signer certificate information, write it out 6777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (mSigningDetails.pastSigningCertificates != null) { 6877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman serializer.startTag(null, "pastSigs"); 6977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman serializer.attribute(null, "count", 7077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Integer.toString(mSigningDetails.pastSigningCertificates.length)); 7177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman writeCertsListXml( 7277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman serializer, writtenSignatures, mSigningDetails.pastSigningCertificates, 7377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman mSigningDetails.pastSigningCertificatesFlags); 7477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman serializer.endTag(null, "pastSigs"); 7577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 7677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman serializer.endTag(null, tagName); 7777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 7877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman 7977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman private void writeCertsListXml(XmlSerializer serializer, ArrayList<Signature> writtenSignatures, 8077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Signature[] signatures, int[] flags) throws IOException { 8177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman for (int i=0; i<signatures.length; i++) { 82cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root serializer.startTag(null, "cert"); 8377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman final Signature sig = signatures[i]; 84cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root final int sigHash = sig.hashCode(); 8577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman final int numWritten = writtenSignatures.size(); 86cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int j; 8777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman for (j=0; j<numWritten; j++) { 8877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Signature writtenSig = writtenSignatures.get(j); 8977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (writtenSig.hashCode() == sigHash && writtenSig.equals(sig)) { 90cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root serializer.attribute(null, "index", Integer.toString(j)); 91cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root break; 92cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 93cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 9477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (j >= numWritten) { 9577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman writtenSignatures.add(sig); 9677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman serializer.attribute(null, "index", Integer.toString(numWritten)); 97cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root serializer.attribute(null, "key", sig.toCharsString()); 98cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 9977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (flags != null) { 10077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman serializer.attribute(null, "flags", Integer.toString(flags[i])); 10177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 102cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root serializer.endTag(null, "cert"); 103cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 104cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 105cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 10677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman void readXml(XmlPullParser parser, ArrayList<Signature> readSignatures) 107cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root throws IOException, XmlPullParserException { 10877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman PackageParser.SigningDetails.Builder builder = 10977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman new PackageParser.SigningDetails.Builder(); 11077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman 111cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root String countStr = parser.getAttributeValue(null, "count"); 112cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (countStr == null) { 113cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root PackageManagerService.reportSettingsProblem(Log.WARN, 11477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Error in package manager settings: <sigs> has" 115cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root + " no count at " + parser.getPositionDescription()); 116cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root XmlUtils.skipCurrentTag(parser); 117cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 11877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman final int count = Integer.parseInt(countStr); 11977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman 120420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumann String schemeVersionStr = parser.getAttributeValue(null, "schemeVersion"); 12177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman int signatureSchemeVersion; 122420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumann if (schemeVersionStr == null) { 123420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumann PackageManagerService.reportSettingsProblem(Log.WARN, 12477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Error in package manager settings: <sigs> has no schemeVersion at " 125420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumann + parser.getPositionDescription()); 12677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman signatureSchemeVersion = SignatureSchemeVersion.UNKNOWN; 127420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumann } else { 12877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman signatureSchemeVersion = Integer.parseInt(schemeVersionStr); 129420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumann } 13077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman builder.setSignatureSchemeVersion(signatureSchemeVersion); 13177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Signature[] signatures = new Signature[count]; 13277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman int pos = readCertsListXml(parser, readSignatures, signatures, null, builder); 13377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman builder.setSignatures(signatures); 13477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (pos < count) { 13577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman // Should never happen -- there is an error in the written 13677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman // settings -- but if it does we don't want to generate 13777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman // a bad array. 13877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Signature[] newSigs = new Signature[pos]; 13977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman System.arraycopy(signatures, 0, newSigs, 0, pos); 14077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman builder = builder.setSignatures(newSigs); 14177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman PackageManagerService.reportSettingsProblem(Log.WARN, 14277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Error in package manager settings: <sigs> count does not match number of " 14377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + " <cert> entries" + parser.getPositionDescription()); 14477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 14577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman 14677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman try { 14777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman mSigningDetails = builder.build(); 14877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } catch (CertificateException e) { 14977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman PackageManagerService.reportSettingsProblem(Log.WARN, 15077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Error in package manager settings: <sigs> " 15177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + "unable to convert certificate(s) to public key(s)."); 15277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman mSigningDetails = PackageParser.SigningDetails.UNKNOWN; 15377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 15477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 15577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman 15677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman private int readCertsListXml(XmlPullParser parser, ArrayList<Signature> readSignatures, 15777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Signature[] signatures, int[] flags, PackageParser.SigningDetails.Builder builder) 15877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman throws IOException, XmlPullParserException { 15977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman int count = signatures.length; 160cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int pos = 0; 161cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 162cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int outerDepth = parser.getDepth(); 163cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int type; 164cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 16577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman && (type != XmlPullParser.END_TAG 16677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman || parser.getDepth() > outerDepth)) { 167cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (type == XmlPullParser.END_TAG 168cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root || type == XmlPullParser.TEXT) { 169cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root continue; 170cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 171cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 172cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root String tagName = parser.getName(); 173cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (tagName.equals("cert")) { 174cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (pos < count) { 175cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root String index = parser.getAttributeValue(null, "index"); 176cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (index != null) { 177cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root try { 178cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root int idx = Integer.parseInt(index); 179cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root String key = parser.getAttributeValue(null, "key"); 180cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (key == null) { 18177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (idx >= 0 && idx < readSignatures.size()) { 18277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Signature sig = readSignatures.get(idx); 183cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (sig != null) { 18477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman signatures[pos] = readSignatures.get(idx); 185cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } else { 186cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root PackageManagerService.reportSettingsProblem(Log.WARN, 187cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root "Error in package manager settings: <cert> " 18877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + "index " + index + " is not defined at " 18977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + parser.getPositionDescription()); 190cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 191cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } else { 192cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root PackageManagerService.reportSettingsProblem(Log.WARN, 193cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root "Error in package manager settings: <cert> " 19477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + "index " + index + " is out of bounds at " 19577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + parser.getPositionDescription()); 196cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 197cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } else { 19877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman while (readSignatures.size() <= idx) { 19977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman readSignatures.add(null); 200cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 201cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root Signature sig = new Signature(key); 20277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman readSignatures.set(idx, sig); 20377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman signatures[pos] = sig; 204cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 205cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } catch (NumberFormatException e) { 206cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root PackageManagerService.reportSettingsProblem(Log.WARN, 207cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root "Error in package manager settings: <cert> " 20877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + "index " + index + " is not a number at " 20977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + parser.getPositionDescription()); 2101137341885d8dc451dddc2e01319fb0fab00bbc3Kenny Root } catch (IllegalArgumentException e) { 2111137341885d8dc451dddc2e01319fb0fab00bbc3Kenny Root PackageManagerService.reportSettingsProblem(Log.WARN, 2121137341885d8dc451dddc2e01319fb0fab00bbc3Kenny Root "Error in package manager settings: <cert> " 21377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + "index " + index + " has an invalid signature at " 21477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + parser.getPositionDescription() + ": " 21577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + e.getMessage()); 21677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 21777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman 21877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (flags != null) { 21977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman String flagsStr = parser.getAttributeValue(null, "flags"); 22077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (flagsStr != null) { 22177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman try { 22277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman flags[pos] = Integer.parseInt(flagsStr); 22377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } catch (NumberFormatException e) { 22477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman PackageManagerService.reportSettingsProblem(Log.WARN, 22577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Error in package manager settings: <cert> " 22677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + "flags " + flagsStr + " is not a number at " 22777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + parser.getPositionDescription()); 22877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 22977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } else { 23077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman PackageManagerService.reportSettingsProblem(Log.WARN, 23177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Error in package manager settings: <cert> has no" 23277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + " flags at " + parser.getPositionDescription()); 23377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 234cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 235cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } else { 236cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root PackageManagerService.reportSettingsProblem(Log.WARN, 237cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root "Error in package manager settings: <cert> has" 23877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + " no index at " + parser.getPositionDescription()); 239cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 240cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } else { 241cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root PackageManagerService.reportSettingsProblem(Log.WARN, 242cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root "Error in package manager settings: too " 24377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + "many <cert> tags, expected " + count 24477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + " at " + parser.getPositionDescription()); 24577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 2467ee17aa6b228a007129147c7a6e9ecba2a40d892Dan Cashman pos++; 2477ee17aa6b228a007129147c7a6e9ecba2a40d892Dan Cashman XmlUtils.skipCurrentTag(parser); 24877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } else if (tagName.equals("pastSigs")) { 24977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (flags == null) { 25077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman // we haven't encountered pastSigs yet, go ahead 25177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman String countStr = parser.getAttributeValue(null, "count"); 25277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (countStr == null) { 25377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman PackageManagerService.reportSettingsProblem(Log.WARN, 25477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Error in package manager settings: <pastSigs> has" 25577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + " no count at " + parser.getPositionDescription()); 25677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman XmlUtils.skipCurrentTag(parser); 25777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 25877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman try { 25977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman final int pastSigsCount = Integer.parseInt(countStr); 26077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Signature[] pastSignatures = new Signature[pastSigsCount]; 26177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman int[] pastSignaturesFlags = new int[pastSigsCount]; 26277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman int pastSigsPos = readCertsListXml(parser, readSignatures, pastSignatures, 26377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman pastSignaturesFlags, builder); 26477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman builder = builder 26577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman .setPastSigningCertificates(pastSignatures) 26677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman .setPastSigningCertificatesFlags(pastSignaturesFlags); 26777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman 26877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (pastSigsPos < pastSigsCount) { 26977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman // Should never happen -- there is an error in the written 27077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman // settings -- but if it does we don't want to generate 27177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman // a bad array. 27277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman Signature[] newSigs = new Signature[pastSigsPos]; 27377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman System.arraycopy(pastSignatures, 0, newSigs, 0, pastSigsPos); 27477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman int[] newFlags = new int[pastSigsPos]; 27577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman System.arraycopy(pastSignaturesFlags, 0, newFlags, 0, pastSigsPos); 27677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman builder = builder 27777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman .setPastSigningCertificates(newSigs) 27877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman .setPastSigningCertificatesFlags(newFlags); 27977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman PackageManagerService.reportSettingsProblem(Log.WARN, 28077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Error in package manager settings: <pastSigs> count does not " 28177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + "match number of <cert> entries " 28277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + parser.getPositionDescription()); 28377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 28477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } catch (NumberFormatException e) { 28577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman PackageManagerService.reportSettingsProblem(Log.WARN, 28677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Error in package manager settings: <pastSigs> " 28777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + "count " + countStr + " is not a number at " 28877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + parser.getPositionDescription()); 28977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 29077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } else { 29177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman PackageManagerService.reportSettingsProblem(Log.WARN, 29277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "<pastSigs> encountered multiple times under the same <sigs> at " 29377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + parser.getPositionDescription()); 29419e8803ddc1cfc74a9c976250da634140249d734Dan Cashman XmlUtils.skipCurrentTag(parser); 295cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 296cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } else { 297cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root PackageManagerService.reportSettingsProblem(Log.WARN, 29877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman "Unknown element under <sigs>: " 29977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman + parser.getName()); 30033e17ae146ac6b13a6a1aea040730e86c927bb5aDan Cashman XmlUtils.skipCurrentTag(parser); 301cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 302cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 30377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman return pos; 304cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 305cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root 306cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root @Override 307cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root public String toString() { 308cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root StringBuffer buf = new StringBuffer(128); 309cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root buf.append("PackageSignatures{"); 310cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root buf.append(Integer.toHexString(System.identityHashCode(this))); 311420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumann buf.append(" version:"); 31277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman buf.append(mSigningDetails.signatureSchemeVersion); 313420d58a9d867a3ce96fb4ea98bd30ee4d44eab4dPatrick Baumann buf.append(", signatures:["); 31477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (mSigningDetails.signatures != null) { 31577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman for (int i = 0; i < mSigningDetails.signatures.length; i++) { 316cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root if (i > 0) buf.append(", "); 317cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root buf.append(Integer.toHexString( 31877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman mSigningDetails.signatures[i].hashCode())); 319cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 320cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 321be6c065d2c2ec960a266da88e6cd5bd33f15fde7Dan Cashman buf.append("]"); 32277029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman buf.append(", past signatures:["); 32377029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (mSigningDetails.pastSigningCertificates != null) { 32477029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman for (int i = 0; i < mSigningDetails.pastSigningCertificates.length; i++) { 32577029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman if (i > 0) buf.append(", "); 32677029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman buf.append(Integer.toHexString( 32777029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman mSigningDetails.pastSigningCertificates[i].hashCode())); 32877029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman buf.append(" flags: "); 32977029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman buf.append(Integer.toHexString(mSigningDetails.pastSigningCertificatesFlags[i])); 33077029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 33177029c5b16351775cb2333369ef9a4bc1d9acf58Daniel Cashman } 332be6c065d2c2ec960a266da88e6cd5bd33f15fde7Dan Cashman buf.append("]}"); 333cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root return buf.toString(); 334cf0b38ca6e5aa5efded7dbdbb623f6cd2746c96aKenny Root } 3357ee17aa6b228a007129147c7a6e9ecba2a40d892Dan Cashman} 336