OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [security/] [auth/] [x500/] [X500Principal.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* X500Principal.java -- X.500 principal.
2
   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.security.auth.x500;
40
 
41
import gnu.java.lang.CPStringBuilder;
42
 
43
import gnu.java.security.OID;
44
import gnu.java.security.der.DER;
45
import gnu.java.security.der.DERReader;
46
import gnu.java.security.der.DERValue;
47
 
48
import java.io.ByteArrayInputStream;
49
import java.io.EOFException;
50
import java.io.IOException;
51
import java.io.InputStream;
52
import java.io.NotActiveException;
53
import java.io.ObjectInputStream;
54
import java.io.ObjectOutputStream;
55
import java.io.Reader;
56
import java.io.Serializable;
57
import java.io.StringReader;
58
 
59
import java.security.Principal;
60
 
61
import java.util.ArrayList;
62
import java.util.HashSet;
63
import java.util.Iterator;
64
import java.util.LinkedHashMap;
65
import java.util.LinkedList;
66
import java.util.List;
67
import java.util.Locale;
68
import java.util.Map;
69
import java.util.Set;
70
 
71
public final class X500Principal implements Principal, Serializable
72
{
73
  private static final long serialVersionUID = -500463348111345721L;
74
 
75
  // Constants and fields.
76
  // ------------------------------------------------------------------------
77
 
78
  public static final String CANONICAL = "CANONICAL";
79
  public static final String RFC1779 = "RFC1779";
80
  public static final String RFC2253 = "RFC2253";
81
 
82
  private static final OID CN         = new OID("2.5.4.3");
83
  private static final OID C          = new OID("2.5.4.6");
84
  private static final OID L          = new OID("2.5.4.7");
85
  private static final OID ST         = new OID("2.5.4.8");
86
  private static final OID STREET     = new OID("2.5.4.9");
87
  private static final OID O          = new OID("2.5.4.10");
88
  private static final OID OU         = new OID("2.5.4.11");
89
  private static final OID DC         = new OID("0.9.2342.19200300.100.1.25");
90
  private static final OID UID        = new OID("0.9.2342.19200300.100.1.1");
91
 
92
  private transient List components;
93
  private transient Map currentRdn;
94
  private transient boolean fixed;
95
  private transient byte[] encoded;
96
 
97
  // Constructors.
98
  // ------------------------------------------------------------------------
99
 
100
  private X500Principal()
101
  {
102
    components = new LinkedList();
103
    currentRdn = new LinkedHashMap();
104
    components.add (currentRdn);
105
  }
106
 
107
  public X500Principal (String name)
108
  {
109
    this();
110
    if (name == null)
111
      throw new NullPointerException();
112
    try
113
      {
114
        parseString (name);
115
      }
116
    catch (IOException ioe)
117
      {
118
        IllegalArgumentException iae = new IllegalArgumentException("malformed name");
119
        iae.initCause (ioe);
120
        throw iae;
121
      }
122
  }
123
 
124
  public X500Principal (byte[] encoded)
125
  {
126
    this(new ByteArrayInputStream (encoded));
127
  }
128
 
129
  public X500Principal (InputStream encoded)
130
  {
131
    this();
132
    try
133
      {
134
        parseDer (encoded);
135
      }
136
    catch (IOException ioe)
137
      {
138
        throw new IllegalArgumentException (ioe.toString());
139
      }
140
  }
141
 
142
  // Instance methods.
143
  // ------------------------------------------------------------------------
144
 
145
  public int hashCode()
146
  {
147
    int result = size();
148
    for (int i = 0; i < size(); ++i)
149
      {
150
        Map m = (Map) components.get(i);
151
        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
152
          {
153
            Map.Entry e = (Map.Entry) it2.next();
154
            // We don't bother looking at the value of the entry.
155
            result = result * 31 + ((OID) e.getKey()).hashCode();
156
          }
157
      }
158
    return result;
159
  }
160
 
161
  public boolean equals(Object o)
162
  {
163
    if (!(o instanceof X500Principal))
164
      return false;
165
    if (size() != ((X500Principal) o).size())
166
      return false;
167
    for (int i = 0; i < size(); i++)
168
      {
169
        Map m = (Map) components.get (i);
170
        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
171
          {
172
            Map.Entry e = (Map.Entry) it2.next();
173
            OID oid = (OID) e.getKey();
174
            String v1 = (String) e.getValue();
175
            String v2 = ((X500Principal) o).getComponent (oid, i);
176
            if (v2 == null)
177
              return false;
178
            if (!compressWS (v1).equalsIgnoreCase (compressWS (v2)))
179
              return false;
180
          }
181
      }
182
    return true;
183
  }
184
 
185
  public byte[] getEncoded()
186
  {
187
    if (encoded == null)
188
      encodeDer();
189
    return (byte[]) encoded.clone();
190
  }
191
 
192
  public String getName()
193
  {
194
    return getName (RFC2253);
195
  }
196
 
197
  public String getName (final String format)
198
  {
199
    boolean rfc2253 = RFC2253.equalsIgnoreCase (format) ||
200
      CANONICAL.equalsIgnoreCase (format);
201
    boolean rfc1779 = RFC1779.equalsIgnoreCase (format);
202
    boolean canon   = CANONICAL.equalsIgnoreCase (format);
203
    if (! (rfc2253 || rfc1779 || canon))
204
      throw new IllegalArgumentException ("unsupported format " + format);
205
    CPStringBuilder str = new CPStringBuilder();
206
    for (Iterator it = components.iterator(); it.hasNext(); )
207
      {
208
        Map m = (Map) it.next();
209
        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
210
          {
211
            Map.Entry entry = (Map.Entry) it2.next();
212
            OID oid = (OID) entry.getKey();
213
            String value = (String) entry.getValue();
214
            if (oid.equals (CN))
215
              str.append ("CN");
216
            else if (oid.equals (C))
217
              str.append ("C");
218
            else if (oid.equals (L))
219
              str.append ("L");
220
            else if (oid.equals (ST))
221
              str.append ("ST");
222
            else if (oid.equals (STREET))
223
              str.append ("STREET");
224
            else if (oid.equals (O))
225
              str.append ("O");
226
            else if (oid.equals (OU))
227
              str.append ("OU");
228
            else if (oid.equals (DC) && rfc2253)
229
              str.append ("DC");
230
            else if (oid.equals (UID) && rfc2253)
231
              str.append ("UID");
232
            else
233
              str.append (oid.toString());
234
            str.append('=');
235
            str.append(value);
236
            if (it2.hasNext())
237
              str.append('+');
238
          }
239
        if (it.hasNext())
240
          str.append(',');
241
      }
242
    if (canon)
243
      return str.toString().toUpperCase (Locale.US).toLowerCase (Locale.US);
244
    return str.toString();
245
  }
246
 
247
  public String toString()
248
  {
249
    return getName (RFC2253);
250
  }
251
 
252
  // Serialization methods.
253
  // ------------------------------------------------------------------------
254
 
255
  private void writeObject (ObjectOutputStream out) throws IOException
256
  {
257
    if (encoded != null)
258
      encodeDer();
259
    out.writeObject (encoded);
260
  }
261
 
262
  private void readObject (ObjectInputStream in)
263
    throws IOException, NotActiveException, ClassNotFoundException
264
  {
265
    byte[] buf = (byte[]) in.readObject();
266
    parseDer (new ByteArrayInputStream (buf));
267
  }
268
 
269
  // Own methods.
270
  // -------------------------------------------------------------------------
271
 
272
  private int size()
273
  {
274
    return components.size();
275
  }
276
 
277
  private String getComponent(OID oid, int rdn)
278
  {
279
    if (rdn >= size())
280
      return null;
281
    return (String) ((Map) components.get (rdn)).get (oid);
282
  }
283
 
284
  private void encodeDer()
285
  {
286
    ArrayList name = new ArrayList(components.size());
287
    for (Iterator it = components.iterator(); it.hasNext(); )
288
      {
289
        Map m = (Map) it.next();
290
        if (m.isEmpty())
291
          continue;
292
        Set rdn = new HashSet();
293
        for (Iterator it2 = m.entrySet().iterator(); it2.hasNext(); )
294
          {
295
            Map.Entry e = (Map.Entry) it2.next();
296
            ArrayList atav = new ArrayList(2);
297
            atav.add(new DERValue(DER.OBJECT_IDENTIFIER, e.getKey()));
298
            atav.add(new DERValue(DER.UTF8_STRING, e.getValue()));
299
            rdn.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, atav));
300
          }
301
        name.add(new DERValue(DER.SET|DER.CONSTRUCTED, rdn));
302
      }
303
    DERValue val = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, name);
304
    encoded = val.getEncoded();
305
  }
306
 
307
  private int sep;
308
 
309
  private void parseString(String str) throws IOException
310
  {
311
    Reader in = new StringReader(str);
312
    while (true)
313
      {
314
        String key = readAttributeType(in);
315
        if (key == null)
316
          break;
317
        String value = readAttributeValue(in);
318
        putComponent(key, value);
319
        if (sep == ',')
320
          newRelativeDistinguishedName();
321
        if (sep == -1)
322
          break;
323
      }
324
  }
325
 
326
  private String readAttributeType(Reader in) throws IOException
327
  {
328
    CPStringBuilder buf = new CPStringBuilder();
329
    int ch;
330
    while ((ch = in.read()) != '=')
331
      {
332
        if (ch == -1)
333
          {
334
            if (buf.length() > 0)
335
              throw new EOFException("partial name read: " + buf);
336
            return null;
337
          }
338
        if (ch > 127)
339
          throw new IOException("Invalid char: " + (char) ch);
340
        if (Character.isLetterOrDigit((char) ch) || ch == '-' || ch == '.')
341
          buf.append((char) ch);
342
        else
343
          throw new IOException("Invalid char: " + (char) ch);
344
      }
345
    return buf.toString();
346
  }
347
 
348
  private String readAttributeValue(Reader in) throws IOException
349
  {
350
    CPStringBuilder buf = new CPStringBuilder();
351
    int ch = in.read();
352
    if (ch == '#')
353
      {
354
        while (true)
355
          {
356
            ch = in.read();
357
            if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
358
                || Character.isDigit((char) ch))
359
              buf.append((char) ch);
360
            else if (ch == '+' || ch == ',')
361
              {
362
                sep = ch;
363
                String hex = buf.toString();
364
                return new String(toByteArray(hex));
365
              }
366
            else
367
              throw new IOException("illegal character: " + (char) ch);
368
          }
369
      }
370
    else if (ch == '"')
371
      {
372
        while (true)
373
          {
374
            ch = in.read();
375
            if (ch == '"')
376
              break;
377
            else if (ch == '\\')
378
              {
379
                ch = in.read();
380
                if (ch == -1)
381
                  throw new EOFException();
382
                if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
383
                    || Character.isDigit((char) ch))
384
                  {
385
                    int i = Character.digit((char) ch, 16) << 4;
386
                    ch = in.read();
387
                    if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
388
                          || Character.isDigit((char) ch)))
389
                      throw new IOException("illegal hex char");
390
                    i |= Character.digit((char) ch, 16);
391
                    buf.append((char) i);
392
                  }
393
                else
394
                  buf.append((char) ch);
395
              }
396
            else
397
              buf.append((char) ch);
398
          }
399
        sep = in.read();
400
        if (sep != '+' && sep != ',')
401
          throw new IOException("illegal character: " + (char) ch);
402
        return buf.toString();
403
      }
404
    else
405
      {
406
        while (true)
407
          {
408
            switch (ch)
409
              {
410
              case '+':
411
              case ',':
412
                sep = ch;
413
                return buf.toString();
414
              case '\\':
415
                ch = in.read();
416
                if (ch == -1)
417
                  throw new EOFException();
418
                if (('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
419
                    || Character.isDigit((char) ch))
420
                  {
421
                    int i = Character.digit((char) ch, 16) << 4;
422
                    ch = in.read();
423
                    if (!(('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
424
                          || Character.isDigit((char) ch)))
425
                      throw new IOException("illegal hex char");
426
                    i |= Character.digit((char) ch, 16);
427
                    buf.append((char) i);
428
                  }
429
                else
430
                  buf.append((char) ch);
431
                break;
432
              case '=':
433
              case '<':
434
              case '>':
435
              case '#':
436
              case ';':
437
                throw new IOException("illegal character: " + (char) ch);
438
              case -1:
439
                sep = -1;
440
                return buf.toString ();
441
              default:
442
                buf.append((char) ch);
443
              }
444
            ch = in.read ();
445
          }
446
      }
447
  }
448
 
449
  private void parseDer (InputStream encoded) throws IOException
450
  {
451
    DERReader der = new DERReader (encoded);
452
    DERValue name = der.read();
453
    if (!name.isConstructed())
454
      throw new IOException ("malformed Name");
455
    this.encoded = name.getEncoded();
456
    int len = 0;
457
    while (len < name.getLength())
458
      {
459
        DERValue rdn = der.read();
460
        if (!rdn.isConstructed())
461
          throw new IOException ("badly formed RDNSequence");
462
        int len2 = 0;
463
        while (len2 < rdn.getLength())
464
          {
465
            DERValue atav = der.read();
466
            if (!atav.isConstructed())
467
              throw new IOException ("badly formed AttributeTypeAndValue");
468
            DERValue val = der.read();
469
            if (val.getTag() != DER.OBJECT_IDENTIFIER)
470
              throw new IOException ("badly formed AttributeTypeAndValue");
471
            OID oid = (OID) val.getValue();
472
            val = der.read();
473
            if (!(val.getValue() instanceof String))
474
              throw new IOException ("badly formed AttributeTypeAndValue");
475
            String value = (String) val.getValue();
476
            putComponent(oid, value);
477
            len2 += atav.getEncodedLength();
478
          }
479
        len += rdn.getEncodedLength();
480
        if (len < name.getLength())
481
          newRelativeDistinguishedName();
482
      }
483
  }
484
 
485
  private void newRelativeDistinguishedName()
486
  {
487
    currentRdn = new LinkedHashMap();
488
    components.add(currentRdn);
489
  }
490
 
491
  private void putComponent(OID oid, String value)
492
  {
493
    currentRdn.put(oid, value);
494
  }
495
 
496
  private void putComponent(String name, String value)
497
  {
498
    name = name.trim().toLowerCase();
499
    if (name.equals("cn"))
500
      putComponent(CN, value);
501
    else if (name.equals("c"))
502
      putComponent(C, value);
503
    else if (name.equals("l"))
504
      putComponent(L, value);
505
    else if (name.equals("street"))
506
      putComponent(STREET, value);
507
    else if (name.equals("st"))
508
      putComponent(ST, value);
509
    else if (name.equals ("o"))
510
      putComponent (O, value);
511
    else if (name.equals ("ou"))
512
      putComponent (OU, value);
513
    else if (name.equals("dc"))
514
      putComponent(DC, value);
515
    else if (name.equals("uid"))
516
      putComponent(UID, value);
517
    else
518
      putComponent(new OID(name), value);
519
  }
520
 
521
  private static String compressWS(String str)
522
  {
523
    CPStringBuilder buf = new CPStringBuilder();
524
    char lastChar = 0;
525
    for (int i = 0; i < str.length(); i++)
526
      {
527
        char c = str.charAt(i);
528
        if (Character.isWhitespace(c))
529
          {
530
            if (!Character.isWhitespace(lastChar))
531
              buf.append(' ');
532
          }
533
        else
534
          buf.append(c);
535
        lastChar = c;
536
      }
537
    return buf.toString().trim();
538
  }
539
 
540
  private static byte[] toByteArray (String str)
541
  {
542
    int limit = str.length();
543
    byte[] result = new byte[((limit + 1) / 2)];
544
    int i = 0, j = 0;
545
    if ((limit % 2) == 1)
546
      {
547
        result[j++] = (byte) Character.digit (str.charAt(i++), 16);
548
      }
549
    while (i < limit)
550
      {
551
        result[j  ]  = (byte) (Character.digit (str.charAt(i++), 16) << 4);
552
        result[j++] |= (byte)  Character.digit (str.charAt(i++), 16);
553
      }
554
    return result;
555
  }
556
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.