Home | History | Annotate | Download | only in provider
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.org.bouncycastle.jce.provider;
     18 
     19 import java.io.ByteArrayInputStream;
     20 import java.io.File;
     21 import java.io.FileOutputStream;
     22 import java.io.FileNotFoundException;
     23 import java.io.InputStream;
     24 import java.io.IOException;
     25 import java.math.BigInteger;
     26 import java.security.cert.CertificateFactory;
     27 import java.security.cert.Certificate;
     28 import java.security.MessageDigest;
     29 import java.security.PrivateKey;
     30 import java.security.PublicKey;
     31 import java.util.HashSet;
     32 import java.util.Set;
     33 import junit.framework.TestCase;
     34 import com.android.org.bouncycastle.jce.provider.CertBlacklist;
     35 import com.android.org.bouncycastle.crypto.Digest;
     36 import com.android.org.bouncycastle.util.encoders.Base64;
     37 import com.android.org.bouncycastle.util.encoders.Hex;
     38 
     39 public class CertBlacklistTest extends TestCase {
     40 
     41     private File tmpFile;
     42 
     43     private Set<String> DEFAULT_PUBKEYS;
     44     private Set<String> DEFAULT_SERIALS;
     45 
     46     public static final String TEST_CERT = "" +
     47                     "MIIDsjCCAxugAwIBAgIJAPLf2gS0zYGUMA0GCSqGSIb3DQEBBQUAMIGYMQswCQYDVQQGEwJVUzET" +
     48                     "MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEPMA0GA1UEChMGR29v" +
     49                     "Z2xlMRAwDgYDVQQLEwd0ZXN0aW5nMRYwFAYDVQQDEw1HZXJlbXkgQ29uZHJhMSEwHwYJKoZIhvcN" +
     50                     "AQkBFhJnY29uZHJhQGdvb2dsZS5jb20wHhcNMTIwNzE0MTc1MjIxWhcNMTIwODEzMTc1MjIxWjCB" +
     51                     "mDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZp" +
     52                     "ZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHdGVzdGluZzEWMBQGA1UEAxMNR2VyZW15IENv" +
     53                     "bmRyYTEhMB8GCSqGSIb3DQEJARYSZ2NvbmRyYUBnb29nbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUA" +
     54                     "A4GNADCBiQKBgQCjGGHATBYlmas+0sEECkno8LZ1KPglb/mfe6VpCT3GhSr+7br7NG/ZwGZnEhLq" +
     55                     "E7YIH4fxltHmQC3Tz+jM1YN+kMaQgRRjo/LBCJdOKaMwUbkVynAH6OYsKevjrOPk8lfM5SFQzJMG" +
     56                     "sA9+Tfopr5xg0BwZ1vA/+E3mE7Tr3M2UvwIDAQABo4IBADCB/TAdBgNVHQ4EFgQUhzkS9E6G+x8W" +
     57                     "L4EsmRjDxu28tHUwgc0GA1UdIwSBxTCBwoAUhzkS9E6G+x8WL4EsmRjDxu28tHWhgZ6kgZswgZgx" +
     58                     "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3" +
     59                     "MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB3Rlc3RpbmcxFjAUBgNVBAMTDUdlcmVteSBDb25k" +
     60                     "cmExITAfBgkqhkiG9w0BCQEWEmdjb25kcmFAZ29vZ2xlLmNvbYIJAPLf2gS0zYGUMAwGA1UdEwQF" +
     61                     "MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAYiugFDmbDOQ2U/+mqNt7o8ftlEo9SJrns6O8uTtK6AvR" +
     62                     "orDrR1AXTXkuxwLSbmVfedMGOZy7Awh7iZa8hw5x9XmUudfNxvmrKVEwGQY2DZ9PXbrnta/dwbhK" +
     63                     "mWfoepESVbo7CKIhJp8gRW0h1Z55ETXD57aGJRvQS4pxkP8ANhM=";
     64 
     65     public CertBlacklistTest() throws IOException {
     66         tmpFile = File.createTempFile("test", "");
     67         DEFAULT_PUBKEYS = getDefaultPubkeys();
     68         DEFAULT_SERIALS = getDefaultSerials();
     69         tmpFile.delete();
     70     }
     71 
     72     @Override
     73     public void setUp() throws Exception {
     74         super.setUp();
     75         tmpFile = File.createTempFile("test", "");
     76     }
     77 
     78     @Override
     79     public void tearDown() throws Exception {
     80         try {
     81             tmpFile.delete();
     82         } finally {
     83             super.tearDown();
     84         }
     85     }
     86 
     87     private Set<String> getPubkeyBlacklist(String path) throws IOException {
     88         // set our blacklist path
     89         CertBlacklist bl = new CertBlacklist(path, CertBlacklist.DEFAULT_SERIAL_BLACKLIST_PATH);
     90         // call readPubkeyBlacklist
     91         Set<byte[]> arr = bl.pubkeyBlacklist;
     92         // convert the results to a hashset of strings
     93         Set<String> results = new HashSet<String>();
     94         for (byte[] value: arr) {
     95             results.add(new String(value));
     96         }
     97         return results;
     98     }
     99 
    100     private Set<String> getSerialBlacklist(String path) throws IOException {
    101         // set our blacklist path
    102         CertBlacklist bl = new CertBlacklist(CertBlacklist.DEFAULT_PUBKEY_BLACKLIST_PATH, path);
    103         // call readPubkeyBlacklist
    104         Set<BigInteger> arr = bl.serialBlacklist;
    105         // convert the results to a hashset of strings
    106         Set<String> results = new HashSet<String>();
    107         for (BigInteger value: arr) {
    108             results.add(value.toString(16));
    109         }
    110         return results;
    111     }
    112 
    113     private String getHash(PublicKey publicKey) throws Exception {
    114         byte[] encoded = publicKey.getEncoded();
    115         MessageDigest digest = MessageDigest.getInstance("SHA1");
    116         byte[] hexlifiedHash = Hex.encode(digest.digest(encoded));
    117         return new String(hexlifiedHash);
    118     }
    119 
    120     private Set<String> getDefaultPubkeys() throws IOException {
    121         return getPubkeyBlacklist("");
    122     }
    123 
    124     private Set<String> getDefaultSerials() throws IOException {
    125         return getSerialBlacklist("");
    126     }
    127 
    128     private Set<String> getCurrentPubkeyBlacklist() throws IOException {
    129         return getPubkeyBlacklist(tmpFile.getCanonicalPath());
    130     }
    131 
    132     private Set<String> getCurrentSerialBlacklist() throws IOException {
    133         return getSerialBlacklist(tmpFile.getCanonicalPath());
    134     }
    135 
    136     private void blacklistToFile(String blacklist) throws IOException {
    137         FileOutputStream out = new FileOutputStream(tmpFile);
    138         out.write(blacklist.toString().getBytes());
    139         out.close();
    140     }
    141 
    142     private void writeBlacklist(HashSet<String> values) throws IOException {
    143         StringBuilder result = new StringBuilder();
    144         // join the values into a string
    145         for (String value : values) {
    146             if (result.length() != 0) {
    147                 result.append(",");
    148             }
    149             result.append(value);
    150         }
    151         blacklistToFile(result.toString());
    152     }
    153 
    154     private PublicKey createPublicKey(String cert) throws Exception {
    155         byte[] derCert = Base64.decode(cert.getBytes());
    156         InputStream istream = new ByteArrayInputStream(derCert);
    157         CertificateFactory cf = CertificateFactory.getInstance("X.509");
    158         return cf.generateCertificate(istream).getPublicKey();
    159     }
    160 
    161     public void testPubkeyBlacklistLegit() throws Exception {
    162         // build the blacklist
    163         HashSet<String> bl = new HashSet<String>();
    164         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
    165         // write the blacklist
    166         writeBlacklist(bl);
    167         // add the default pubkeys into the bl
    168         bl.addAll(DEFAULT_PUBKEYS);
    169         // do the test
    170         assertEquals(bl, getCurrentPubkeyBlacklist());
    171     }
    172 
    173     public void testLegitPubkeyIsntBlacklisted() throws Exception {
    174         // build the public key
    175         PublicKey pk = createPublicKey(TEST_CERT);
    176         // write that to the test blacklist
    177         writeBlacklist(new HashSet<String>());
    178         // set our blacklist path
    179         CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(),
    180                                              CertBlacklist.DEFAULT_SERIAL_BLACKLIST_PATH);
    181         // check to make sure it isn't blacklisted
    182         assertEquals(bl.isPublicKeyBlackListed(pk), false);
    183     }
    184 
    185     public void testPubkeyIsBlacklisted() throws Exception {
    186         // build the public key
    187         PublicKey pk = createPublicKey(TEST_CERT);
    188         // get its hash
    189         String hash = getHash(pk);
    190         // write that to the test blacklist
    191         HashSet<String> testBlackList = new HashSet<String>();
    192         testBlackList.add(hash);
    193         writeBlacklist(testBlackList);
    194         // set our blacklist path
    195         CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(),
    196                                              CertBlacklist.DEFAULT_SERIAL_BLACKLIST_PATH);
    197         // check to make sure it isn't blacklited
    198         assertTrue(bl.isPublicKeyBlackListed(pk));
    199     }
    200 
    201     public void testSerialBlacklistLegit() throws IOException {
    202         // build the blacklist
    203         HashSet<String> bl = new HashSet<String>();
    204         bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
    205         // write the blacklist
    206         writeBlacklist(bl);
    207         // add the default serials into the bl
    208         bl.addAll(DEFAULT_SERIALS);
    209         // do the test
    210         assertEquals(bl, getCurrentSerialBlacklist());
    211     }
    212 
    213     public void testPubkeyBlacklistMultipleLegit() throws IOException {
    214         // build the blacklist
    215         HashSet<String> bl = new HashSet<String>();
    216         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
    217         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
    218         // write the blacklist
    219         writeBlacklist(bl);
    220         // add the default pubkeys into the bl
    221         bl.addAll(DEFAULT_PUBKEYS);
    222         // do the test
    223         assertEquals(bl, getCurrentPubkeyBlacklist());
    224     }
    225 
    226     public void testSerialBlacklistMultipleLegit() throws IOException {
    227         // build the blacklist
    228         HashSet<String> bl = new HashSet<String>();
    229         bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
    230         bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
    231         // write the blacklist
    232         writeBlacklist(bl);
    233         // add the default serials into the bl
    234         bl.addAll(DEFAULT_SERIALS);
    235         // do the test
    236         assertEquals(bl, getCurrentSerialBlacklist());
    237     }
    238 
    239     public void testPubkeyBlacklistMultipleBad() throws IOException {
    240         // build the blacklist
    241         HashSet<String> bl = new HashSet<String>();
    242         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
    243         bl.add("");
    244         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
    245         // write the blacklist
    246         writeBlacklist(bl);
    247         // add the default pubkeys into the bl
    248         bl.addAll(DEFAULT_PUBKEYS);
    249         // remove the bad one
    250         bl.remove("");
    251         // do the test- results should be all but the bad one are handled
    252         assertEquals(bl, getCurrentPubkeyBlacklist());
    253     }
    254 
    255     public void testSerialBlacklistMultipleBad() throws IOException {
    256         // build the blacklist
    257         HashSet<String> bl = new HashSet<String>();
    258         bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
    259         bl.add("");
    260         bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
    261         // write the blacklist
    262         writeBlacklist(bl);
    263         // add the default serials into the bl
    264         bl.addAll(DEFAULT_SERIALS);
    265         // remove the bad one
    266         bl.remove("");
    267         // do the test- results should be all but the bad one are handled
    268         assertEquals(bl, getCurrentSerialBlacklist());
    269     }
    270 
    271     public void testPubkeyBlacklistDoesntExist() throws IOException {
    272         assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
    273     }
    274 
    275     public void testSerialBlacklistDoesntExist() throws IOException {
    276         assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
    277     }
    278 
    279     public void testPubkeyBlacklistNotHexValues() throws IOException {
    280         // build the blacklist
    281         HashSet<String> bl = new HashSet<String>();
    282         bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
    283         // write the blacklist
    284         writeBlacklist(bl);
    285         // do the test
    286         assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
    287     }
    288 
    289     public void testSerialBlacklistNotHexValues() throws IOException {
    290         // build the blacklist
    291         HashSet<String> bl = new HashSet<String>();
    292         bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
    293         // write the blacklist
    294         writeBlacklist(bl);
    295         // do the test
    296         assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
    297     }
    298 
    299     public void testPubkeyBlacklistIncorrectLength() throws IOException {
    300         // build the blacklist
    301         HashSet<String> bl = new HashSet<String>();
    302         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091cc");
    303         // write the blacklist
    304         writeBlacklist(bl);
    305         // do the test
    306         assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
    307     }
    308 
    309     public void testSerialBlacklistZero() throws IOException {
    310         // build the blacklist
    311         HashSet<String> bl = new HashSet<String>();
    312         bl.add("0");
    313         // write the blacklist
    314         writeBlacklist(bl);
    315         // add the default serials
    316         bl.addAll(DEFAULT_SERIALS);
    317         // do the test
    318         assertEquals(bl, getCurrentSerialBlacklist());
    319     }
    320 
    321     public void testSerialBlacklistNegative() throws IOException {
    322         // build the blacklist
    323         HashSet<String> bl = new HashSet<String>();
    324         bl.add("-1");
    325         // write the blacklist
    326         writeBlacklist(bl);
    327         // add the default serials
    328         bl.addAll(DEFAULT_SERIALS);
    329         // do the test
    330         assertEquals(bl, getCurrentSerialBlacklist());
    331     }
    332 }
    333