View Javadoc
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 }