blob: b374f56c3c0a521552917d39db3ef58b1b097565 [file] [log] [blame]
/*
* 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 com.android.org.bouncycastle.jce.provider;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.cert.CertificateFactory;
import java.security.cert.Certificate;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
import com.android.org.bouncycastle.jce.provider.CertBlacklist;
import com.android.org.bouncycastle.crypto.Digest;
import com.android.org.bouncycastle.util.encoders.Base64;
import com.android.org.bouncycastle.util.encoders.Hex;
public class CertBlacklistTest extends TestCase {
private File tmpFile;
private Set<String> DEFAULT_PUBKEYS;
private Set<String> DEFAULT_SERIALS;
public static final String TEST_CERT = "" +
"MIIDsjCCAxugAwIBAgIJAPLf2gS0zYGUMA0GCSqGSIb3DQEBBQUAMIGYMQswCQYDVQQGEwJVUzET" +
"MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEPMA0GA1UEChMGR29v" +
"Z2xlMRAwDgYDVQQLEwd0ZXN0aW5nMRYwFAYDVQQDEw1HZXJlbXkgQ29uZHJhMSEwHwYJKoZIhvcN" +
"AQkBFhJnY29uZHJhQGdvb2dsZS5jb20wHhcNMTIwNzE0MTc1MjIxWhcNMTIwODEzMTc1MjIxWjCB" +
"mDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZp" +
"ZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHdGVzdGluZzEWMBQGA1UEAxMNR2VyZW15IENv" +
"bmRyYTEhMB8GCSqGSIb3DQEJARYSZ2NvbmRyYUBnb29nbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUA" +
"A4GNADCBiQKBgQCjGGHATBYlmas+0sEECkno8LZ1KPglb/mfe6VpCT3GhSr+7br7NG/ZwGZnEhLq" +
"E7YIH4fxltHmQC3Tz+jM1YN+kMaQgRRjo/LBCJdOKaMwUbkVynAH6OYsKevjrOPk8lfM5SFQzJMG" +
"sA9+Tfopr5xg0BwZ1vA/+E3mE7Tr3M2UvwIDAQABo4IBADCB/TAdBgNVHQ4EFgQUhzkS9E6G+x8W" +
"L4EsmRjDxu28tHUwgc0GA1UdIwSBxTCBwoAUhzkS9E6G+x8WL4EsmRjDxu28tHWhgZ6kgZswgZgx" +
"CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3" +
"MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB3Rlc3RpbmcxFjAUBgNVBAMTDUdlcmVteSBDb25k" +
"cmExITAfBgkqhkiG9w0BCQEWEmdjb25kcmFAZ29vZ2xlLmNvbYIJAPLf2gS0zYGUMAwGA1UdEwQF" +
"MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAYiugFDmbDOQ2U/+mqNt7o8ftlEo9SJrns6O8uTtK6AvR" +
"orDrR1AXTXkuxwLSbmVfedMGOZy7Awh7iZa8hw5x9XmUudfNxvmrKVEwGQY2DZ9PXbrnta/dwbhK" +
"mWfoepESVbo7CKIhJp8gRW0h1Z55ETXD57aGJRvQS4pxkP8ANhM=";
public CertBlacklistTest() throws IOException {
tmpFile = File.createTempFile("test", "");
DEFAULT_PUBKEYS = getDefaultPubkeys();
DEFAULT_SERIALS = getDefaultSerials();
tmpFile.delete();
}
@Override
public void setUp() throws Exception {
super.setUp();
tmpFile = File.createTempFile("test", "");
}
@Override
public void tearDown() throws Exception {
try {
tmpFile.delete();
} finally {
super.tearDown();
}
}
private Set<String> getPubkeyBlacklist(String path) throws IOException {
// set our blacklist path
CertBlacklist bl = new CertBlacklist(path, CertBlacklist.DEFAULT_SERIAL_BLACKLIST_PATH);
// call readPubkeyBlacklist
Set<byte[]> arr = bl.pubkeyBlacklist;
// convert the results to a hashset of strings
Set<String> results = new HashSet<String>();
for (byte[] value: arr) {
results.add(new String(value));
}
return results;
}
private Set<String> getSerialBlacklist(String path) throws IOException {
// set our blacklist path
CertBlacklist bl = new CertBlacklist(CertBlacklist.DEFAULT_PUBKEY_BLACKLIST_PATH, path);
// call readPubkeyBlacklist
Set<BigInteger> arr = bl.serialBlacklist;
// convert the results to a hashset of strings
Set<String> results = new HashSet<String>();
for (BigInteger value: arr) {
results.add(value.toString(16));
}
return results;
}
private String getHash(PublicKey publicKey) throws Exception {
byte[] encoded = publicKey.getEncoded();
MessageDigest digest = MessageDigest.getInstance("SHA1");
byte[] hexlifiedHash = Hex.encode(digest.digest(encoded));
return new String(hexlifiedHash);
}
private Set<String> getDefaultPubkeys() throws IOException {
return getPubkeyBlacklist("");
}
private Set<String> getDefaultSerials() throws IOException {
return getSerialBlacklist("");
}
private Set<String> getCurrentPubkeyBlacklist() throws IOException {
return getPubkeyBlacklist(tmpFile.getCanonicalPath());
}
private Set<String> getCurrentSerialBlacklist() throws IOException {
return getSerialBlacklist(tmpFile.getCanonicalPath());
}
private void blacklistToFile(String blacklist) throws IOException {
FileOutputStream out = new FileOutputStream(tmpFile);
out.write(blacklist.toString().getBytes());
out.close();
}
private void writeBlacklist(HashSet<String> values) throws IOException {
StringBuilder result = new StringBuilder();
// join the values into a string
for (String value : values) {
if (result.length() != 0) {
result.append(",");
}
result.append(value);
}
blacklistToFile(result.toString());
}
private PublicKey createPublicKey(String cert) throws Exception {
byte[] derCert = Base64.decode(cert.getBytes());
InputStream istream = new ByteArrayInputStream(derCert);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
return cf.generateCertificate(istream).getPublicKey();
}
public void testPubkeyBlacklistLegit() throws Exception {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
// write the blacklist
writeBlacklist(bl);
// add the default pubkeys into the bl
bl.addAll(DEFAULT_PUBKEYS);
// do the test
assertEquals(bl, getCurrentPubkeyBlacklist());
}
public void testLegitPubkeyIsntBlacklisted() throws Exception {
// build the public key
PublicKey pk = createPublicKey(TEST_CERT);
// write that to the test blacklist
writeBlacklist(new HashSet<String>());
// set our blacklist path
CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(),
CertBlacklist.DEFAULT_SERIAL_BLACKLIST_PATH);
// check to make sure it isn't blacklisted
assertEquals(bl.isPublicKeyBlackListed(pk), false);
}
public void testPubkeyIsBlacklisted() throws Exception {
// build the public key
PublicKey pk = createPublicKey(TEST_CERT);
// get its hash
String hash = getHash(pk);
// write that to the test blacklist
HashSet<String> testBlackList = new HashSet<String>();
testBlackList.add(hash);
writeBlacklist(testBlackList);
// set our blacklist path
CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(),
CertBlacklist.DEFAULT_SERIAL_BLACKLIST_PATH);
// check to make sure it isn't blacklited
assertTrue(bl.isPublicKeyBlackListed(pk));
}
public void testSerialBlacklistLegit() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
// write the blacklist
writeBlacklist(bl);
// add the default serials into the bl
bl.addAll(DEFAULT_SERIALS);
// do the test
assertEquals(bl, getCurrentSerialBlacklist());
}
public void testPubkeyBlacklistMultipleLegit() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
// write the blacklist
writeBlacklist(bl);
// add the default pubkeys into the bl
bl.addAll(DEFAULT_PUBKEYS);
// do the test
assertEquals(bl, getCurrentPubkeyBlacklist());
}
public void testSerialBlacklistMultipleLegit() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
// write the blacklist
writeBlacklist(bl);
// add the default serials into the bl
bl.addAll(DEFAULT_SERIALS);
// do the test
assertEquals(bl, getCurrentSerialBlacklist());
}
public void testPubkeyBlacklistMultipleBad() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
bl.add("");
bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
// write the blacklist
writeBlacklist(bl);
// add the default pubkeys into the bl
bl.addAll(DEFAULT_PUBKEYS);
// remove the bad one
bl.remove("");
// do the test- results should be all but the bad one are handled
assertEquals(bl, getCurrentPubkeyBlacklist());
}
public void testSerialBlacklistMultipleBad() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
bl.add("");
bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
// write the blacklist
writeBlacklist(bl);
// add the default serials into the bl
bl.addAll(DEFAULT_SERIALS);
// remove the bad one
bl.remove("");
// do the test- results should be all but the bad one are handled
assertEquals(bl, getCurrentSerialBlacklist());
}
public void testPubkeyBlacklistDoesntExist() throws IOException {
assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
}
public void testSerialBlacklistDoesntExist() throws IOException {
assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
}
public void testPubkeyBlacklistNotHexValues() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
// write the blacklist
writeBlacklist(bl);
// do the test
assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
}
public void testSerialBlacklistNotHexValues() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
// write the blacklist
writeBlacklist(bl);
// do the test
assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
}
public void testPubkeyBlacklistIncorrectLength() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091cc");
// write the blacklist
writeBlacklist(bl);
// do the test
assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
}
public void testSerialBlacklistZero() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("0");
// write the blacklist
writeBlacklist(bl);
// add the default serials
bl.addAll(DEFAULT_SERIALS);
// do the test
assertEquals(bl, getCurrentSerialBlacklist());
}
public void testSerialBlacklistNegative() throws IOException {
// build the blacklist
HashSet<String> bl = new HashSet<String>();
bl.add("-1");
// write the blacklist
writeBlacklist(bl);
// add the default serials
bl.addAll(DEFAULT_SERIALS);
// do the test
assertEquals(bl, getCurrentSerialBlacklist());
}
}