Home | History | Annotate | Download | only in x509
      1 /*
      2  * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 package sun.security.x509;
     27 
     28 import java.io.IOException;
     29 import sun.security.util.*;
     30 
     31 /**
     32  * This class defines the EDIPartyName of the GeneralName choice.
     33  * The ASN.1 syntax for this is:
     34  * <pre>
     35  * EDIPartyName ::= SEQUENCE {
     36  *     nameAssigner  [0]  DirectoryString OPTIONAL,
     37  *     partyName     [1]  DirectoryString }
     38  * </pre>
     39  *
     40  * @author Hemma Prafullchandra
     41  * @see GeneralName
     42  * @see GeneralNames
     43  * @see GeneralNameInterface
     44  */
     45 public class EDIPartyName implements GeneralNameInterface {
     46 
     47     // Private data members
     48     private static final byte TAG_ASSIGNER = 0;
     49     private static final byte TAG_PARTYNAME = 1;
     50 
     51     private String assigner = null;
     52     private String party = null;
     53 
     54     private int myhash = -1;
     55 
     56     /**
     57      * Create the EDIPartyName object from the specified names.
     58      *
     59      * @param assignerName the name of the assigner
     60      * @param partyName the name of the EDI party.
     61      */
     62     public EDIPartyName(String assignerName, String partyName) {
     63         this.assigner = assignerName;
     64         this.party = partyName;
     65     }
     66 
     67     /**
     68      * Create the EDIPartyName object from the specified name.
     69      *
     70      * @param partyName the name of the EDI party.
     71      */
     72     public EDIPartyName(String partyName) {
     73         this.party = partyName;
     74     }
     75 
     76     /**
     77      * Create the EDIPartyName object from the passed encoded Der value.
     78      *
     79      * @param derValue the encoded DER EDIPartyName.
     80      * @exception IOException on error.
     81      */
     82     public EDIPartyName(DerValue derValue) throws IOException {
     83         DerInputStream in = new DerInputStream(derValue.toByteArray());
     84         DerValue[] seq = in.getSequence(2);
     85 
     86         int len = seq.length;
     87         if (len < 1 || len > 2)
     88             throw new IOException("Invalid encoding of EDIPartyName");
     89 
     90         for (int i = 0; i < len; i++) {
     91             DerValue opt = seq[i];
     92             if (opt.isContextSpecific(TAG_ASSIGNER) &&
     93                 !opt.isConstructed()) {
     94                 if (assigner != null)
     95                     throw new IOException("Duplicate nameAssigner found in"
     96                                           + " EDIPartyName");
     97                 opt = opt.data.getDerValue();
     98                 assigner = opt.getAsString();
     99             }
    100             if (opt.isContextSpecific(TAG_PARTYNAME) &&
    101                 !opt.isConstructed()) {
    102                 if (party != null)
    103                     throw new IOException("Duplicate partyName found in"
    104                                           + " EDIPartyName");
    105                 opt = opt.data.getDerValue();
    106                 party = opt.getAsString();
    107             }
    108         }
    109     }
    110 
    111     /**
    112      * Return the type of the GeneralName.
    113      */
    114     public int getType() {
    115         return (GeneralNameInterface.NAME_EDI);
    116     }
    117 
    118     /**
    119      * Encode the EDI party name into the DerOutputStream.
    120      *
    121      * @param out the DER stream to encode the EDIPartyName to.
    122      * @exception IOException on encoding errors.
    123      */
    124     public void encode(DerOutputStream out) throws IOException {
    125         DerOutputStream tagged = new DerOutputStream();
    126         DerOutputStream tmp = new DerOutputStream();
    127 
    128         if (assigner != null) {
    129             DerOutputStream tmp2 = new DerOutputStream();
    130             // XXX - shd check is chars fit into PrintableString
    131             tmp2.putPrintableString(assigner);
    132             tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT,
    133                                  false, TAG_ASSIGNER), tmp2);
    134         }
    135         if (party == null)
    136             throw  new IOException("Cannot have null partyName");
    137 
    138         // XXX - shd check is chars fit into PrintableString
    139         tmp.putPrintableString(party);
    140         tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT,
    141                                  false, TAG_PARTYNAME), tmp);
    142 
    143         out.write(DerValue.tag_Sequence, tagged);
    144     }
    145 
    146     /**
    147      * Return the assignerName
    148      *
    149      * @returns String assignerName
    150      */
    151     public String getAssignerName() {
    152         return assigner;
    153     }
    154 
    155     /**
    156      * Return the partyName
    157      *
    158      * @returns String partyName
    159      */
    160     public String getPartyName() {
    161         return party;
    162     }
    163 
    164     /**
    165      * Compare this EDIPartyName with another.  Does a byte-string
    166      * comparison without regard to type of the partyName and
    167      * the assignerName.
    168      *
    169      * @returns true if the two names match
    170      */
    171     public boolean equals(Object other) {
    172         if (!(other instanceof EDIPartyName))
    173             return false;
    174         String otherAssigner = ((EDIPartyName)other).assigner;
    175         if (this.assigner == null) {
    176             if (otherAssigner != null)
    177                 return false;
    178         } else {
    179             if (!(this.assigner.equals(otherAssigner)))
    180                 return false;
    181         }
    182         String otherParty = ((EDIPartyName)other).party;
    183         if (this.party == null) {
    184             if (otherParty != null)
    185                 return false;
    186         } else {
    187             if (!(this.party.equals(otherParty)))
    188                 return false;
    189         }
    190         return true;
    191     }
    192 
    193     /**
    194      * Returns the hash code value for this EDIPartyName.
    195      *
    196      * @return a hash code value.
    197      */
    198     public int hashCode() {
    199         if (myhash == -1) {
    200             myhash = 37 + party.hashCode();
    201             if (assigner != null) {
    202                 myhash = 37 * myhash + assigner.hashCode();
    203             }
    204         }
    205         return myhash;
    206     }
    207 
    208     /**
    209      * Return the printable string.
    210      */
    211     public String toString() {
    212         return ("EDIPartyName: " +
    213                  ((assigner == null) ? "" :
    214                    ("  nameAssigner = " + assigner + ","))
    215                  + "  partyName = " + party);
    216     }
    217 
    218     /**
    219      * Return constraint type:<ul>
    220      *   <li>NAME_DIFF_TYPE = -1: input name is different type from name (i.e. does not constrain)
    221      *   <li>NAME_MATCH = 0: input name matches name
    222      *   <li>NAME_NARROWS = 1: input name narrows name
    223      *   <li>NAME_WIDENS = 2: input name widens name
    224      *   <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but is same type
    225      * </ul>.  These results are used in checking NameConstraints during
    226      * certification path verification.
    227      *
    228      * @param inputName to be checked for being constrained
    229      * @returns constraint type above
    230      * @throws UnsupportedOperationException if name is same type, but comparison operations are
    231      *          not supported for this name type.
    232      */
    233     public int constrains(GeneralNameInterface inputName) throws UnsupportedOperationException {
    234         int constraintType;
    235         if (inputName == null)
    236             constraintType = NAME_DIFF_TYPE;
    237         else if (inputName.getType() != NAME_EDI)
    238             constraintType = NAME_DIFF_TYPE;
    239         else {
    240             throw new UnsupportedOperationException("Narrowing, widening, and matching of names not supported for EDIPartyName");
    241         }
    242         return constraintType;
    243     }
    244 
    245     /**
    246      * Return subtree depth of this name for purposes of determining
    247      * NameConstraints minimum and maximum bounds and for calculating
    248      * path lengths in name subtrees.
    249      *
    250      * @returns distance of name from root
    251      * @throws UnsupportedOperationException if not supported for this name type
    252      */
    253     public int subtreeDepth() throws UnsupportedOperationException {
    254         throw new UnsupportedOperationException("subtreeDepth() not supported for EDIPartyName");
    255     }
    256 
    257 }
    258