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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [javax/] [security/] [auth/] [x500/] [X500Principal.java] - Blame information for rev 14

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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