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 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     byte[] encoding;
     87 
     88     /**
     89      * Constructs the instance of TBSCertificate without optional
     90      * fields (issuerUniqueID, subjectUniqueID, extensions)
     91      * @param   version :   int
     92      * @param   serialNumber    :   BigInteger
     93      * @param   signature   :   AlgorithmIdentifier
     94      * @param   issuer  :   Name
     95      * @param   validity    :   Validity
     96      * @param   subject :   Name
     97      * @param   subjectPublicKeyInfo    :   SubjectPublicKeyInfo
     98      */
     99     public TBSCertificate(int version, BigInteger serialNumber,
    100                           AlgorithmIdentifier signature, Name issuer,
    101                           Validity validity, Name subject,
    102                           SubjectPublicKeyInfo subjectPublicKeyInfo) {
    103         this(version, serialNumber, signature, issuer, validity, subject,
    104              subjectPublicKeyInfo, null, null, null);
    105     }
    106 
    107     /**
    108      * TODO
    109      * @param   version:    int
    110      * @param   serialNumber:   BigInteger
    111      * @param   signature:  AlgorithmIdentifier
    112      * @param   issuer: Name
    113      * @param   validity:   Validity
    114      * @param   subject:    Name
    115      * @param   subjectPublicKeyInfo:   SubjectPublicKeyInfo
    116      * @param   issuerUniqueID: byte[]
    117      * @param   subjectUniqueID:    byte[]
    118      * @param   extensions: Extensions
    119      */
    120     public TBSCertificate(int version, BigInteger serialNumber,
    121                           AlgorithmIdentifier signature, Name issuer,
    122                           Validity validity, Name subject,
    123                           SubjectPublicKeyInfo subjectPublicKeyInfo,
    124                           boolean[] issuerUniqueID, boolean[] subjectUniqueID,
    125                           Extensions extensions) {
    126         this.version = version;
    127         this.serialNumber = serialNumber;
    128         this.signature = signature;
    129         this.issuer = issuer;
    130         this.validity = validity;
    131         this.subject = subject;
    132         this.subjectPublicKeyInfo = subjectPublicKeyInfo;
    133         this.issuerUniqueID = issuerUniqueID;
    134         this.subjectUniqueID = subjectUniqueID;
    135         this.extensions = extensions;
    136     }
    137 
    138     //
    139     // TODO
    140     // @param   version:    int
    141     // @param   serialNumber:   BigInteger
    142     // @param   signature:  AlgorithmIdentifier
    143     // @param   issuer: Name
    144     // @param   validity:   Validity
    145     // @param   subject:    Name
    146     // @param   subjectPublicKeyInfo:   SubjectPublicKeyInfo
    147     // @param   issuerUniqueID: byte[]
    148     // @param   subjectUniqueID:    byte[]
    149     // @param   extensions: Extensions
    150     // @param   encoding:   byte[]
    151     //
    152     private TBSCertificate(int version, BigInteger serialNumber,
    153                           AlgorithmIdentifier signature, Name issuer,
    154                           Validity validity, Name subject,
    155                           SubjectPublicKeyInfo subjectPublicKeyInfo,
    156                           boolean[] issuerUniqueID, boolean[] subjectUniqueID,
    157                           Extensions extensions, byte[] encoding) {
    158         this(version, serialNumber, signature, issuer, validity, subject,
    159              subjectPublicKeyInfo, issuerUniqueID, subjectUniqueID, extensions);
    160         this.encoding = encoding;
    161     }
    162 
    163     /**
    164      * Returns the value of version field of the structure.
    165      * @return  version
    166      */
    167     public int getVersion() {
    168         return version;
    169     }
    170 
    171     /**
    172      * Returns the value of serialNumber field of the structure.
    173      * @return  serialNumber
    174      */
    175     public BigInteger getSerialNumber() {
    176         return serialNumber;
    177     }
    178 
    179     /**
    180      * Returns the value of signature field of the structure.
    181      * @return  signature
    182      */
    183     public AlgorithmIdentifier getSignature() {
    184         return signature;
    185     }
    186 
    187     /**
    188      * Returns the value of issuer field of the structure.
    189      * @return  issuer
    190      */
    191     public Name getIssuer() {
    192         return issuer;
    193     }
    194 
    195     /**
    196      * Returns the value of validity field of the structure.
    197      * @return  validity
    198      */
    199     public Validity getValidity() {
    200         return validity;
    201     }
    202 
    203     /**
    204      * Returns the value of subject field of the structure.
    205      * @return  subject
    206      */
    207     public Name getSubject() {
    208         return subject;
    209     }
    210 
    211     /**
    212      * Returns the value of subjectPublicKeyInfo field of the structure.
    213      * @return  subjectPublicKeyInfo
    214      */
    215     public SubjectPublicKeyInfo getSubjectPublicKeyInfo() {
    216         return subjectPublicKeyInfo;
    217     }
    218 
    219     /**
    220      * Returns the value of issuerUniqueID field of the structure.
    221      * @return  issuerUniqueID
    222      */
    223     public boolean[] getIssuerUniqueID() {
    224         return issuerUniqueID;
    225     }
    226 
    227     /**
    228      * Returns the value of subjectUniqueID field of the structure.
    229      * @return  subjectUniqueID
    230      */
    231     public boolean[] getSubjectUniqueID() {
    232         return subjectUniqueID;
    233     }
    234 
    235     /**
    236      * Returns the value of extensions field of the structure.
    237      * @return  extensions
    238      */
    239     public Extensions getExtensions() {
    240         return extensions;
    241     }
    242 
    243     /**
    244      * Returns ASN.1 encoded form of this X.509 TBSCertificate value.
    245      * @return a byte array containing ASN.1 encode form.
    246      */
    247     public byte[] getEncoded() {
    248         if (encoding == null) {
    249             encoding = ASN1.encode(this);
    250         }
    251         return encoding;
    252     }
    253 
    254     /**
    255      * Places the string representation into the StringBuffer object.
    256      */
    257     public void dumpValue(StringBuffer buffer) {
    258         buffer.append('[');
    259         buffer.append("\n  Version: V").append(version+1);
    260         buffer.append("\n  Subject: ")
    261             .append(subject.getName(X500Principal.RFC2253));
    262         buffer.append("\n  Signature Algorithm: ");
    263         signature.dumpValue(buffer);
    264         buffer.append("\n  Key: ");
    265         buffer.append(subjectPublicKeyInfo.getPublicKey().toString());
    266         buffer.append("\n  Validity: [From: ");
    267         buffer.append(validity.getNotBefore());
    268         buffer.append("\n               To: ");
    269         buffer.append(validity.getNotAfter()).append(']');
    270         buffer.append("\n  Issuer: ");
    271         buffer.append(issuer.getName(X500Principal.RFC2253));
    272         buffer.append("\n  Serial Number: ");
    273         buffer.append(serialNumber);
    274         if (issuerUniqueID != null) {
    275             buffer.append("\n  Issuer Id: ");
    276             for (int i=0; i<issuerUniqueID.length; i++) {
    277                 buffer.append(issuerUniqueID[i] ? '1' : '0');
    278             }
    279         }
    280         if (subjectUniqueID != null) {
    281             buffer.append("\n  Subject Id: ");
    282             for (int i=0; i<subjectUniqueID.length; i++) {
    283                 buffer.append(subjectUniqueID[i] ? '1' : '0');
    284             }
    285         }
    286         if (extensions != null) {
    287             buffer.append("\n\n  Extensions: ");
    288             buffer.append("[\n");
    289             extensions.dumpValue(buffer, "    ");
    290             buffer.append("  ]");
    291         }
    292         buffer.append("\n]");
    293     }
    294 
    295     /**
    296      * X.509 TBSCertificate encoder/decoder.
    297      */
    298     public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
    299             new ASN1Explicit(0, ASN1Integer.getInstance()), ASN1Integer.getInstance(),
    300             AlgorithmIdentifier.ASN1, Name.ASN1,
    301             Validity.ASN1, Name.ASN1, SubjectPublicKeyInfo.ASN1,
    302             new ASN1Implicit(1, ASN1BitString.getInstance()),
    303             new ASN1Implicit(2, ASN1BitString.getInstance()),
    304             new ASN1Explicit(3, Extensions.ASN1)}) {
    305         {
    306             setDefault(new byte[] {0}, 0);
    307             setOptional(7);
    308             setOptional(8);
    309             setOptional(9);
    310         }
    311 
    312         protected Object getDecodedObject(BerInputStream in) {
    313             Object[] values = (Object[]) in.content;
    314 
    315             boolean[] issuerUniqueID = (values[7] == null)
    316                 ? null : ((BitString) values[7]).toBooleanArray();
    317             boolean[] subjectUniqueID = (values[8] == null)
    318                 ? null : ((BitString) values[8]).toBooleanArray();
    319             return new TBSCertificate(
    320                         ASN1Integer.toIntValue(values[0]),
    321                         new BigInteger((byte[]) values[1]),
    322                         (AlgorithmIdentifier) values[2],
    323                         (Name) values[3],
    324                         (Validity) values[4],
    325                         (Name) values[5],
    326                         (SubjectPublicKeyInfo) values[6],
    327                         issuerUniqueID,
    328                         subjectUniqueID,
    329                         (Extensions) values[9],
    330                         in.getEncoded()
    331                     );
    332         }
    333 
    334         protected void getValues(Object object, Object[] values) {
    335             TBSCertificate tbs = (TBSCertificate) object;
    336             values[0] = ASN1Integer.fromIntValue(tbs.version);
    337             values[1] = tbs.serialNumber.toByteArray();
    338             values[2] = tbs.signature;
    339             values[3] = tbs.issuer;
    340             values[4] = tbs.validity;
    341             values[5] = tbs.subject;
    342             values[6] = tbs.subjectPublicKeyInfo;
    343             if (tbs.issuerUniqueID != null) {
    344                 values[7] = new BitString(tbs.issuerUniqueID);
    345             }
    346             if (tbs.subjectUniqueID != null) {
    347                 values[8] = new BitString(tbs.subjectUniqueID);
    348             }
    349             values[9] = tbs.extensions;
    350         }
    351     };
    352 }
    353