Home | History | Annotate | Download | only in x509
      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 * @version $Revision$
     21 */
     22 
     23 package org.apache.harmony.security.x509;
     24 
     25 import java.math.BigInteger;
     26 import javax.security.auth.x500.X500Principal;
     27 import org.apache.harmony.security.asn1.ASN1BitString;
     28 import org.apache.harmony.security.asn1.ASN1Explicit;
     29 import org.apache.harmony.security.asn1.ASN1Implicit;
     30 import org.apache.harmony.security.asn1.ASN1Integer;
     31 import org.apache.harmony.security.asn1.ASN1Sequence;
     32 import org.apache.harmony.security.asn1.ASN1Type;
     33 import org.apache.harmony.security.asn1.BerInputStream;
     34 import org.apache.harmony.security.asn1.BitString;
     35 import org.apache.harmony.security.x501.Name;
     36 
     37 /**
     38  * The class encapsulates the ASN.1 DER encoding/decoding work
     39  * with TBSCertificate structure which is the part of X.509 certificate
     40  * (as specified in RFC 3280 -
     41  *  Internet X.509 Public Key Infrastructure.
     42  *  Certificate and Certificate Revocation List (CRL) Profile.
     43  *  http://www.ietf.org/rfc/rfc3280.txt):
     44  *
     45  * <pre>
     46  *  TBSCertificate  ::=  SEQUENCE  {
     47  *       version         [0]  EXPLICIT Version DEFAULT v1,
     48  *       serialNumber         CertificateSerialNumber,
     49  *       signature            AlgorithmIdentifier,
     50  *       issuer               Name,
     51  *       validity             Validity,
     52  *       subject              Name,
     53  *       subjectPublicKeyInfo SubjectPublicKeyInfo,
     54  *       issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
     55  *                            -- If present, version MUST be v2 or v3
     56  *       subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
     57  *                            -- If present, version MUST be v2 or v3
     58  *       extensions      [3]  EXPLICIT Extensions OPTIONAL
     59  *                            -- If present, version MUST be v3
     60  *  }
     61  * </pre>
     62  */
     63 public final class TBSCertificate {
     64 
     65     /** the value of version field of the structure */
     66     private final int version;
     67     /** the value of serialNumber field of the structure */
     68     private final BigInteger serialNumber;
     69     /** the value of signature field of the structure */
     70     private final AlgorithmIdentifier signature;
     71     /** the value of issuer field of the structure */
     72     private final Name issuer;
     73     /** the value of validity field of the structure */
     74     private final Validity validity;
     75     /** the value of subject field of the structure */
     76     private final Name subject;
     77     /** the value of subjectPublicKeyInfo field of the structure */
     78     private final SubjectPublicKeyInfo subjectPublicKeyInfo;
     79     /** the value of issuerUniqueID field of the structure */
     80     private final boolean[] issuerUniqueID;
     81     /** the value of subjectUniqueID field of the structure */
     82     private final boolean[] subjectUniqueID;
     83     /** the value of extensions field of the structure */
     84     private final Extensions extensions;
     85     /** the ASN.1 encoded form of TBSCertificate */
     86     private byte[] encoding;
     87 
     88     public TBSCertificate(int version, BigInteger serialNumber,
     89                           AlgorithmIdentifier signature, Name issuer,
     90                           Validity validity, Name subject,
     91                           SubjectPublicKeyInfo subjectPublicKeyInfo,
     92                           boolean[] issuerUniqueID, boolean[] subjectUniqueID,
     93                           Extensions extensions) {
     94         this.version = version;
     95         this.serialNumber = serialNumber;
     96         this.signature = signature;
     97         this.issuer = issuer;
     98         this.validity = validity;
     99         this.subject = subject;
    100         this.subjectPublicKeyInfo = subjectPublicKeyInfo;
    101         this.issuerUniqueID = issuerUniqueID;
    102         this.subjectUniqueID = subjectUniqueID;
    103         this.extensions = extensions;
    104     }
    105 
    106     private TBSCertificate(int version, BigInteger serialNumber,
    107                           AlgorithmIdentifier signature, Name issuer,
    108                           Validity validity, Name subject,
    109                           SubjectPublicKeyInfo subjectPublicKeyInfo,
    110                           boolean[] issuerUniqueID, boolean[] subjectUniqueID,
    111                           Extensions extensions, byte[] encoding) {
    112         this(version, serialNumber, signature, issuer, validity, subject,
    113              subjectPublicKeyInfo, issuerUniqueID, subjectUniqueID, extensions);
    114         this.encoding = encoding;
    115     }
    116 
    117     /**
    118      * Returns the value of version field of the structure.
    119      */
    120     public int getVersion() {
    121         return version;
    122     }
    123 
    124     /**
    125      * Returns the value of serialNumber field of the structure.
    126      */
    127     public BigInteger getSerialNumber() {
    128         return serialNumber;
    129     }
    130 
    131     /**
    132      * Returns the value of signature field of the structure.
    133      */
    134     public AlgorithmIdentifier getSignature() {
    135         return signature;
    136     }
    137 
    138     /**
    139      * Returns the value of issuer field of the structure.
    140      */
    141     public Name getIssuer() {
    142         return issuer;
    143     }
    144 
    145     /**
    146      * Returns the value of validity field of the structure.
    147      */
    148     public Validity getValidity() {
    149         return validity;
    150     }
    151 
    152     /**
    153      * Returns the value of subject field of the structure.
    154      */
    155     public Name getSubject() {
    156         return subject;
    157     }
    158 
    159     /**
    160      * Returns the value of subjectPublicKeyInfo field of the structure.
    161      */
    162     public SubjectPublicKeyInfo getSubjectPublicKeyInfo() {
    163         return subjectPublicKeyInfo;
    164     }
    165 
    166     /**
    167      * Returns the value of issuerUniqueID field of the structure.
    168      */
    169     public boolean[] getIssuerUniqueID() {
    170         return issuerUniqueID;
    171     }
    172 
    173     /**
    174      * Returns the value of subjectUniqueID field of the structure.
    175      */
    176     public boolean[] getSubjectUniqueID() {
    177         return subjectUniqueID;
    178     }
    179 
    180     /**
    181      * Returns the value of extensions field of the structure.
    182      */
    183     public Extensions getExtensions() {
    184         return extensions;
    185     }
    186 
    187     /**
    188      * Returns ASN.1 encoded form of this X.509 TBSCertificate value.
    189      */
    190     public byte[] getEncoded() {
    191         if (encoding == null) {
    192             encoding = ASN1.encode(this);
    193         }
    194         return encoding;
    195     }
    196 
    197     public void dumpValue(StringBuilder sb) {
    198         sb.append('[');
    199         sb.append("\n  Version: V").append(version+1);
    200         sb.append("\n  Subject: ").append(subject.getName(X500Principal.RFC2253));
    201         sb.append("\n  Signature Algorithm: ");
    202         signature.dumpValue(sb);
    203         sb.append("\n  Key: ").append(subjectPublicKeyInfo.getPublicKey().toString());
    204         sb.append("\n  Validity: [From: ").append(validity.getNotBefore());
    205         sb.append("\n               To: ").append(validity.getNotAfter()).append(']');
    206         sb.append("\n  Issuer: ").append(issuer.getName(X500Principal.RFC2253));
    207         sb.append("\n  Serial Number: ").append(serialNumber);
    208         if (issuerUniqueID != null) {
    209             sb.append("\n  Issuer Id: ");
    210             for (boolean b : issuerUniqueID) {
    211                 sb.append(b ? '1' : '0');
    212             }
    213         }
    214         if (subjectUniqueID != null) {
    215             sb.append("\n  Subject Id: ");
    216             for (boolean b : subjectUniqueID) {
    217                 sb.append(b ? '1' : '0');
    218             }
    219         }
    220         if (extensions != null) {
    221             sb.append("\n\n  Extensions: ");
    222             sb.append("[\n");
    223             extensions.dumpValue(sb, "    ");
    224             sb.append("  ]");
    225         }
    226         sb.append("\n]");
    227     }
    228 
    229     /**
    230      * X.509 TBSCertificate encoder/decoder.
    231      */
    232     public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
    233             new ASN1Explicit(0, ASN1Integer.getInstance()), ASN1Integer.getInstance(),
    234             AlgorithmIdentifier.ASN1, Name.ASN1,
    235             Validity.ASN1, Name.ASN1, SubjectPublicKeyInfo.ASN1,
    236             new ASN1Implicit(1, ASN1BitString.getInstance()),
    237             new ASN1Implicit(2, ASN1BitString.getInstance()),
    238             new ASN1Explicit(3, Extensions.ASN1)}) {
    239         {
    240             setDefault(new byte[] {0}, 0);
    241             setOptional(7);
    242             setOptional(8);
    243             setOptional(9);
    244         }
    245 
    246         @Override protected Object getDecodedObject(BerInputStream in) {
    247             Object[] values = (Object[]) in.content;
    248 
    249             boolean[] issuerUniqueID = (values[7] == null)
    250                 ? null : ((BitString) values[7]).toBooleanArray();
    251             boolean[] subjectUniqueID = (values[8] == null)
    252                 ? null : ((BitString) values[8]).toBooleanArray();
    253             return new TBSCertificate(
    254                         ASN1Integer.toIntValue(values[0]),
    255                         new BigInteger((byte[]) values[1]),
    256                         (AlgorithmIdentifier) values[2],
    257                         (Name) values[3],
    258                         (Validity) values[4],
    259                         (Name) values[5],
    260                         (SubjectPublicKeyInfo) values[6],
    261                         issuerUniqueID,
    262                         subjectUniqueID,
    263                         (Extensions) values[9],
    264                         in.getEncoded()
    265                     );
    266         }
    267 
    268         @Override protected void getValues(Object object, Object[] values) {
    269             TBSCertificate tbs = (TBSCertificate) object;
    270             values[0] = ASN1Integer.fromIntValue(tbs.version);
    271             values[1] = tbs.serialNumber.toByteArray();
    272             values[2] = tbs.signature;
    273             values[3] = tbs.issuer;
    274             values[4] = tbs.validity;
    275             values[5] = tbs.subject;
    276             values[6] = tbs.subjectPublicKeyInfo;
    277             if (tbs.issuerUniqueID != null) {
    278                 values[7] = new BitString(tbs.issuerUniqueID);
    279             }
    280             if (tbs.subjectUniqueID != null) {
    281                 values[8] = new BitString(tbs.subjectUniqueID);
    282             }
    283             values[9] = tbs.extensions;
    284         }
    285     };
    286 }
    287