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 24import java.io.ByteArrayInputStream; 25import java.io.IOException; 26import java.math.BigInteger; 27import java.security.cert.CertificateFactory; 28import java.util.Arrays; 29import java.util.Date; 30 31import junit.framework.Test; 32import junit.framework.TestCase; 33import junit.framework.TestSuite; 34 35import org.apache.harmony.security.asn1.ASN1Integer; 36import org.apache.harmony.security.x501.Name; 37import org.apache.harmony.security.x509.AlgorithmIdentifier; 38import org.apache.harmony.security.x509.Certificate; 39import org.apache.harmony.security.x509.EDIPartyName; 40import org.apache.harmony.security.x509.Extension; 41import org.apache.harmony.security.x509.Extensions; 42import org.apache.harmony.security.x509.GeneralName; 43import org.apache.harmony.security.x509.GeneralNames; 44import org.apache.harmony.security.x509.NameConstraints; 45import org.apache.harmony.security.x509.ORAddress; 46import org.apache.harmony.security.x509.OtherName; 47import org.apache.harmony.security.x509.SubjectPublicKeyInfo; 48import org.apache.harmony.security.x509.TBSCertificate; 49import org.apache.harmony.security.x509.Validity; 50 51/** 52 * Testing the encoding/decoding work of the following structure: 53 * (as specified in RFC 3280 - 54 * Internet X.509 Public Key Infrastructure. 55 * Certificate and Certificate Revocation List (CRL) Profile. 56 * http://www.ietf.org/rfc/rfc3280.txt): 57 * <p/> 58 * <pre> 59 * Certificate ::= SEQUENCE { 60 * tbsCertificate TBSCertificate, 61 * signatureAlgorithm AlgorithmIdentifier, 62 * signatureValue BIT STRING 63 * } 64 * 65 * TBSCertificate ::= SEQUENCE { 66 * version [0] EXPLICIT Version DEFAULT v1, 67 * serialNumber CertificateSerialNumber, 68 * signature AlgorithmIdentifier, 69 * issuer Name, 70 * validity Validity, 71 * subject Name, 72 * subjectPublicKeyInfo SubjectPublicKeyInfo, 73 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, 74 * -- If present, version MUST be v2 or v3 75 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, 76 * -- If present, version MUST be v2 or v3 77 * extensions [3] EXPLICIT Extensions OPTIONAL 78 * -- If present, version MUST be v3 79 * } 80 * 81 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 82 * 83 * CertificateSerialNumber ::= INTEGER 84 * 85 * Validity ::= SEQUENCE { 86 * notBefore Time, 87 * notAfter Time 88 * } 89 * 90 * Time ::= CHOICE { 91 * utcTime UTCTime, 92 * generalTime GeneralizedTime 93 * } 94 * 95 * UniqueIdentifier ::= BIT STRING 96 * 97 * SubjectPublicKeyInfo ::= SEQUENCE { 98 * algorithm AlgorithmIdentifier, 99 * subjectPublicKey BIT STRING 100 * } 101 * 102 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 103 * 104 * Extension ::= SEQUENCE { 105 * extnID OBJECT IDENTIFIER, 106 * critical BOOLEAN DEFAULT FALSE, 107 * extnValue OCTET STRING 108 * } 109 * </pre> 110 */ 111 112public class CertificateTest extends TestCase { 113 114 /** 115 * Certificate(TBSCertificate tbsCertificate, AlgorithmIdentifier 116 * signatureAlgorithm, byte[] signatureValue) method testing. 117 * Makes the certificate, gets its encoded form, makes new certificate 118 * from this encoded form by CertificateFactory, and decodes encoded 119 * form. 120 */ 121 public void testCertificate() throws Exception { 122 // make the TBSCertificate for Certificate 123 int version = 2; //v3 124 BigInteger serialNumber = BigInteger.valueOf(555L); 125 AlgorithmIdentifier signature = new AlgorithmIdentifier("1.2.3.44.555"); // random value 126 Name issuer = new Name("O=Certificate Issuer"); 127 Validity validity = new Validity(new Date(100000000), new Date(200000000)); 128 Name subject = new Name("O=Subject Organization"); 129 SubjectPublicKeyInfo subjectPublicKeyInfo = 130 new SubjectPublicKeyInfo(new AlgorithmIdentifier("1.2.840.113549.1.1.2"), 131 new byte[10]); 132 boolean[] issuerUniqueID = new boolean[] 133 { true, false, true, false, true, false, true, false }; // random value 134 boolean[] subjectUniqueID = new boolean[] 135 { false, true, false, true, false, true, false, true }; // random value 136 // make the Extensions for TBSCertificate 137 // Subject Alternative Names 138 GeneralName[] san = new GeneralName[] { 139 new GeneralName( 140 new OtherName("1.2.3.4.5", 141 ASN1Integer.getInstance().encode( 142 BigInteger.valueOf(55L).toByteArray()))), 143 new GeneralName(1, "rfc@822.Name"), 144 new GeneralName(2, "dNSName"), 145 new GeneralName(new ORAddress()), 146 new GeneralName(4, "O=Organization"), 147 new GeneralName(new EDIPartyName("assigner", "party")), 148 new GeneralName(6, "http://Resource.Id"), 149 new GeneralName(new byte[] { 1, 1, 1, 1 }), 150 new GeneralName(8, "1.2.3.4444.55555") 151 }; 152 GeneralNames sans = new GeneralNames(Arrays.asList(san)); 153 Extension extension = new Extension("2.5.29.17", true, sans.getEncoded()); 154 Extensions extensions = new Extensions(); 155 extensions.addExtension(extension); 156 157 byte[] encoding = extensions.getEncoded(); 158 Extensions.ASN1.decode(encoding); 159 160 TBSCertificate tbsCertificate = new TBSCertificate(version, serialNumber, 161 signature, issuer, validity, subject, subjectPublicKeyInfo, 162 issuerUniqueID, subjectUniqueID, extensions); 163 164 encoding = tbsCertificate.getEncoded(); 165 TBSCertificate.ASN1.decode(encoding); 166 167 Certificate certificate = new Certificate(tbsCertificate, signature, new byte[10]); 168 169 encoding = certificate.getEncoded(); 170 171 Certificate.ASN1.decode(encoding); 172 173 encoding = Certificate.ASN1.encode(certificate); 174 175 ByteArrayInputStream bais = new ByteArrayInputStream(encoding); 176 177 //try { 178 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 179 cf.generateCertificate(bais); 180 //} catch (CertificateException e) { 181 // there is no X.509 certificate factory implementation installed 182 //} 183 } 184 185 /** 186 * getTbsCertificate() method testing. 187 */ 188 public void testGetTbsCertificate() throws IOException { 189 // manually derived data: 190 byte[] encoding = new byte[] { 191 (byte) 0x30, (byte) 0x13, // NameConstraints 192 (byte) 0xa1, (byte) 0x11, // GeneralSubtrees (excludedSubtrees) 193 (byte) 0x30, (byte) 0x0f, // GeneralSubtree 194 (byte) 0xa0, (byte) 0x0a, // GeneralName 195 // OtherName: 196 (byte) 0x06, (byte) 0x03, // type-id (OID) 197 (byte) 0x00, (byte) 0x01, (byte) 0x02, // oid 198 (byte) 0xA0, (byte) 0x03, // value (raw) 199 1, 1, (byte) 0xff, // boolean 200 (byte) 0x80, (byte) 0x01, (byte) 0x00 // minimum 201 }; 202 NameConstraints.ASN1.decode(encoding); 203 } 204 205 /** 206 * getSignatureAlgorithm() method testing. 207 */ 208 public void testGetSignatureAlgorithm() { 209 } 210 211 /** 212 * getSignatureValue() method testing. 213 */ 214 public void testGetSignatureValue() { 215 } 216 217 /** 218 * getValue() method testing. 219 */ 220 public void testGetValue() { 221 } 222 223 public static Test suite() { 224 return new TestSuite(CertificateTest.class); 225 } 226 227} 228