1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18/** 19 * @author Alexander Y. Kleymenov 20 */ 21 22package org.apache.harmony.security.tests.x509; 23 24 25import java.io.ByteArrayInputStream; 26import java.io.IOException; 27import java.math.BigInteger; 28import java.security.cert.CertificateFactory; 29import java.security.cert.X509CRL; 30import java.security.cert.X509CRLEntry; 31import java.util.Arrays; 32import java.util.Date; 33import java.util.List; 34import java.util.Set; 35 36import junit.framework.Test; 37import junit.framework.TestCase; 38import junit.framework.TestSuite; 39 40import org.apache.harmony.security.asn1.ASN1GeneralizedTime; 41import org.apache.harmony.security.asn1.ASN1Integer; 42import org.apache.harmony.security.x501.Name; 43import org.apache.harmony.security.x509.AlgorithmIdentifier; 44import org.apache.harmony.security.x509.CertificateList; 45import org.apache.harmony.security.x509.Extension; 46import org.apache.harmony.security.x509.Extensions; 47import org.apache.harmony.security.x509.GeneralName; 48import org.apache.harmony.security.x509.GeneralNames; 49import org.apache.harmony.security.x509.TBSCertList; 50 51/** 52 * CertificateListTest 53 */ 54public class CertificateListTest extends TestCase { 55 56 // OID was taken from http://oid.elibel.tm.fr 57 private static String algOID = "1.2.840.10040.4.3"; 58 //private static String algName = "SHA1withDSA"; 59 private static byte[] algParams = { 1, 1, 0 }; // DER boolean false encoding 60 private static AlgorithmIdentifier signature; 61 private static byte[] signatureValue = new byte[10]; 62 63 static { 64 signature = new AlgorithmIdentifier(algOID, algParams); 65 } 66 67 private static String issuerName = "O=Certificate Issuer"; 68 private static Date thisUpdate = new Date(); 69 private static Date nextUpdate; 70 71 static { 72 nextUpdate = new Date(thisUpdate.getTime() + 100000); 73 } 74 75 private static Extension crlEntryExtension; 76 77 static { 78 // Invalidity Date Extension (rfc 3280) 79 crlEntryExtension = new Extension("2.5.29.24", 80 ASN1GeneralizedTime.getInstance().encode(new Date())); 81 } 82 83 private static Extensions crlEntryExtensions = new Extensions(); 84 85 static { 86 //* 87 crlEntryExtensions.addExtension(crlEntryExtension); 88 // add the Certificate Issuer Extension to check if implementation 89 // support indirect CRLs. As says rfc 3280 (p.62): 90 // "If used by conforming CRL issuers, this extension MUST always be 91 // critical. If an implementation ignored this extension it could not 92 // correctly attribute CRL entries to certificates. This specification 93 // RECOMMENDS that implementations recognize this extension." 94 try { 95 crlEntryExtensions.addExtension( 96 new Extension("2.5.29.29", true, 97 //* 98 //ASN1OctetString.getInstance().encode( 99 GeneralNames.ASN1.encode( 100 new GeneralNames(Arrays.asList( 101 new GeneralName[] { 102 new GeneralName(new Name("O=Cert Organization"))//new GeneralName(4, "O=Organization") 103 }) 104 ) 105 ) 106 //) 107 //*/ 108 ) 109 ); 110 } catch (Exception e) { 111 e.printStackTrace(); 112 } 113 //*/ 114 } 115 116 private static Date revocationDate = new Date(); 117 private static List revokedCertificates = Arrays.asList( 118 new TBSCertList.RevokedCertificate[] { 119 new TBSCertList.RevokedCertificate(BigInteger.valueOf(555), 120 revocationDate, null),//crlEntryExtensions), 121 new TBSCertList.RevokedCertificate(BigInteger.valueOf(666), 122 revocationDate, crlEntryExtensions), 123 new TBSCertList.RevokedCertificate(BigInteger.valueOf(777), 124 revocationDate, null),//crlEntryExtensions) 125 }); 126 private static Extensions crlExtensions = new Extensions( 127 Arrays.asList(new Extension[] { 128 new Extension("2.5.29.20", // CRL Number Extension (rfc 3280) 129 ASN1Integer.getInstance().encode( 130 BigInteger.valueOf(4444).toByteArray())), 131 })); 132 133 private CertificateList certificateList; 134 private TBSCertList tbscertlist; 135 private byte[] encoding; 136 137 protected void setUp() throws java.lang.Exception { 138 try { 139 Name issuer = new Name(issuerName); 140 141 tbscertlist = 142 new TBSCertList(2, signature, issuer, thisUpdate, 143 nextUpdate, revokedCertificates, crlExtensions); 144 145 certificateList = 146 new CertificateList(tbscertlist, signature, signatureValue); 147 148 encoding = CertificateList.ASN1.encode(certificateList); 149 150 certificateList = (CertificateList) 151 CertificateList.ASN1.decode(encoding); 152 153 } catch (IOException e) { 154 e.printStackTrace(); 155 fail("Unexpected IOException was thrown: " + e.getMessage()); 156 } 157 } 158 159 160 /** 161 * CertificateList(TBSCertList tbsCertList, AlgorithmIdentifier 162 * signatureAlgorithm, byte[] signatureValue) method testing. 163 */ 164 public void testCertificateList() { 165 try { 166 AlgorithmIdentifier signature = 167 new AlgorithmIdentifier(algOID, algParams); 168 Name issuer = new Name(issuerName); 169 TBSCertList tbscl = 170 new TBSCertList(signature, issuer, thisUpdate); 171 CertificateList cl = 172 new CertificateList(tbscl, signature, new byte[] { 0 }); 173 174 byte[] encoding = CertificateList.ASN1.encode(cl); 175 CertificateList.ASN1.decode(encoding); 176 177 tbscl = new TBSCertList(2, signature, issuer, thisUpdate, 178 nextUpdate, revokedCertificates, crlExtensions); 179 180 cl = new CertificateList(tbscl, signature, new byte[] { 0 }); 181 182 encoding = CertificateList.ASN1.encode(cl); 183 CertificateList.ASN1.decode(encoding); 184 185 } catch (IOException e) { 186 e.printStackTrace(); 187 fail("Unexpected IOException was thrown: " + e.getMessage()); 188 } 189 } 190 191 /** 192 * getTbsCertList() method testing. 193 */ 194 public void testGetTbsCertList() { 195 assertTrue("Returned tbsCertList value is incorrect", 196 tbscertlist.equals(certificateList.getTbsCertList())); 197 } 198 199 /** 200 * getSignatureAlgorithm() method testing. 201 */ 202 public void testGetSignatureAlgorithm() { 203 assertTrue("Returned signatureAlgorithm value is incorrect", 204 signature.equals(certificateList.getSignatureAlgorithm())); 205 } 206 207 /** 208 * getSignatureValue() method testing. 209 */ 210 public void testGetSignatureValue() { 211 assertTrue("Returned signatureAlgorithm value is incorrect", 212 Arrays.equals(signatureValue, certificateList.getSignatureValue())); 213 } 214 215 public void testSupportIndirectCRLs() throws Exception { 216 X509CRL crl = (X509CRL) 217 CertificateFactory.getInstance("X.509").generateCRL( 218 new ByteArrayInputStream(encoding)); 219 Set rcerts = crl.getRevokedCertificates(); 220 System.out.println(">> rcerts:" + rcerts); 221 222 System.out.println("}>> " + rcerts.toArray()[0]); 223 System.out.println("}>> " + ((X509CRLEntry) rcerts.toArray()[0]).getCertificateIssuer()); 224 System.out.println("}>> " + ((X509CRLEntry) rcerts.toArray()[1]).getCertificateIssuer()); 225 System.out.println("}>> " + ((X509CRLEntry) rcerts.toArray()[2]).getCertificateIssuer()); 226 System.out.println(">> " + crl.getRevokedCertificate( 227 BigInteger.valueOf(555)).getCertificateIssuer()); 228 } 229 230 public static Test suite() { 231 return new TestSuite(CertificateListTest.class); 232 } 233 234} 235