Source Code Cross Referenced for GeneralName.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » security » x509 » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » org package » org.apache.harmony.security.x509 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        /**
019:         * @author Vladimir N. Molotkov, Alexander Y. Kleymenov
020:         * @version $Revision$
021:         */package org.apache.harmony.security.x509;
022:
023:        import java.io.IOException;
024:        import java.net.URI;
025:        import java.net.URISyntaxException;
026:        import java.util.ArrayList;
027:        import java.util.Arrays;
028:        import java.util.Collections;
029:        import java.util.List;
030:
031:        import javax.security.auth.x500.X500Principal;
032:
033:        import org.apache.harmony.security.asn1.ASN1Choice;
034:        import org.apache.harmony.security.asn1.ASN1Implicit;
035:        import org.apache.harmony.security.asn1.ASN1OctetString;
036:        import org.apache.harmony.security.asn1.ASN1Oid;
037:        import org.apache.harmony.security.asn1.ASN1StringType;
038:        import org.apache.harmony.security.asn1.ASN1Type;
039:        import org.apache.harmony.security.asn1.BerInputStream;
040:        import org.apache.harmony.security.asn1.ObjectIdentifier;
041:        import org.apache.harmony.security.internal.nls.Messages;
042:        import org.apache.harmony.security.x501.Name;
043:
044:        /**
045:         * The class encapsulates the ASN.1 DER encoding/decoding work 
046:         * with the GeneralName structure which is a part of X.509 certificate
047:         * (as specified in RFC 3280 -
048:         *  Internet X.509 Public Key Infrastructure.
049:         *  Certificate and Certificate Revocation List (CRL) Profile.
050:         *  http://www.ietf.org/rfc/rfc3280.txt):
051:         * 
052:         * <pre>
053:         * 
054:         *   GeneralName::= CHOICE {
055:         *        otherName                       [0]     OtherName,
056:         *        rfc822Name                      [1]     IA5String,
057:         *        dNSName                         [2]     IA5String,
058:         *        x400Address                     [3]     ORAddress,
059:         *        directoryName                   [4]     Name,
060:         *        ediPartyName                    [5]     EDIPartyName,
061:         *        uniformResourceIdentifier       [6]     IA5String,
062:         *        iPAddress                       [7]     OCTET STRING,
063:         *        registeredID                    [8]     OBJECT IDENTIFIER
064:         *   }
065:         * 
066:         *   OtherName::= SEQUENCE {
067:         *        type-id    OBJECT IDENTIFIER,
068:         *        value      [0] EXPLICIT ANY DEFINED BY type-id 
069:         *   }
070:         * 
071:         *   EDIPartyName::= SEQUENCE {
072:         *        nameAssigner            [0]     DirectoryString OPTIONAL,
073:         *        partyName               [1]     DirectoryString 
074:         *   }
075:         * 
076:         *   DirectoryString::= CHOICE {
077:         *        teletexString             TeletexString   (SIZE (1..MAX)),
078:         *        printableString           PrintableString (SIZE (1..MAX)),
079:         *        universalString           UniversalString (SIZE (1..MAX)),
080:         *        utf8String              UTF8String      (SIZE (1..MAX)),
081:         *        bmpString               BMPString       (SIZE (1..MAX)) 
082:         *   }
083:         *  
084:         * </pre>
085:         * 
086:         * @see org.apache.harmony.security.x509.NameConstraints
087:         * @see org.apache.harmony.security.x509.GeneralSubtree
088:         */
089:        public class GeneralName {
090:
091:            /**
092:             * The values of the tags of fields
093:             */
094:            public static final int OTHER_NAME = 0;
095:            public static final int RFC822_NAME = 1;
096:            public static final int DNS_NAME = 2;
097:            public static final int X400_ADDR = 3;
098:            public static final int DIR_NAME = 4;
099:            public static final int EDIP_NAME = 5;
100:            public static final int UR_ID = 6;
101:            public static final int IP_ADDR = 7;
102:            public static final int REG_ID = 8;
103:
104:            // ASN1 encoders/decoders for name choices
105:            private static ASN1Type[] nameASN1 = new ASN1Type[9];
106:
107:            static {
108:                nameASN1[OTHER_NAME] = OtherName.ASN1;
109:                nameASN1[RFC822_NAME] = ASN1StringType.IA5STRING;
110:                nameASN1[DNS_NAME] = ASN1StringType.IA5STRING;
111:                nameASN1[UR_ID] = ASN1StringType.IA5STRING;
112:                nameASN1[X400_ADDR] = ORAddress.ASN1;
113:                nameASN1[DIR_NAME] = Name.ASN1;
114:                nameASN1[EDIP_NAME] = EDIPartyName.ASN1;
115:                nameASN1[IP_ADDR] = ASN1OctetString.getInstance();
116:                nameASN1[REG_ID] = ASN1Oid.getInstance();
117:            }
118:
119:            // the tag of the name type
120:            private int tag;
121:            // the name value (can be String or byte array)
122:            private Object name;
123:            // the ASN.1 encoded form of GeneralName
124:            private byte[] encoding;
125:            // the ASN.1 encoded form of GeneralName's field 
126:            private byte[] name_encoding;
127:
128:            /**
129:             * Makes the GeneralName object from the tag type and corresponding
130:             * well established string representation of the name value.
131:             * The String representation of [7] iPAddress is such as:
132:             *  For IP v4, as specified in RFC 791, the address must
133:             *  contain exactly 4 byte component.  For IP v6, as specified in
134:             *  RFC 1883, the address must contain exactly 16 byte component.
135:             *  If GeneralName structure is used as a part of Name Constraints
136:             *  extension, to represent an address range the number of address
137:             *  component is doubled (to 8 and 32 bytes respectively).
138:             * Note that the names:
139:             * [0] otherName, [3] x400Address, [5] ediPartyName
140:             *   have no the string representation, so exception will be thrown.
141:             * To make the GeneralName object with such names use another constructor. 
142:             * @param tag is an integer which value corresponds to the name type. 
143:             * @param name is a name value corresponding to the tag.
144:             * <pre>
145:             */
146:            public GeneralName(int tag, String name) throws IOException {
147:                if (name == null) {
148:                    throw new IOException(Messages.getString("security.28")); //$NON-NLS-1$
149:                }
150:                this .tag = tag;
151:                switch (tag) {
152:                case OTHER_NAME:
153:                case X400_ADDR:
154:                case EDIP_NAME:
155:                    throw new IOException(Messages.getString(
156:                            "security.180", tag)); //$NON-NLS-1$ //$NON-NLS-2$
157:                case DNS_NAME:
158:                    // according to RFC 3280 p.34 the DNS name should be 
159:                    // checked against the
160:                    // RFC 1034 p.10 (3.5. Preferred name syntax):
161:                    checkDNS(name);
162:                    this .name = name;
163:                    break;
164:                case UR_ID:
165:                    // check the uniformResourceIdentifier for correctness
166:                    // according to RFC 3280 p.34
167:                    checkURI(name);
168:                    this .name = name;
169:                    break;
170:                case RFC822_NAME:
171:                    this .name = name;
172:                    break;
173:                case REG_ID:
174:                    this .name = oidStrToInts(name);
175:                    break;
176:                case DIR_NAME:
177:                    this .name = new Name(name);
178:                    break;
179:                case IP_ADDR:
180:                    this .name = ipStrToBytes(name);
181:                    break;
182:                default:
183:                    throw new IOException(Messages.getString(
184:                            "security.181", tag)); //$NON-NLS-1$ //$NON-NLS-2$
185:                }
186:            }
187:
188:            /**
189:             * TODO
190:             * @param   name:   OtherName
191:             */
192:            public GeneralName(OtherName name) {
193:                this .tag = OTHER_NAME;
194:                this .name = name;
195:            }
196:
197:            /**
198:             * TODO
199:             * @param   name:   ORAddress
200:             */
201:            public GeneralName(ORAddress name) {
202:                this .tag = X400_ADDR;
203:                this .name = name;
204:            }
205:
206:            /**
207:             * TODO
208:             * @param   name:   Name
209:             */
210:            public GeneralName(Name name) {
211:                this .tag = DIR_NAME;
212:                this .name = name;
213:            }
214:
215:            /**
216:             * TODO
217:             * @param   name:   EDIPartyName
218:             */
219:            public GeneralName(EDIPartyName name) {
220:                this .tag = EDIP_NAME;
221:                this .name = name;
222:            }
223:
224:            /**
225:             * Constructor for type [7] iPAddress. 
226:             * name is an array of bytes such as:
227:             *  For IP v4, as specified in RFC 791, the address must
228:             *  contain exactly 4 byte component.  For IP v6, as specified in
229:             *  RFC 1883, the address must contain exactly 16 byte component.
230:             *  If GeneralName structure is used as a part of Name Constraints
231:             *  extension, to represent an address range the number of address
232:             *  component is doubled (to 8 and 32 bytes respectively).
233:             */
234:            public GeneralName(byte[] name) throws IllegalArgumentException {
235:                int length = name.length;
236:                if (length != 4 && length != 8 && length != 16 && length != 32) {
237:                    throw new IllegalArgumentException(Messages
238:                            .getString("security.182")); //$NON-NLS-1$
239:                }
240:                this .tag = IP_ADDR;
241:                this .name = new byte[name.length];
242:                System.arraycopy(name, 0, this .name, 0, name.length);
243:            }
244:
245:            /**
246:             * Constructs an object representing the value of GeneralName.
247:             * @param tag is an integer which value corresponds
248:             * to the name type (0-8), 
249:             * @param name is a DER encoded for of the name value
250:             */
251:            public GeneralName(int tag, byte[] name) throws IOException {
252:                if (name == null) {
253:                    throw new NullPointerException(Messages
254:                            .getString("security.28")); //$NON-NLS-1$
255:                }
256:                if ((tag < 0) || (tag > 8)) {
257:                    throw new IOException(Messages.getString(
258:                            "security.183", tag)); //$NON-NLS-1$
259:                }
260:                this .tag = tag;
261:                this .name_encoding = new byte[name.length];
262:                System.arraycopy(name, 0, this .name_encoding, 0, name.length);
263:                this .name = nameASN1[tag].decode(this .name_encoding);
264:            }
265:
266:            /**
267:             * Returns the tag of the name in the structure
268:             * @return the tag of the name
269:             */
270:            public int getTag() {
271:                return tag;
272:            }
273:
274:            /**
275:             * @return the value of the name. 
276:             * The class of name object depends on the tag as follows:
277:             * [0] otherName - OtherName object,
278:             * [1] rfc822Name - String object,
279:             * [2] dNSName - String object,
280:             * [3] x400Address - ORAddress object,
281:             * [4] directoryName - instance of Name object,
282:             * [5] ediPartyName - EDIPartyName object,
283:             * [6] uniformResourceIdentifier - String object,
284:             * [7] iPAddress - array of bytes such as:
285:             *  For IP v4, as specified in RFC 791, the address must
286:             *  contain exactly 4 byte component.  For IP v6, as specified in
287:             *  RFC 1883, the address must contain exactly 16 byte component.
288:             *  If GeneralName structure is used as a part of Name Constraints
289:             *  extension, to represent an address range the number of address
290:             *  component is doubled (to 8 and 32 bytes respectively).
291:             * [8] registeredID - String.
292:             */
293:            public Object getName() {
294:                return name;
295:            }
296:
297:            /**
298:             * TODO
299:             * @param   _gname: Object
300:             * @return
301:             */
302:            public boolean equals(Object _gname) {
303:                if (!(_gname instanceof  GeneralName)) {
304:                    return false;
305:                }
306:                GeneralName gname = (GeneralName) _gname;
307:                if (this .tag != gname.tag) {
308:                    return false;
309:                }
310:                switch (tag) {
311:                case RFC822_NAME:
312:                case DNS_NAME:
313:                case UR_ID:
314:                    return ((String) name).equalsIgnoreCase((String) gname
315:                            .getName());
316:                case REG_ID:
317:                    return Arrays.equals((int[]) name, (int[]) gname.name);
318:                case IP_ADDR:
319:                    // iPAddress [7], check by using ranges.
320:                    return Arrays.equals((byte[]) name, (byte[]) gname.name);
321:                case DIR_NAME:
322:                case X400_ADDR:
323:                case OTHER_NAME:
324:                case EDIP_NAME:
325:                    return Arrays.equals(getEncoded(), gname.getEncoded());
326:                default:
327:                    // should never happen
328:                }
329:                //System.out.println(false);
330:                return false;
331:            }
332:
333:            public int hashCode() {
334:                switch (tag) {
335:                case RFC822_NAME:
336:                case DNS_NAME:
337:                case UR_ID:
338:                case REG_ID:
339:                case IP_ADDR:
340:                    return name.hashCode();
341:                case DIR_NAME:
342:                case X400_ADDR:
343:                case OTHER_NAME:
344:                case EDIP_NAME:
345:                    return getEncoded().hashCode();
346:                default:
347:                    return super .hashCode();
348:                }
349:            }
350:
351:            /**
352:             * Checks if the other general name is acceptable by this object.
353:             * The name is acceptable if it has the same type name and its
354:             * name value is equal to name value of this object. Also the name
355:             * is acceptable if this general name object is a part of name 
356:             * constraints and the specified name is satisfied the restriction
357:             * provided by this object (for more detail see section 4.2.1.11
358:             * of rfc 3280).
359:             * Note that for X400Address [3] check procedure is unclear so method
360:             * just checks the equality of encoded forms.
361:             * For otherName [0], ediPartyName [5], and registeredID [8] 
362:             * the check procedure if not defined by rfc 3280 and for names of 
363:             * these types this method also checks only for equality of encoded forms.
364:             */
365:            public boolean isAcceptable(GeneralName gname) {
366:                if (this .tag != gname.getTag()) {
367:                    return false;
368:                }
369:                switch (this .tag) {
370:                case RFC822_NAME:
371:                    // Mail address [1]: 
372:                    // a@b.c - particular address is acceptable by the same address,
373:                    // or by b.c - host name.
374:                    return ((String) gname.getName()).toLowerCase().endsWith(
375:                            ((String) name).toLowerCase());
376:                case DNS_NAME:
377:                    // DNS name [2] that can be constructed by simply adding 
378:                    // to the left hand side of the name satisfies the name 
379:                    // constraint: aaa.aa.aa satisfies to aaa.aa.aa, aa.aa, ..
380:                    String dns = (String) name;
381:                    String _dns = (String) gname.getName();
382:                    if (dns.equalsIgnoreCase(_dns)) {
383:                        return true;
384:                    } else {
385:                        return _dns.toLowerCase().endsWith(
386:                                "." + dns.toLowerCase()); //$NON-NLS-1$
387:                    }
388:                case UR_ID:
389:                    // For URIs the constraint ".xyz.com" is satisfied by both 
390:                    // abc.xyz.com and abc.def.xyz.com.  However, the constraint 
391:                    // ".xyz.com" is not satisfied by "xyz.com".  
392:                    // When the constraint does not begin with a period, it
393:                    // specifies a host.
394:                    // Extract the host from URI:
395:                    String uri = (String) name;
396:                    int begin = uri.indexOf("://") + 3; //$NON-NLS-1$
397:                    int end = uri.indexOf('/', begin);
398:                    String host = (end == -1) ? uri.substring(begin) : uri
399:                            .substring(begin, end);
400:                    uri = (String) gname.getName();
401:                    begin = uri.indexOf("://") + 3; //$NON-NLS-1$
402:                    end = uri.indexOf('/', begin);
403:                    String _host = (end == -1) ? uri.substring(begin) : uri
404:                            .substring(begin, end);
405:                    if (host.startsWith(".")) { //$NON-NLS-1$
406:                        return _host.toLowerCase().endsWith(host.toLowerCase());
407:                    } else {
408:                        return host.equalsIgnoreCase(_host);
409:                    }
410:                case IP_ADDR:
411:                    // iPAddress [7], check by using ranges.
412:                    byte[] address = (byte[]) name;
413:                    byte[] _address = (byte[]) gname.getName();
414:                    int length = address.length;
415:                    int _length = _address.length;
416:                    if (length == _length) {
417:                        return Arrays.equals(address, _address);
418:                    } else if (length == 2 * _length) {
419:                        for (int i = 0; i < _address.length; i++) {
420:                            if ((_address[i] < address[i])
421:                                    || (_address[i] > address[i + _length])) {
422:                                return false;
423:                            }
424:                        }
425:                        return true;
426:                    } else {
427:                        return false;
428:                    }
429:                case DIR_NAME:
430:                    // FIXME: false:
431:                    // directoryName according to 4.1.2.4
432:                    // comparing the encoded forms of the names
433:                    //TODO:
434:                    //Legacy implementations exist where an RFC 822 name 
435:                    //is embedded in the subject distinguished name in an 
436:                    //attribute of type EmailAddress
437:                case X400_ADDR:
438:                case OTHER_NAME:
439:                case EDIP_NAME:
440:                case REG_ID:
441:                    return Arrays.equals(getEncoded(), gname.getEncoded());
442:                default:
443:                    // should never happen
444:                }
445:                return true;
446:            }
447:
448:            /**
449:             * Gets a list representation of this GeneralName object.
450:             * The first entry of the list is an Integer object representing
451:             * the type of mane (0-8), and the second entry is a value of the name:
452:             * string or ASN.1 DER encoded form depending on the type as follows:
453:             * rfc822Name, dNSName, uniformResourceIdentifier names are returned 
454:             * as Strings, using the string formats for those types (rfc 3280)
455:             * IP v4 address names are returned using dotted quad notation. 
456:             * IP v6 address names are returned in the form "p1:p2:...:p8", 
457:             * where p1-p8 are hexadecimal values representing the eight 16-bit 
458:             * pieces of the address. registeredID name are returned as Strings 
459:             * represented as a series of nonnegative integers separated by periods. 
460:             * And directory names (distinguished names) are returned in 
461:             * RFC 2253 string format. 
462:             * otherName, X400Address, ediPartyName returned as byte arrays 
463:             * containing the ASN.1 DER encoded form of the name. 
464:             */
465:            public List getAsList() {
466:                ArrayList result = new ArrayList();
467:                result.add(new Integer(tag));
468:                switch (tag) {
469:                case OTHER_NAME:
470:                    result.add(((OtherName) name).getEncoded());
471:                    break;
472:                case RFC822_NAME:
473:                case DNS_NAME:
474:                case UR_ID:
475:                    result.add(name); // String
476:                    break;
477:                case REG_ID:
478:                    result.add(ObjectIdentifier.toString((int[]) name));
479:                    break;
480:                case X400_ADDR:
481:                    result.add(((ORAddress) name).getEncoded());
482:                    break;
483:                case DIR_NAME: // directoryName is returned as a String
484:                    result.add(((Name) name).getName(X500Principal.RFC2253));
485:                    break;
486:                case EDIP_NAME:
487:                    result.add(((EDIPartyName) name).getEncoded());
488:                    break;
489:                case IP_ADDR: //iPAddress is returned as a String, not as a byte array
490:                    result.add(ipBytesToStr((byte[]) name));
491:                    break;
492:                default:
493:                    // should never happen
494:                }
495:                return Collections.unmodifiableList(result);
496:            }
497:
498:            // 
499:            // TODO
500:            // @param   data:   byte[]
501:            // @return
502:            // 
503:            private String getBytesAsString(byte[] data) {
504:                String result = ""; //$NON-NLS-1$
505:                for (int i = 0; i < data.length; i++) {
506:                    String tail = Integer.toHexString(0x00ff & data[i]);
507:                    if (tail.length() == 1) {
508:                        tail = "0" + tail; //$NON-NLS-1$
509:                    }
510:                    result += tail + " "; //$NON-NLS-1$
511:                }
512:                return result;
513:            }
514:
515:            /**
516:             * TODO
517:             * @return
518:             */
519:            public String toString() {
520:                String result = ""; //$NON-NLS-1$
521:                switch (tag) {
522:                case OTHER_NAME:
523:                    result = "otherName[0]: " //$NON-NLS-1$
524:                            + getBytesAsString(getEncoded());
525:                    break;
526:                case RFC822_NAME:
527:                    result = "rfc822Name[1]: " + name; //$NON-NLS-1$
528:                    break;
529:                case DNS_NAME:
530:                    result = "dNSName[2]: " + name; //$NON-NLS-1$
531:                    break;
532:                case UR_ID:
533:                    result = "uniformResourceIdentifier[6]: " + name; //$NON-NLS-1$
534:                    break;
535:                case REG_ID:
536:                    result = "registeredID[8]: " + ObjectIdentifier.toString((int[]) name); //$NON-NLS-1$
537:                    break;
538:                case X400_ADDR:
539:                    result = "x400Address[3]: " //$NON-NLS-1$
540:                            + getBytesAsString(getEncoded());
541:                    break;
542:                case DIR_NAME:
543:                    result = "directoryName[4]: " //$NON-NLS-1$
544:                            + ((Name) name).getName(X500Principal.RFC2253);
545:                    break;
546:                case EDIP_NAME:
547:                    result = "ediPartyName[5]: " //$NON-NLS-1$
548:                            + getBytesAsString(getEncoded());
549:                    break;
550:                case IP_ADDR:
551:                    result = "iPAddress[7]: " + ipBytesToStr((byte[]) name); //$NON-NLS-1$
552:                    break;
553:                default:
554:                    // should never happen
555:                }
556:                return result;
557:            }
558:
559:            /**
560:             * Returns ASN.1 encoded form of this X.509 GeneralName value.
561:             * @return a byte array containing ASN.1 encode form.
562:             */
563:            public byte[] getEncoded() {
564:                if (encoding == null) {
565:                    encoding = ASN1.encode(this );
566:                }
567:                return encoding;
568:            }
569:
570:            /**
571:             * @return the encoded value of the name without the tag associated 
572:             *         with the name in the GeneralName structure
573:             * @throws  IOException 
574:             */
575:            public byte[] getEncodedName() {
576:                if (name_encoding == null) {
577:                    name_encoding = nameASN1[tag].encode(name);
578:                }
579:                return name_encoding;
580:            }
581:
582:            /**
583:             * Checks the correctness of the string representation of DNS name.
584:             * The correctness is checked as specified in RFC 1034 p. 10.
585:             */
586:            public static void checkDNS(String dns) throws IOException {
587:                byte[] bytes = dns.toLowerCase().getBytes();
588:                // indicates if it is a first letter of the label
589:                boolean first_letter = true;
590:                for (int i = 0; i < bytes.length; i++) {
591:                    byte ch = bytes[i];
592:                    if (first_letter) {
593:                        if (ch > 'z' || ch < 'a') {
594:                            throw new IOException(Messages.getString(
595:                                    "security.184", //$NON-NLS-1$
596:                                    (char) ch, dns));
597:                        }
598:                        first_letter = false;
599:                        continue;
600:                    }
601:                    if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')
602:                            || (ch == '-') || (ch == '.'))) {
603:                        throw new IOException(Messages.getString(
604:                                "security.185", dns)); //$NON-NLS-1$
605:                    }
606:                    if (ch == '.') {
607:                        // check the end of the previous label, it should not
608:                        // be '-' sign
609:                        if (bytes[i - 1] == '-') {
610:                            throw new IOException(Messages.getString(
611:                                    "security.186", dns)); //$NON-NLS-1$
612:                        }
613:                        first_letter = true;
614:                    }
615:                }
616:            }
617:
618:            /**
619:             * Checks the correctness of the string representation of URI name.
620:             * The correctness is checked as pointed out in RFC 3280 p. 34.
621:             */
622:            public static void checkURI(String uri) throws IOException {
623:                try {
624:                    URI ur = new URI(uri);
625:                    if ((ur.getScheme() == null)
626:                            || (ur.getRawSchemeSpecificPart().length() == 0)) {
627:                        throw new IOException(Messages.getString(
628:                                "security.187", uri)); //$NON-NLS-1$
629:                    }
630:                    if (!ur.isAbsolute()) {
631:                        throw new IOException(Messages.getString(
632:                                "security.188", uri)); //$NON-NLS-1$
633:                    }
634:                } catch (URISyntaxException e) {
635:                    throw (IOException) new IOException(Messages.getString(
636:                            "security.189", uri)).initCause(e);//$NON-NLS-1$
637:
638:                }
639:            }
640:
641:            /**
642:             * Converts OID into array of bytes.
643:             */
644:            public static int[] oidStrToInts(String oid) throws IOException {
645:                byte[] bytes = oid.getBytes();
646:                if (bytes[bytes.length - 1] == '.') {
647:                    throw new IOException(Messages
648:                            .getString("security.56", oid)); //$NON-NLS-1$
649:                }
650:                int[] result = new int[bytes.length / 2 + 1]; // best case: a.b.c.d.e
651:                int number = 0; // the number of OID's components
652:                for (int i = 0; i < bytes.length; i++) {
653:                    int value = 0;
654:                    int pos = i;
655:                    while ((i < bytes.length) && (bytes[i] >= '0')
656:                            && (bytes[i] <= '9')) {
657:                        value = 10 * value + (bytes[i++] - 48);
658:                    }
659:                    if (i == pos) {
660:                        // the number was not read
661:                        throw new IOException(Messages.getString(
662:                                "security.56", oid)); //$NON-NLS-1$
663:                    }
664:                    result[number++] = value;
665:                    if (i >= bytes.length) {
666:                        break;
667:                    }
668:                    if (bytes[i] != '.') {
669:                        throw new IOException(Messages.getString(
670:                                "security.56", oid)); //$NON-NLS-1$
671:                    }
672:                }
673:                if (number < 2) {
674:                    throw new IOException(Messages.getString(
675:                            "security.18A", oid));//$NON-NLS-1$
676:                }
677:                int[] res = new int[number];
678:                for (int i = 0; i < number; i++) {
679:                    res[i] = result[i];
680:                }
681:                return res;
682:            }
683:
684:            /**
685:             * Helper method. Converts the String representation of IP address
686:             * to the array of bytes. IP addresses are expected in two versions:<br>
687:             * IPv4 - in dot-decimal notation<br>
688:             * IPv6 - in colon hexadecimal notation<br>
689:             * Also method works with the ranges of the addresses represented
690:             * as 2 addresses separated by '/' character.
691:             * @param   address :   String representation of IP address
692:             * @return  byte representation of IP address
693:             */
694:            public static byte[] ipStrToBytes(String ip) throws IOException {
695:                boolean isIPv4 = (ip.indexOf('.') > 0);
696:                // number of components (should be 4 or 8)
697:                int num_components = (isIPv4) ? 4 : 16;
698:                if (ip.indexOf('/') > 0) {
699:                    num_components *= 2; // this is a range of addresses
700:                }
701:                // the resulting array
702:                byte[] result = new byte[num_components];
703:                byte[] ip_bytes = ip.getBytes();
704:                // number of address component to be read
705:                int component = 0;
706:                // if it is reading the second bound of a range
707:                boolean reading_second_bound = false;
708:                if (isIPv4) {
709:                    // IPv4 address is expected in the form of dot-decimal notation:
710:                    //      1.100.2.200
711:                    // or in the range form:
712:                    //      1.100.2.200/1.100.3.300
713:                    int i = 0;
714:                    while (i < ip_bytes.length) {
715:                        int digits = 0;
716:                        // the value of the address component
717:                        int value = 0;
718:                        while ((i < ip_bytes.length) && (ip_bytes[i] >= '0')
719:                                && (ip_bytes[i] <= '9')) {
720:                            digits++;
721:                            if (digits > 3) {
722:                                throw new IOException(Messages.getString(
723:                                        "security.18B", ip)); //$NON-NLS-1$
724:                            }
725:                            value = 10 * value + (ip_bytes[i] - 48);
726:                            i++;
727:                        }
728:                        if (digits == 0) {
729:                            // ip_bytes[i] is not a number
730:                            throw new IOException(Messages.getString(
731:                                    "security.18C", ip));//$NON-NLS-1$
732:                        }
733:                        result[component] = (byte) value;
734:                        component++;
735:                        if (i >= ip_bytes.length) {
736:                            // no more bytes
737:                            break;
738:                        }
739:                        // check the reached delimiter
740:                        if ((ip_bytes[i] != '.' && ip_bytes[i] != '/')) {
741:                            throw new IOException(Messages.getString(
742:                                    "security.18C", ip)); //$NON-NLS-1$
743:                        }
744:                        // check the correctness of the range
745:                        if (ip_bytes[i] == '/') {
746:                            if (reading_second_bound) {
747:                                // more than 2 bounds in the range
748:                                throw new IOException(Messages.getString(
749:                                        "security.18C", ip)); //$NON-NLS-1$
750:                            }
751:                            if (component != 4) {
752:                                throw new IOException(Messages.getString(
753:                                        "security.18D", ip)); //$NON-NLS-1$
754:                            }
755:                            reading_second_bound = true;
756:                        }
757:                        // check the number of the components
758:                        if (component > ((reading_second_bound) ? 7 : 3)) {
759:                            throw new IOException(Messages.getString(
760:                                    "security.18D", ip)); //$NON-NLS-1$
761:                        }
762:                        i++;
763:                    }
764:                    // check the number of read components
765:                    if (component != num_components) {
766:                        throw new IOException(Messages.getString(
767:                                "security.18D", ip)); //$NON-NLS-1$
768:                    }
769:                } else {
770:                    // IPv6 address is expected in the form of
771:                    // colon hexadecimal notation:
772:                    // 010a:020b:3337:1000:FFFA:ABCD:9999:0000
773:                    // or in a range form:
774:                    // 010a:020b:3337:1000:FFFA:ABCD:9999:0000/010a:020b:3337:1000:FFFA:ABCD:9999:1111
775:                    if (ip_bytes.length != 39 && ip_bytes.length != 79) {
776:                        // incorrect length of the string representation
777:                        throw new IOException(Messages.getString(
778:                                "security.18E", ip)); //$NON-NLS-1$
779:                    }
780:                    int value = 0;
781:                    // indicates the reading of the second half of byte
782:                    boolean second_hex = false;
783:                    // if the delimiter (':' or '/') is expected
784:                    boolean expect_delimiter = false;
785:                    for (int i = 0; i < ip_bytes.length; i++) {
786:                        byte bytik = ip_bytes[i];
787:                        if ((bytik >= '0') && (bytik <= '9')) {
788:                            value = (bytik - 48); // '0':0, '1':1, ... , '9':9
789:                        } else if ((bytik >= 'A') && (bytik <= 'F')) {
790:                            value = (bytik - 55); // 'A':10, 'B':11, ... , 'F':15
791:                        } else if ((bytik >= 'a') && (bytik <= 'f')) {
792:                            value = (bytik - 87); // 'a':10, 'b':11, ... , 'f':15
793:                        } else if (second_hex) {
794:                            // second hex value of a byte is expected but was not read
795:                            // (it is the situation like: ...ABCD:A:ABCD...)
796:                            throw new IOException(Messages.getString(
797:                                    "security.18E", ip)); //$NON-NLS-1$
798:                        } else if ((bytik == ':') || (bytik == '/')) {
799:                            if (component % 2 == 1) {
800:                                // second byte of the component is omitted 
801:                                // (it is the situation like: ... ABDC:AB:ABCD ...)
802:                                throw new IOException(Messages.getString(
803:                                        "security.18E", ip)); //$NON-NLS-1$
804:                            }
805:                            if (bytik == '/') {
806:                                if (reading_second_bound) {
807:                                    // more than 2 bounds in the range
808:                                    throw new IOException(Messages.getString(
809:                                            "security.18E", ip)); //$NON-NLS-1$
810:                                }
811:                                if (component != 16) {
812:                                    // check the number of read components
813:                                    throw new IOException(Messages.getString(
814:                                            "security.18F", ip)); //$NON-NLS-1$
815:                                }
816:                                reading_second_bound = true;
817:                            }
818:                            expect_delimiter = false;
819:                            continue;
820:                        } else {
821:                            throw new IOException(Messages.getString(
822:                                    "security.18E", ip)); //$NON-NLS-1$
823:                        }
824:                        if (expect_delimiter) { // delimiter is expected but was not read
825:                            throw new IOException(Messages.getString(
826:                                    "security.18E", ip)); //$NON-NLS-1$
827:                        }
828:                        if (!second_hex) {
829:                            // first half of byte has been read
830:                            result[component] = (byte) (value << 4);
831:                            second_hex = true;
832:                        } else {
833:                            // second half of byte has been read
834:                            result[component] = (byte) ((result[component] & 0xFF) | value);
835:                            // delimiter is expected if 2 bytes were read
836:                            expect_delimiter = (component % 2 == 1);
837:                            second_hex = false;
838:                            component++;
839:                        }
840:                    }
841:                    // check the correctness of the read address:
842:                    if (second_hex || (component % 2 == 1)) {
843:                        throw new IOException(Messages.getString(
844:                                "security.18E", ip)); //$NON-NLS-1$
845:                    }
846:                }
847:                return result;
848:            }
849:
850:            /**
851:             * Helper method. Converts the byte array representation of ip address
852:             * to the String.
853:             * @param   ip :   byte array representation of ip address
854:             *  If the length of byte array 4 then it represents an IP v4 
855:             *  and the output String will be in the dotted quad form. 
856:             *  If the length is 16 then it represents an IP v6 
857:             *  and the output String will be returned in format "p1:p2:...:p8", 
858:             *  where p1-p8 are hexadecimal values representing the eight 16-bit 
859:             *  pieces of the address.
860:             *  If the length is 8 or 32 then it represents an address range (RFC 1519)
861:             *  and the output String will contain 2 IP address divided by "/"
862:             * @return  String representation of ip address
863:             */
864:            public static String ipBytesToStr(byte[] ip) {
865:                String result = ""; //$NON-NLS-1$
866:                if (ip.length < 9) { // IP v4
867:                    for (int i = 0; i < ip.length; i++) {
868:                        result += Integer.toString(ip[i] & 0xff);
869:                        if (i != ip.length - 1) {
870:                            result += (i == 3) ? "/" : "."; //$NON-NLS-1$ //$NON-NLS-2$
871:                        }
872:                    }
873:                } else {
874:                    for (int i = 0; i < ip.length; i++) {
875:                        result += Integer.toHexString(0x00ff & ip[i]);
876:                        if ((i % 2 != 0) && (i != ip.length - 1)) {
877:                            result += (i == 15) ? "/" : ":"; //$NON-NLS-1$ //$NON-NLS-2$
878:                        }
879:                    }
880:                }
881:                return result;
882:            }
883:
884:            public static final ASN1Choice ASN1 = new ASN1Choice(
885:                    new ASN1Type[] { new ASN1Implicit(0, OtherName.ASN1),
886:                            new ASN1Implicit(1, ASN1StringType.IA5STRING),
887:                            new ASN1Implicit(2, ASN1StringType.IA5STRING),
888:                            new ASN1Implicit(3, ORAddress.ASN1),
889:                            new ASN1Implicit(4, Name.ASN1),
890:                            new ASN1Implicit(5, EDIPartyName.ASN1),
891:                            new ASN1Implicit(6, ASN1StringType.IA5STRING),
892:                            new ASN1Implicit(7, ASN1OctetString.getInstance()),
893:                            new ASN1Implicit(8, ASN1Oid.getInstance()) }) {
894:
895:                public Object getObjectToEncode(Object value) {
896:                    return ((GeneralName) value).name;
897:                }
898:
899:                public int getIndex(java.lang.Object object) {
900:                    return ((GeneralName) object).tag;
901:                }
902:
903:                public Object getDecodedObject(BerInputStream in)
904:                        throws IOException {
905:                    GeneralName result;
906:                    switch (in.choiceIndex) {
907:                    case OTHER_NAME: // OtherName
908:                        result = new GeneralName((OtherName) in.content);
909:                        break;
910:                    case RFC822_NAME: // rfc822Name
911:                    case DNS_NAME: // dNSName
912:                        result = new GeneralName(in.choiceIndex,
913:                                (String) in.content);
914:                        break;
915:                    case X400_ADDR:
916:                        result = new GeneralName((ORAddress) in.content);
917:                        break;
918:                    case DIR_NAME: // directoryName (X.500 Name)
919:                        result = new GeneralName((Name) in.content);
920:                        break;
921:                    case EDIP_NAME: // ediPartyName
922:                        result = new GeneralName((EDIPartyName) in.content);
923:                        break;
924:                    case UR_ID: // uniformResourceIdentifier
925:                        String uri = (String) in.content;
926:                        if (uri.indexOf(":") == -1) { //$NON-NLS-1$
927:                            throw new IOException(Messages.getString(
928:                                    "security.190", uri)); //$NON-NLS-1$
929:                        }
930:                        result = new GeneralName(in.choiceIndex, uri);
931:                        break;
932:                    case IP_ADDR: // iPAddress
933:                        result = new GeneralName((byte[]) in.content);
934:                        break;
935:                    case REG_ID: // registeredID
936:                        result = new GeneralName(in.choiceIndex,
937:                                ObjectIdentifier.toString((int[]) in.content));
938:                        break;
939:                    default:
940:                        throw new IOException(Messages.getString(
941:                                "security.191", in.choiceIndex)); //$NON-NLS-1$
942:                    }
943:                    result.encoding = in.getEncoded();
944:                    return result;
945:                }
946:            };
947:
948:            // public static void printAsHex(int perLine,
949:            //         String prefix,
950:            //         String delimiter,
951:            //         byte[] data) {
952:            //     for (int i=0; i<data.length; i++) {
953:            //         String tail = Integer.toHexString(0x000000ff & data[i]);
954:            //         if (tail.length() == 1) {
955:            //             tail = "0" + tail; 
956:            //         }
957:            //         System.out.print(prefix + "0x" + tail + delimiter);
958:
959:            //         if (((i+1)%perLine) == 0) {
960:            //             System.out.println();
961:            //         }
962:            //     }
963:            //     System.out.println();
964:            // }
965:
966:            // public static void main(String[] args) {
967:            //     System.out.println(">> "+new BigInteger(new byte[] {(byte)23, (byte)255}).toString(2));
968:            //     System.out.println(ipBytesToStr(new byte[] {(byte)255, (byte)23, (byte)128, (byte)130}));
969:            //     System.out.println(ipBytesToStr(new byte[] {(byte)255, (byte)23, (byte)128, (byte)130,
970:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130}));
971:            //     System.out.println(ipBytesToStr(new byte[] {(byte)255, (byte)23, (byte)128, (byte)130,
972:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
973:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
974:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130}));
975:            //     System.out.println(ipBytesToStr(new byte[] {(byte)255, (byte)23, (byte)128, (byte)130,
976:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
977:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
978:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
979:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
980:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
981:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130,
982:            //                                                 (byte)255, (byte)23, (byte)128, (byte)130}));
983:            //     ipStrToBytes("1.2.3.4");
984:            //     ipStrToBytes("1.2.3.4/4.3.2.1");
985:            //     printAsHex(8, "", " ", ipStrToBytes("ff17:8082:ff17:8082:ff17:8082:ff17:8082/ff17:8082:ff17:8082:ff17:8082:ff17:8082"));
986:            // }
987:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.