summaryrefslogtreecommitdiffstats
path: root/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java')
-rw-r--r--luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java175
1 files changed, 175 insertions, 0 deletions
diff --git a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java
new file mode 100644
index 0000000..8359c99
--- /dev/null
+++ b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/CertPinManagerTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+package org.apache.harmony.xnet.provider.jsse;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.security.cert.X509Certificate;
+import java.security.KeyStore;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+import junit.framework.TestCase;
+import libcore.java.security.TestKeyStore;
+
+public class CertPinManagerTest extends TestCase {
+
+ private X509Certificate[] chain;
+ private List<X509Certificate> shortChain;
+ private List<X509Certificate> longChain;
+ private String shortPin;
+ private String longPin;
+ private List<File> tmpFiles = new ArrayList<File>();
+
+ private String writeTmpPinFile(String text) throws Exception {
+ File tmp = File.createTempFile("pins", null);
+ FileWriter fstream = new FileWriter(tmp);
+ fstream.write(text);
+ fstream.close();
+ tmpFiles.add(tmp);
+ return tmp.getPath();
+ }
+
+ private static String getFingerprint(X509Certificate cert) throws NoSuchAlgorithmException {
+ MessageDigest dgst = MessageDigest.getInstance("SHA512");
+ byte[] encoded = cert.getPublicKey().getEncoded();
+ byte[] fingerprint = dgst.digest(encoded);
+ return IntegralToString.bytesToHexString(fingerprint, false);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ // build some valid chains
+ KeyStore.PrivateKeyEntry pke = TestKeyStore.getServer().getPrivateKey("RSA", "RSA");
+ chain = (X509Certificate[]) pke.getCertificateChain();
+ X509Certificate root = chain[2];
+ X509Certificate server = chain[0];
+
+ // build the short and long chains
+ shortChain = new ArrayList<X509Certificate>();
+ shortChain.add(root);
+ longChain = new ArrayList<X509Certificate>();
+ longChain.add(server);
+
+ // we'll use the root as the pin for the short entry and the server as the pin for the long
+ shortPin = getFingerprint(root);
+ longPin = getFingerprint(server);
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ try {
+ for (File f : tmpFiles) {
+ f.delete();
+ }
+ tmpFiles.clear();
+ } finally {
+ super.tearDown();
+ }
+ }
+
+ public void testPinFileMaximumLookup() throws Exception {
+
+ // write a pinfile with two entries, one longer than the other
+ String shortEntry = "*.google.com=true|" + shortPin;
+ String longEntry = "*.clients.google.com=true|" + longPin;
+
+ // create the pinFile
+ String path = writeTmpPinFile(shortEntry + "\n" + longEntry);
+ CertPinManager pf = new CertPinManager(path, new TrustedCertificateStore());
+
+ // verify that the shorter chain doesn't work for a name matching the longer
+ assertTrue("short chain long uri failed",
+ pf.chainIsNotPinned("android.clients.google.com", shortChain));
+ // verify that the longer chain doesn't work for a name matching the shorter
+ assertTrue("long chain short uri failed",
+ pf.chainIsNotPinned("android.google.com", longChain));
+ // verify that the shorter chain works for the shorter domain
+ assertTrue("short chain short uri failed",
+ !pf.chainIsNotPinned("android.google.com", shortChain));
+ // and the same for the longer
+ assertTrue("long chain long uri failed",
+ !pf.chainIsNotPinned("android.clients.google.com", longChain));
+ }
+
+ public void testPinEntryMalformedEntry() throws Exception {
+ // set up the pinEntry with a bogus entry
+ String entry = "*.google.com=";
+ try {
+ new PinListEntry(entry, new TrustedCertificateStore());
+ fail("Accepted an empty pin list entry.");
+ } catch (PinEntryException expected) {
+ }
+ }
+
+ public void testPinEntryNull() throws Exception {
+ // set up the pinEntry with a bogus entry
+ String entry = null;
+ try {
+ new PinListEntry(entry, new TrustedCertificateStore());
+ fail("Accepted a basically wholly bogus entry.");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testPinEntryEmpty() throws Exception {
+ // set up the pinEntry with a bogus entry
+ try {
+ new PinListEntry("", new TrustedCertificateStore());
+ fail("Accepted an empty entry.");
+ } catch (PinEntryException expected) {
+ }
+ }
+
+ public void testPinEntryPinFailure() throws Exception {
+ // write a pinfile with two entries, one longer than the other
+ String shortEntry = "*.google.com=true|" + shortPin;
+
+ // set up the pinEntry with a pinlist that doesn't match what we'll give it
+ PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
+ assertTrue("Not enforcing!", e.getEnforcing());
+ // verify that it doesn't accept
+ boolean retval = e.chainIsNotPinned(longChain);
+ assertTrue("Accepted an incorrect pinning, this is very bad", retval);
+ }
+
+ public void testPinEntryPinSuccess() throws Exception {
+ // write a pinfile with two entries, one longer than the other
+ String shortEntry = "*.google.com=true|" + shortPin;
+
+ // set up the pinEntry with a pinlist that matches what we'll give it
+ PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
+ assertTrue("Not enforcing!", e.getEnforcing());
+ // verify that it accepts
+ boolean retval = e.chainIsNotPinned(shortChain);
+ assertTrue("Failed on a correct pinning, this is very bad", !retval);
+ }
+
+ public void testPinEntryNonEnforcing() throws Exception {
+ // write a pinfile with two entries, one longer than the other
+ String shortEntry = "*.google.com=false|" + shortPin;
+
+ // set up the pinEntry with a pinlist that matches what we'll give it
+ PinListEntry e = new PinListEntry(shortEntry, new TrustedCertificateStore());
+ assertFalse("Enforcing!", e.getEnforcing());
+ // verify that it accepts
+ boolean retval = e.chainIsNotPinned(shortChain);
+ assertTrue("Failed on an unenforced pinning, this is bad-ish", !retval);
+ }
+}