blob: ee7c15b04d67f372949b603e4a8f3e8a36a89fb3 [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 libcore.java.security.cert;
import tests.support.resource.Support_Resources;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.security.Provider;
import java.security.Security;
import java.security.cert.CRL;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import junit.framework.TestCase;
public class X509CRLTest extends TestCase {
private Provider[] mX509Providers;
private static final String CERT_RSA = "x509/cert-rsa.der";
private static final String CERT_DSA = "x509/cert-dsa.der";
private static final String CRL_RSA = "x509/crl-rsa.der";
private static final String CRL_RSA_DSA = "x509/crl-rsa-dsa.der";
private static final String CRL_UNSUPPORTED = "x509/crl-unsupported.der";
private static final String CRL_RSA_DATES = "x509/crl-rsa-dates.txt";
private static final String CRL_RSA_DSA_DATES = "x509/crl-rsa-dsa-dates.txt";
private static final String CRL_RSA_SIG = "x509/crl-rsa-sig.der";
private static final String CRL_RSA_TBS = "x509/crl-rsa-tbs.der";
private final X509Certificate getCertificate(CertificateFactory f, String name)
throws Exception {
final InputStream is = Support_Resources.getStream(name);
assertNotNull("File does not exist: " + name, is);
try {
X509Certificate c = (X509Certificate) f.generateCertificate(is);
assertNotNull(c);
return c;
} finally {
try {
is.close();
} catch (IOException ignored) {
}
}
}
private final X509CRL getCRL(CertificateFactory f, String name) throws Exception {
final InputStream is = Support_Resources.getStream(name);
assertNotNull("File does not exist: " + name, is);
try {
X509CRL crl = (X509CRL) f.generateCRL(is);
assertNotNull(crl);
return crl;
} finally {
try {
is.close();
} catch (IOException ignored) {
}
}
}
private byte[] getResourceAsBytes(String name) throws Exception {
final InputStream ris = Support_Resources.getStream(name);
try {
DataInputStream dis = new DataInputStream(ris);
byte[] buf = new byte[ris.available()];
dis.readFully(buf);
return buf;
} finally {
try {
ris.close();
} catch (IOException ignored) {
}
}
}
private Map<String, Date> getCrlDates(String name) throws Exception {
Map<String, Date> dates = new HashMap<String, Date>();
final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz");
final InputStream ris = Support_Resources.getStream(name);
try {
final BufferedReader buf = new BufferedReader(new InputStreamReader(ris));
String line;
while ((line = buf.readLine()) != null) {
int index = line.indexOf('=');
String key = line.substring(0, index);
final Date value = sdf.parse(line.substring(index + 1));
dates.put(key, value);
}
return dates;
} finally {
try {
ris.close();
} catch (IOException ignored) {
}
}
}
public void test_Provider() throws Exception {
final ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();
PrintStream out = new PrintStream(errBuffer);
for (Provider p : mX509Providers) {
try {
CertificateFactory f = CertificateFactory.getInstance("X.509", p);
isRevoked(f);
getType(f);
getEncoded(f);
getVersion(f);
hasUnsupportedCriticalExtension(f);
getSignature(f);
getTBSCertList(f);
getRevokedCertificates(f);
getThisUpdateNextUpdate(f);
getSigAlgName(f);
getSigAlgOID(f);
test_toString(f);
test_equals(f);
} catch (Throwable e) {
out.append("Error encountered checking " + p.getName() + "\n");
e.printStackTrace(out);
}
}
out.flush();
if (errBuffer.size() > 0) {
throw new Exception("Errors encountered:\n\n" + errBuffer.toString() + "\n\n");
}
}
private void getType(CertificateFactory f) throws Exception {
CRL crlRsa = getCRL(f, CRL_RSA);
assertEquals("X.509", crlRsa.getType());
}
private void isRevoked(CertificateFactory f) throws Exception {
X509Certificate rsaCert = getCertificate(f, CERT_RSA);
X509Certificate dsaCert = getCertificate(f, CERT_DSA);
X509CRL crlRsa = getCRL(f, CRL_RSA);
X509CRL crlRsaDsa = getCRL(f, CRL_RSA_DSA);
assertTrue(crlRsa.isRevoked(rsaCert));
assertFalse(crlRsa.isRevoked(dsaCert));
assertTrue(crlRsaDsa.isRevoked(rsaCert));
assertTrue(crlRsaDsa.isRevoked(dsaCert));
try {
assertFalse(crlRsa.isRevoked(null));
if ("BC".equals(f.getProvider().getName())) {
fail("BouncyCastle throws on null input");
}
} catch (NullPointerException e) {
if (!"BC".equals(f.getProvider().getName())) {
fail("Should not throw on null input");
}
}
}
private void getThisUpdateNextUpdate(CertificateFactory f) throws Exception {
{
X509CRL crl = getCRL(f, CRL_RSA);
Map<String, Date> dates = getCrlDates(CRL_RSA_DATES);
Date lastUpdate = dates.get("lastUpdate");
Date nextUpdate = dates.get("nextUpdate");
assertNotNull(lastUpdate);
assertNotNull(nextUpdate);
assertDateEquals(lastUpdate, crl.getThisUpdate());
assertDateEquals(nextUpdate, crl.getNextUpdate());
}
{
X509CRL crl = getCRL(f, CRL_RSA_DSA);
Map<String, Date> dates = getCrlDates(CRL_RSA_DSA_DATES);
Date lastUpdate = dates.get("lastUpdate");
Date nextUpdate = dates.get("nextUpdate");
assertNotNull(lastUpdate);
assertNotNull(nextUpdate);
assertDateEquals(lastUpdate, crl.getThisUpdate());
assertDateEquals(nextUpdate, crl.getNextUpdate());
}
}
private void getSigAlgName(CertificateFactory f) throws Exception {
X509CRL crlRsa = getCRL(f, CRL_RSA);
String actual = crlRsa.getSigAlgName().toUpperCase(Locale.US);
// Bouncycastle is broken
if ("BC".equals(f.getProvider().getName())) {
assertEquals("1.2.840.113549.1.1.5", actual);
} else {
assertEquals("SHA1WITHRSA", actual);
}
}
private void getSigAlgOID(CertificateFactory f) throws Exception {
X509CRL crlRsa = getCRL(f, CRL_RSA);
assertEquals("1.2.840.113549.1.1.5", crlRsa.getSigAlgOID());
}
private void getVersion(CertificateFactory f) throws Exception {
X509CRL crlRsa = getCRL(f, CRL_RSA);
assertEquals(1, crlRsa.getVersion());
}
private void hasUnsupportedCriticalExtension(CertificateFactory f) throws Exception {
X509CRL crlRsa = getCRL(f, CRL_RSA);
assertFalse(crlRsa.hasUnsupportedCriticalExtension());
X509CRL unsupportedCrl = getCRL(f, CRL_UNSUPPORTED);
assertTrue(unsupportedCrl.hasUnsupportedCriticalExtension());
}
private void getSignature(CertificateFactory f) throws Exception {
X509CRL crlRsa = getCRL(f, CRL_RSA);
byte[] expected = getResourceAsBytes(CRL_RSA_SIG);
assertEquals(Arrays.toString(expected), Arrays.toString(crlRsa.getSignature()));
}
private void getTBSCertList(CertificateFactory f) throws Exception {
X509CRL crlRsa = getCRL(f, CRL_RSA);
byte[] expected = getResourceAsBytes(CRL_RSA_TBS);
assertEquals(Arrays.toString(expected), Arrays.toString(crlRsa.getTBSCertList()));
}
private void getEncoded(CertificateFactory f) throws Exception {
X509CRL crlRsa = getCRL(f, CRL_RSA);
byte[] crlRsaBytes = getResourceAsBytes(CRL_RSA);
assertEquals(Arrays.toString(crlRsaBytes), Arrays.toString(crlRsa.getEncoded()));
}
private static void assertDateEquals(Date date1, Date date2) throws Exception {
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
String result1 = formatter.format(date1);
String result2 = formatter.format(date2);
assertEquals(result1, result2);
}
private void assertRsaCrl(CertificateFactory f, X509CRLEntry rsaEntry) throws Exception {
assertNotNull(rsaEntry);
X509Certificate rsaCert = getCertificate(f, CERT_RSA);
Map<String, Date> dates = getCrlDates(CRL_RSA_DSA_DATES);
Date expectedDate = dates.get("lastUpdate");
assertEquals(rsaCert.getSerialNumber(), rsaEntry.getSerialNumber());
assertDateEquals(expectedDate, rsaEntry.getRevocationDate());
assertNull(rsaEntry.getCertificateIssuer());
assertFalse(rsaEntry.hasExtensions());
assertNull(rsaEntry.getCriticalExtensionOIDs());
assertNull(rsaEntry.getNonCriticalExtensionOIDs());
}
private void assertDsaCrl(CertificateFactory f, X509CRLEntry dsaEntry) throws Exception {
X509Certificate dsaCert = getCertificate(f, CERT_DSA);
Map<String, Date> dates = getCrlDates(CRL_RSA_DSA_DATES);
Date expectedDate = dates.get("lastUpdate");
assertEquals(dsaCert.getSerialNumber(), dsaEntry.getSerialNumber());
assertDateEquals(expectedDate, dsaEntry.getRevocationDate());
assertNull(dsaEntry.getCertificateIssuer());
assertTrue(dsaEntry.hasExtensions());
/* TODO: get the OID */
assertNotNull(dsaEntry.getCriticalExtensionOIDs());
/* TODO: get the OID */
assertNotNull(dsaEntry.getNonCriticalExtensionOIDs());
}
private void getRevokedCertificates(CertificateFactory f) throws Exception {
X509CRL crlRsa = getCRL(f, CRL_RSA);
X509Certificate rsaCert = getCertificate(f, CERT_RSA);
X509Certificate dsaCert = getCertificate(f, CERT_DSA);
Set<? extends X509CRLEntry> entries = crlRsa.getRevokedCertificates();
assertEquals(1, entries.size());
for (X509CRLEntry e : entries) {
assertRsaCrl(f, e);
}
X509CRL crlRsaDsa = getCRL(f, CRL_RSA_DSA);
Set<? extends X509CRLEntry> entries2 = crlRsaDsa.getRevokedCertificates();
assertEquals(2, entries2.size());
assertRsaCrl(f, crlRsaDsa.getRevokedCertificate(rsaCert));
assertDsaCrl(f, crlRsaDsa.getRevokedCertificate(dsaCert));
}
private void test_toString(CertificateFactory f) throws Exception {
X509CRL crl1 = getCRL(f, CRL_RSA);
X509CRL crl2 = getCRL(f, CRL_RSA);
X509CRL crlRsaDsa = getCRL(f, CRL_RSA_DSA);
assertNotNull(crl1);
assertNotNull(crlRsaDsa);
assertEquals(crl1.toString(), crl2.toString());
assertFalse(crl1.toString().equals(crlRsaDsa.toString()));
}
private void test_equals(CertificateFactory f) throws Exception {
X509CRL crl1 = getCRL(f, CRL_RSA);
X509CRL crl2 = getCRL(f, CRL_RSA);
X509Certificate rsaCert = getCertificate(f, CERT_RSA);
X509CRL crlRsaDsa = getCRL(f, CRL_RSA_DSA);
assertEquals(crl1, crl2);
assertFalse(crl1.equals(crlRsaDsa));
X509CRLEntry entry1 = crl1.getRevokedCertificate(rsaCert);
assertNotNull(entry1);
X509CRLEntry entry2 = crl2.getRevokedCertificate(rsaCert);
assertNotNull(entry2);
assertEquals(entry1, entry2);
}
@Override
protected void setUp() throws Exception {
super.setUp();
mX509Providers = Security.getProviders("CertificateFactory.X509");
}
}