/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. */ /** * @author Alexander Y. Kleymenov */ package org.apache.harmony.security.tests.x509; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CertificateFactory; import java.util.Arrays; import java.util.Date; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.harmony.security.asn1.ASN1Integer; import org.apache.harmony.security.x501.Name; import org.apache.harmony.security.x509.AlgorithmIdentifier; import org.apache.harmony.security.x509.Certificate; import org.apache.harmony.security.x509.EDIPartyName; import org.apache.harmony.security.x509.Extension; import org.apache.harmony.security.x509.Extensions; import org.apache.harmony.security.x509.GeneralName; import org.apache.harmony.security.x509.GeneralNames; import org.apache.harmony.security.x509.NameConstraints; import org.apache.harmony.security.x509.ORAddress; import org.apache.harmony.security.x509.OtherName; import org.apache.harmony.security.x509.SubjectPublicKeyInfo; import org.apache.harmony.security.x509.TBSCertificate; import org.apache.harmony.security.x509.Validity; /** * Testing the encoding/decoding work of the following structure: * (as specified in RFC 3280 - * Internet X.509 Public Key Infrastructure. * Certificate and Certificate Revocation List (CRL) Profile. * http://www.ietf.org/rfc/rfc3280.txt): *

*

 *   Certificate  ::=  SEQUENCE  {
 *        tbsCertificate       TBSCertificate,
 *        signatureAlgorithm   AlgorithmIdentifier,
 *        signatureValue       BIT STRING
 *   }
 *
 *   TBSCertificate  ::=  SEQUENCE  {
 *        version         [0]  EXPLICIT Version DEFAULT v1,
 *        serialNumber         CertificateSerialNumber,
 *        signature            AlgorithmIdentifier,
 *        issuer               Name,
 *        validity             Validity,
 *        subject              Name,
 *        subjectPublicKeyInfo SubjectPublicKeyInfo,
 *        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
 *                             -- If present, version MUST be v2 or v3
 *        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
 *                             -- If present, version MUST be v2 or v3
 *        extensions      [3]  EXPLICIT Extensions OPTIONAL
 *                             -- If present, version MUST be v3
 *   }
 *
 *   Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
 *
 *   CertificateSerialNumber  ::=  INTEGER
 *
 *   Validity ::= SEQUENCE {
 *        notBefore      Time,
 *        notAfter       Time
 *   }
 *
 *   Time ::= CHOICE {
 *        utcTime        UTCTime,
 *        generalTime    GeneralizedTime
 *   }
 *
 *   UniqueIdentifier  ::=  BIT STRING
 *
 *   SubjectPublicKeyInfo  ::=  SEQUENCE  {
 *        algorithm            AlgorithmIdentifier,
 *        subjectPublicKey     BIT STRING
 *   }
 *
 *   Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
 *
 *   Extension  ::=  SEQUENCE  {
 *        extnID      OBJECT IDENTIFIER,
 *        critical    BOOLEAN DEFAULT FALSE,
 *        extnValue   OCTET STRING
 *   }
 * 
*/ public class CertificateTest extends TestCase { /** * Certificate(TBSCertificate tbsCertificate, AlgorithmIdentifier * signatureAlgorithm, byte[] signatureValue) method testing. * Makes the certificate, gets its encoded form, makes new certificate * from this encoded form by CertificateFactory, and decodes encoded * form. */ public void testCertificate() throws Exception { // make the TBSCertificate for Certificate int version = 2; //v3 BigInteger serialNumber = BigInteger.valueOf(555L); AlgorithmIdentifier signature = new AlgorithmIdentifier("1.2.3.44.555"); // random value Name issuer = new Name("O=Certificate Issuer"); Validity validity = new Validity(new Date(100000000), new Date(200000000)); Name subject = new Name("O=Subject Organization"); SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier("1.2.840.113549.1.1.2"), new byte[10]); boolean[] issuerUniqueID = new boolean[] { true, false, true, false, true, false, true, false }; // random value boolean[] subjectUniqueID = new boolean[] { false, true, false, true, false, true, false, true }; // random value // make the Extensions for TBSCertificate // Subject Alternative Names GeneralName[] san = new GeneralName[] { new GeneralName( new OtherName("1.2.3.4.5", ASN1Integer.getInstance().encode( BigInteger.valueOf(55L).toByteArray()))), new GeneralName(1, "rfc@822.Name"), new GeneralName(2, "dNSName"), new GeneralName(new ORAddress()), new GeneralName(4, "O=Organization"), new GeneralName(new EDIPartyName("assigner", "party")), new GeneralName(6, "http://Resource.Id"), new GeneralName(new byte[] { 1, 1, 1, 1 }), new GeneralName(8, "1.2.3.4444.55555") }; GeneralNames sans = new GeneralNames(Arrays.asList(san)); Extension extension = new Extension("2.5.29.17", true, sans.getEncoded()); Extensions extensions = new Extensions(); extensions.addExtension(extension); byte[] encoding = extensions.getEncoded(); Extensions.ASN1.decode(encoding); TBSCertificate tbsCertificate = new TBSCertificate(version, serialNumber, signature, issuer, validity, subject, subjectPublicKeyInfo, issuerUniqueID, subjectUniqueID, extensions); encoding = tbsCertificate.getEncoded(); TBSCertificate.ASN1.decode(encoding); Certificate certificate = new Certificate(tbsCertificate, signature, new byte[10]); encoding = certificate.getEncoded(); Certificate.ASN1.decode(encoding); encoding = Certificate.ASN1.encode(certificate); ByteArrayInputStream bais = new ByteArrayInputStream(encoding); //try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); cf.generateCertificate(bais); //} catch (CertificateException e) { // there is no X.509 certificate factory implementation installed //} } /** * getTbsCertificate() method testing. */ public void testGetTbsCertificate() throws IOException { // manually derived data: byte[] encoding = new byte[] { (byte) 0x30, (byte) 0x13, // NameConstraints (byte) 0xa1, (byte) 0x11, // GeneralSubtrees (excludedSubtrees) (byte) 0x30, (byte) 0x0f, // GeneralSubtree (byte) 0xa0, (byte) 0x0a, // GeneralName // OtherName: (byte) 0x06, (byte) 0x03, // type-id (OID) (byte) 0x00, (byte) 0x01, (byte) 0x02, // oid (byte) 0xA0, (byte) 0x03, // value (raw) 1, 1, (byte) 0xff, // boolean (byte) 0x80, (byte) 0x01, (byte) 0x00 // minimum }; NameConstraints.ASN1.decode(encoding); } /** * getSignatureAlgorithm() method testing. */ public void testGetSignatureAlgorithm() { } /** * getSignatureValue() method testing. */ public void testGetSignatureValue() { } /** * getValue() method testing. */ public void testGetValue() { } public static Test suite() { return new TestSuite(CertificateTest.class); } }