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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [java/] [security/] [x509/] [X500DistinguishedName.java] - Blame information for rev 14

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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