Loading services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/CertUtils.java +15 −11 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.locksettings.recoverablekeystore.certificate; import static javax.xml.xpath.XPathConstants.NODESET; import android.annotation.IntDef; import android.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; Loading @@ -25,6 +26,8 @@ import com.android.internal.annotations.VisibleForTesting; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; Loading Loading @@ -72,13 +75,14 @@ final class CertUtils { private static final String CERT_STORE_ALG = "Collection"; private static final String SIGNATURE_ALG = "SHA256withRSA"; private CertUtils() {} @Retention(RetentionPolicy.SOURCE) @IntDef({MUST_EXIST_UNENFORCED, MUST_EXIST_EXACTLY_ONE, MUST_EXIST_AT_LEAST_ONE}) @interface MustExist {} static final int MUST_EXIST_UNENFORCED = 0; static final int MUST_EXIST_EXACTLY_ONE = 1; static final int MUST_EXIST_AT_LEAST_ONE = 2; enum MustExist { FALSE, EXACTLY_ONE, AT_LEAST_ONE, } private CertUtils() {} /** * Decodes a byte array containing an encoded X509 certificate. Loading Loading @@ -159,7 +163,7 @@ final class CertUtils { * @return a list of strings that are the text contents of the child nodes * @throws CertParsingException if any parsing error occurs */ static List<String> getXmlNodeContents(MustExist mustExist, Element rootNode, static List<String> getXmlNodeContents(@MustExist int mustExist, Element rootNode, String... nodeTags) throws CertParsingException { String expression = String.join("/", nodeTags); Loading @@ -173,10 +177,10 @@ final class CertUtils { } switch (mustExist) { case FALSE: case MUST_EXIST_UNENFORCED: break; case EXACTLY_ONE: case MUST_EXIST_EXACTLY_ONE: if (nodeList.getLength() != 1) { throw new CertParsingException( "The XML file must contain exactly one node with the path " Loading @@ -184,7 +188,7 @@ final class CertUtils { } break; case AT_LEAST_ONE: case MUST_EXIST_AT_LEAST_ONE: if (nodeList.getLength() == 0) { throw new CertParsingException( "The XML file must contain at least one node with the path " Loading @@ -194,7 +198,7 @@ final class CertUtils { default: throw new UnsupportedOperationException( "This enum value of MustExist is not supported: " + mustExist); "This value of MustExist is not supported: " + mustExist); } List<String> result = new ArrayList<>(); Loading services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/CertXml.java +4 −4 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ public final class CertXml { private static long parseSerial(Element rootNode) throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, CertUtils.MUST_EXIST_EXACTLY_ONE, rootNode, METADATA_NODE_TAG, METADATA_SERIAL_NODE_TAG); Loading @@ -139,7 +139,7 @@ public final class CertXml { private static long parseRefreshInterval(Element rootNode) throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, CertUtils.MUST_EXIST_EXACTLY_ONE, rootNode, METADATA_NODE_TAG, METADATA_REFRESH_INTERVAL_NODE_TAG); Loading @@ -150,7 +150,7 @@ public final class CertXml { throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.FALSE, CertUtils.MUST_EXIST_UNENFORCED, rootNode, INTERMEDIATE_CERT_LIST_TAG, INTERMEDIATE_CERT_ITEM_TAG); Loading @@ -165,7 +165,7 @@ public final class CertXml { throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.AT_LEAST_ONE, CertUtils.MUST_EXIST_AT_LEAST_ONE, rootNode, ENDPOINT_CERT_LIST_TAG, ENDPOINT_CERT_ITEM_TAG); Loading services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/SigXml.java +3 −3 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ public final class SigXml { throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.FALSE, CertUtils.MUST_EXIST_UNENFORCED, rootNode, INTERMEDIATE_CERT_LIST_TAG, INTERMEDIATE_CERT_ITEM_TAG); Loading @@ -108,14 +108,14 @@ public final class SigXml { private static X509Certificate parseSignerCert(Element rootNode) throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, rootNode, SIGNER_CERT_NODE_TAG); CertUtils.MUST_EXIST_EXACTLY_ONE, rootNode, SIGNER_CERT_NODE_TAG); return CertUtils.decodeCert(CertUtils.decodeBase64(contents.get(0))); } private static byte[] parseFileSignature(Element rootNode) throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, rootNode, SIGNATURE_NODE_TAG); CertUtils.MUST_EXIST_EXACTLY_ONE, rootNode, SIGNATURE_NODE_TAG); return CertUtils.decodeBase64(contents.get(0)); } } services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertUtilsTest.java +6 −6 Original line number Diff line number Diff line Loading @@ -146,14 +146,14 @@ public final class CertUtilsTest { @Test public void getXmlNodeContents_singleLevel_succeeds() throws Exception { Element root = CertUtils.getXmlRootNode(XML_STR.getBytes(UTF_8)); assertThat(CertUtils.getXmlNodeContents(CertUtils.MustExist.FALSE, root, "node1")) assertThat(CertUtils.getXmlNodeContents(CertUtils.MUST_EXIST_UNENFORCED, root, "node1")) .containsExactly("node1-1", "node1-2"); } @Test public void getXmlNodeContents_multipleLevels_succeeds() throws Exception { Element root = CertUtils.getXmlRootNode(XML_STR.getBytes(UTF_8)); assertThat(CertUtils.getXmlNodeContents(CertUtils.MustExist.FALSE, root, "node2", "node1")) assertThat(CertUtils.getXmlNodeContents(CertUtils.MUST_EXIST_UNENFORCED, root, "node2", "node1")) .containsExactly("node2-node1-1", "node2-node1-2", "node2-node1-3"); } Loading @@ -162,7 +162,7 @@ public final class CertUtilsTest { Element root = CertUtils.getXmlRootNode(XML_STR.getBytes(UTF_8)); assertThat( CertUtils.getXmlNodeContents( CertUtils.MustExist.FALSE, root, "node2", "node-not-exist")) CertUtils.MUST_EXIST_UNENFORCED, root, "node2", "node-not-exist")) .isEmpty(); } Loading @@ -174,7 +174,7 @@ public final class CertUtilsTest { CertParsingException.class, () -> CertUtils.getXmlNodeContents( CertUtils.MustExist.AT_LEAST_ONE, root, "node2", CertUtils.MUST_EXIST_AT_LEAST_ONE, root, "node2", "node-not-exist")); assertThat(expected.getMessage()).contains("must contain at least one"); } Loading @@ -187,7 +187,7 @@ public final class CertUtilsTest { CertParsingException.class, () -> CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, root, "node-not-exist", CertUtils.MUST_EXIST_EXACTLY_ONE, root, "node-not-exist", "node1")); assertThat(expected.getMessage()).contains("must contain exactly one"); } Loading @@ -200,7 +200,7 @@ public final class CertUtilsTest { CertParsingException.class, () -> CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, root, "node2", "node1")); CertUtils.MUST_EXIST_EXACTLY_ONE, root, "node2", "node1")); assertThat(expected.getMessage()).contains("must contain exactly one"); } Loading Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/CertUtils.java +15 −11 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.locksettings.recoverablekeystore.certificate; import static javax.xml.xpath.XPathConstants.NODESET; import android.annotation.IntDef; import android.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; Loading @@ -25,6 +26,8 @@ import com.android.internal.annotations.VisibleForTesting; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; Loading Loading @@ -72,13 +75,14 @@ final class CertUtils { private static final String CERT_STORE_ALG = "Collection"; private static final String SIGNATURE_ALG = "SHA256withRSA"; private CertUtils() {} @Retention(RetentionPolicy.SOURCE) @IntDef({MUST_EXIST_UNENFORCED, MUST_EXIST_EXACTLY_ONE, MUST_EXIST_AT_LEAST_ONE}) @interface MustExist {} static final int MUST_EXIST_UNENFORCED = 0; static final int MUST_EXIST_EXACTLY_ONE = 1; static final int MUST_EXIST_AT_LEAST_ONE = 2; enum MustExist { FALSE, EXACTLY_ONE, AT_LEAST_ONE, } private CertUtils() {} /** * Decodes a byte array containing an encoded X509 certificate. Loading Loading @@ -159,7 +163,7 @@ final class CertUtils { * @return a list of strings that are the text contents of the child nodes * @throws CertParsingException if any parsing error occurs */ static List<String> getXmlNodeContents(MustExist mustExist, Element rootNode, static List<String> getXmlNodeContents(@MustExist int mustExist, Element rootNode, String... nodeTags) throws CertParsingException { String expression = String.join("/", nodeTags); Loading @@ -173,10 +177,10 @@ final class CertUtils { } switch (mustExist) { case FALSE: case MUST_EXIST_UNENFORCED: break; case EXACTLY_ONE: case MUST_EXIST_EXACTLY_ONE: if (nodeList.getLength() != 1) { throw new CertParsingException( "The XML file must contain exactly one node with the path " Loading @@ -184,7 +188,7 @@ final class CertUtils { } break; case AT_LEAST_ONE: case MUST_EXIST_AT_LEAST_ONE: if (nodeList.getLength() == 0) { throw new CertParsingException( "The XML file must contain at least one node with the path " Loading @@ -194,7 +198,7 @@ final class CertUtils { default: throw new UnsupportedOperationException( "This enum value of MustExist is not supported: " + mustExist); "This value of MustExist is not supported: " + mustExist); } List<String> result = new ArrayList<>(); Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/CertXml.java +4 −4 Original line number Diff line number Diff line Loading @@ -129,7 +129,7 @@ public final class CertXml { private static long parseSerial(Element rootNode) throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, CertUtils.MUST_EXIST_EXACTLY_ONE, rootNode, METADATA_NODE_TAG, METADATA_SERIAL_NODE_TAG); Loading @@ -139,7 +139,7 @@ public final class CertXml { private static long parseRefreshInterval(Element rootNode) throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, CertUtils.MUST_EXIST_EXACTLY_ONE, rootNode, METADATA_NODE_TAG, METADATA_REFRESH_INTERVAL_NODE_TAG); Loading @@ -150,7 +150,7 @@ public final class CertXml { throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.FALSE, CertUtils.MUST_EXIST_UNENFORCED, rootNode, INTERMEDIATE_CERT_LIST_TAG, INTERMEDIATE_CERT_ITEM_TAG); Loading @@ -165,7 +165,7 @@ public final class CertXml { throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.AT_LEAST_ONE, CertUtils.MUST_EXIST_AT_LEAST_ONE, rootNode, ENDPOINT_CERT_LIST_TAG, ENDPOINT_CERT_ITEM_TAG); Loading
services/core/java/com/android/server/locksettings/recoverablekeystore/certificate/SigXml.java +3 −3 Original line number Diff line number Diff line Loading @@ -94,7 +94,7 @@ public final class SigXml { throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.FALSE, CertUtils.MUST_EXIST_UNENFORCED, rootNode, INTERMEDIATE_CERT_LIST_TAG, INTERMEDIATE_CERT_ITEM_TAG); Loading @@ -108,14 +108,14 @@ public final class SigXml { private static X509Certificate parseSignerCert(Element rootNode) throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, rootNode, SIGNER_CERT_NODE_TAG); CertUtils.MUST_EXIST_EXACTLY_ONE, rootNode, SIGNER_CERT_NODE_TAG); return CertUtils.decodeCert(CertUtils.decodeBase64(contents.get(0))); } private static byte[] parseFileSignature(Element rootNode) throws CertParsingException { List<String> contents = CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, rootNode, SIGNATURE_NODE_TAG); CertUtils.MUST_EXIST_EXACTLY_ONE, rootNode, SIGNATURE_NODE_TAG); return CertUtils.decodeBase64(contents.get(0)); } }
services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/certificate/CertUtilsTest.java +6 −6 Original line number Diff line number Diff line Loading @@ -146,14 +146,14 @@ public final class CertUtilsTest { @Test public void getXmlNodeContents_singleLevel_succeeds() throws Exception { Element root = CertUtils.getXmlRootNode(XML_STR.getBytes(UTF_8)); assertThat(CertUtils.getXmlNodeContents(CertUtils.MustExist.FALSE, root, "node1")) assertThat(CertUtils.getXmlNodeContents(CertUtils.MUST_EXIST_UNENFORCED, root, "node1")) .containsExactly("node1-1", "node1-2"); } @Test public void getXmlNodeContents_multipleLevels_succeeds() throws Exception { Element root = CertUtils.getXmlRootNode(XML_STR.getBytes(UTF_8)); assertThat(CertUtils.getXmlNodeContents(CertUtils.MustExist.FALSE, root, "node2", "node1")) assertThat(CertUtils.getXmlNodeContents(CertUtils.MUST_EXIST_UNENFORCED, root, "node2", "node1")) .containsExactly("node2-node1-1", "node2-node1-2", "node2-node1-3"); } Loading @@ -162,7 +162,7 @@ public final class CertUtilsTest { Element root = CertUtils.getXmlRootNode(XML_STR.getBytes(UTF_8)); assertThat( CertUtils.getXmlNodeContents( CertUtils.MustExist.FALSE, root, "node2", "node-not-exist")) CertUtils.MUST_EXIST_UNENFORCED, root, "node2", "node-not-exist")) .isEmpty(); } Loading @@ -174,7 +174,7 @@ public final class CertUtilsTest { CertParsingException.class, () -> CertUtils.getXmlNodeContents( CertUtils.MustExist.AT_LEAST_ONE, root, "node2", CertUtils.MUST_EXIST_AT_LEAST_ONE, root, "node2", "node-not-exist")); assertThat(expected.getMessage()).contains("must contain at least one"); } Loading @@ -187,7 +187,7 @@ public final class CertUtilsTest { CertParsingException.class, () -> CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, root, "node-not-exist", CertUtils.MUST_EXIST_EXACTLY_ONE, root, "node-not-exist", "node1")); assertThat(expected.getMessage()).contains("must contain exactly one"); } Loading @@ -200,7 +200,7 @@ public final class CertUtilsTest { CertParsingException.class, () -> CertUtils.getXmlNodeContents( CertUtils.MustExist.EXACTLY_ONE, root, "node2", "node1")); CertUtils.MUST_EXIST_EXACTLY_ONE, root, "node2", "node1")); assertThat(expected.getMessage()).contains("must contain exactly one"); } Loading