Source Code Cross Referenced for IPAddressName.java in  » 6.0-JDK-Modules » j2me » sun » 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 » 6.0 JDK Modules » j2me » sun.security.x509 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)IPAddressName.java	1.15 06/10/10
003:         *
004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.  
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER  
006:         *   
007:         * This program is free software; you can redistribute it and/or  
008:         * modify it under the terms of the GNU General Public License version  
009:         * 2 only, as published by the Free Software Foundation.   
010:         *   
011:         * This program is distributed in the hope that it will be useful, but  
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of  
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
014:         * General Public License version 2 for more details (a copy is  
015:         * included at /legal/license.txt).   
016:         *   
017:         * You should have received a copy of the GNU General Public License  
018:         * version 2 along with this work; if not, write to the Free Software  
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
020:         * 02110-1301 USA   
021:         *   
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa  
023:         * Clara, CA 95054 or visit www.sun.com if you need additional  
024:         * information or have any questions. 
025:         *
026:         */
027:
028:        package sun.security.x509;
029:
030:        import java.io.IOException;
031:        import java.lang.Integer;
032:        import java.net.InetAddress;
033:        import java.util.Arrays;
034:        import sun.misc.HexDumpEncoder;
035:        import sun.security.util.BitArray;
036:        import sun.security.util.DerOutputStream;
037:        import sun.security.util.DerValue;
038:
039:        /**
040:         * This class implements the IPAddressName as required by the GeneralNames
041:         * ASN.1 object.  Both IPv4 and IPv6 addresses are supported using the
042:         * formats specified in IETF PKIX RFC2459.
043:         * <p>
044:         * [RFC2459 4.2.1.7 Subject Alternative Name]
045:         * When the subjectAltName extension contains a iPAddress, the address
046:         * MUST be stored in the octet string in "network byte order," as
047:         * specified in RFC 791. The least significant bit (LSB) of
048:         * each octet is the LSB of the corresponding byte in the network
049:         * address. For IP Version 4, as specified in RFC 791, the octet string
050:         * MUST contain exactly four octets.  For IP Version 6, as specified in
051:         * RFC 1883, the octet string MUST contain exactly sixteen octets.
052:         * <p>
053:         * [RFC2459 4.2.1.11 Name Constraints]
054:         * The syntax of iPAddress MUST be as described in section 4.2.1.7 with
055:         * the following additions specifically for Name Constraints.  For IPv4
056:         * addresses, the ipAddress field of generalName MUST contain eight (8)
057:         * octets, encoded in the style of RFC 1519 (CIDR) to represent an
058:         * address range.[RFC 1519]  For IPv6 addresses, the ipAddress field
059:         * MUST contain 32 octets similarly encoded.  For example, a name
060:         * constraint for "class C" subnet 10.9.8.0 shall be represented as the
061:         * octets 0A 09 08 00 FF FF FF 00, representing the CIDR notation
062:         * 10.9.8.0/255.255.255.0.
063:         * <p>
064:         * @see GeneralName
065:         * @see GeneralNameInterface
066:         * @see GeneralNames
067:         *
068:         * @version 1.8
069:         *
070:         * @author Amit Kapoor
071:         * @author Hemma Prafullchandra
072:         */
073:        public class IPAddressName implements  GeneralNameInterface {
074:            private byte[] address;
075:            private boolean isIPv4;
076:            private String name;
077:
078:            /**
079:             * Create the IPAddressName object from the passed encoded Der value.
080:             *
081:             * @params derValue the encoded DER IPAddressName.
082:             * @exception IOException on error.
083:             */
084:            public IPAddressName(DerValue derValue) throws IOException {
085:                this (derValue.getOctetString());
086:            }
087:
088:            /**
089:             * Create the IPAddressName object with the specified octets.
090:             *
091:             * @params address the IP address
092:             * @throws IOException if address is not a valid IPv4 or IPv6 address
093:             */
094:            public IPAddressName(byte[] address) throws IOException {
095:                /*
096:                 * A valid address must consist of 4 bytes of address and
097:                 * optional 4 bytes of 4 bytes of mask, or 16 bytes of address
098:                 * and optional 16 bytes of mask.
099:                 */
100:                if (address.length == 4 || address.length == 8) {
101:                    isIPv4 = true;
102:                } else if (address.length == 16 || address.length == 32) {
103:                    isIPv4 = false;
104:                } else {
105:                    throw new IOException("Invalid IPAddressName");
106:                }
107:                this .address = address;
108:            }
109:
110:            /**
111:             * Create an IPAddressName from a String.
112:             * [IETF RFC1338 Supernetting & IETF RFC1519 Classless Inter-Domain
113:             * Routing (CIDR)] For IPv4 addresses, the forms are
114:             * "b1.b2.b3.b4" or "b1.b2.b3.b4/m1.m2.m3.m4", where b1 - b4 are decimal
115:             * byte values 0-255 and m1 - m4 are decimal mask values
116:             * 0 - 255.
117:             * <p>
118:             * [IETF RFC2373 IP Version 6 Addressing Architecture]
119:             * For IPv6 addresses, the forms are "a1:a2:...:a8" or "a1:a2:...:a8/n",
120:             * where a1-a8 are hexadecimal values representing the eight 16-bit pieces 
121:             * of the address. If /n is used, n is a decimal number indicating how many 
122:             * of the leftmost contiguous bits of the address comprise the prefix for 
123:             * this subnet. Internally, a mask value is created using the prefix length.
124:             * <p>
125:             * @param name String form of IPAddressName
126:             * @throws IOException if name can not be converted to a valid IPv4 or IPv6
127:             *     address
128:             */
129:            public IPAddressName(String name) throws IOException {
130:
131:                if (name == null || name.length() == 0) {
132:                    throw new IOException("IPAddress cannot be null or empty");
133:                }
134:                if (name.charAt(name.length() - 1) == '/') {
135:                    throw new IOException("Invalid IPAddress: " + name);
136:                }
137:
138:                if (name.indexOf(':') >= 0) {
139:                    // name is IPv6: uses colons as value separators
140:                    // Parse name into byte-value address components and optional 
141:                    // prefix
142:                    parseIPv6(name);
143:                    isIPv4 = false;
144:                } else if (name.indexOf('.') >= 0) {
145:                    //name is IPv4: uses dots as value separators
146:                    parseIPv4(name);
147:                    isIPv4 = true;
148:                } else {
149:                    throw new IOException("Invalid IPAddress: " + name);
150:                }
151:            }
152:
153:            /**
154:             * Parse an IPv4 address.
155:             *
156:             * @param name IPv4 address with optional mask values
157:             * @throws IOException on error
158:             */
159:            private void parseIPv4(String name) throws IOException {
160:
161:                // Parse name into byte-value address components
162:                int slashNdx = name.indexOf('/');
163:                if (slashNdx == -1) {
164:                    address = InetAddress.getByName(name).getAddress();
165:                } else {
166:                    address = new byte[8];
167:
168:                    // parse mask
169:                    byte[] mask = InetAddress.getByName(
170:                            name.substring(slashNdx + 1)).getAddress();
171:
172:                    // parse base address
173:                    byte[] host = InetAddress.getByName(
174:                            name.substring(0, slashNdx)).getAddress();
175:
176:                    System.arraycopy(host, 0, address, 0, 4);
177:                    System.arraycopy(mask, 0, address, 4, 4);
178:                }
179:            }
180:
181:            /**
182:             * Parse an IPv6 address.
183:             *
184:             * @param name String IPv6 address with optional /<prefix length>
185:             *             If /<prefix length> is present, address[] array will
186:             *             be 32 bytes long, otherwise 16.
187:             * @throws IOException on error
188:             */
189:            private final static int MASKSIZE = 16;
190:
191:            private void parseIPv6(String name) throws IOException {
192:
193:                int slashNdx = name.indexOf('/');
194:                if (slashNdx == -1) {
195:                    address = InetAddress.getByName(name).getAddress();
196:                } else {
197:                    address = new byte[32];
198:                    byte[] base = InetAddress.getByName(
199:                            name.substring(0, slashNdx)).getAddress();
200:                    System.arraycopy(base, 0, address, 0, 16);
201:
202:                    // append a mask corresponding to the num of prefix bits specified
203:                    int prefixLen = Integer.parseInt(name
204:                            .substring(slashNdx + 1));
205:                    if (prefixLen > 128)
206:                        throw new IOException(
207:                                "IPv6Address prefix is longer than 128");
208:
209:                    // create new bit array initialized to zeros
210:                    BitArray bitArray = new BitArray(MASKSIZE * 8);
211:
212:                    // set all most significant bits up to prefix length
213:                    for (int i = 0; i < prefixLen; i++)
214:                        bitArray.set(i, true);
215:                    byte[] maskArray = bitArray.toByteArray();
216:
217:                    // copy mask bytes into mask portion of address
218:                    for (int i = 0; i < MASKSIZE; i++)
219:                        address[MASKSIZE + i] = maskArray[i];
220:                }
221:            }
222:
223:            /**
224:             * Return the type of the GeneralName.
225:             */
226:            public int getType() {
227:                return NAME_IP;
228:            }
229:
230:            /**
231:             * Encode the IPAddress name into the DerOutputStream.
232:             *
233:             * @params out the DER stream to encode the IPAddressName to.
234:             * @exception IOException on encoding errors.
235:             */
236:            public void encode(DerOutputStream out) throws IOException {
237:                out.putOctetString(address);
238:            }
239:
240:            /**
241:             * Return a printable string of IPaddress
242:             */
243:            public String toString() {
244:                try {
245:                    return "IPAddress: " + getName();
246:                } catch (IOException ioe) {
247:                    // dump out hex rep for debugging purposes
248:                    HexDumpEncoder enc = new HexDumpEncoder();
249:                    return "IPAddress: " + enc.encodeBuffer(address);
250:                }
251:            }
252:
253:            /**
254:             * Return a standard String representation of IPAddress.
255:             * See IPAddressName(String) for the formats used for IPv4
256:             * and IPv6 addresses.
257:             *
258:             * @throws IOException if the IPAddress cannot be converted to a String
259:             */
260:            public String getName() throws IOException {
261:                if (name != null)
262:                    return name;
263:
264:                if (isIPv4) {
265:                    //IPv4 address or subdomain
266:                    byte[] host = new byte[4];
267:                    System.arraycopy(address, 0, host, 0, 4);
268:                    name = InetAddress.getByAddress(host).getHostAddress();
269:                    if (address.length == 8) {
270:                        byte[] mask = new byte[4];
271:                        System.arraycopy(address, 4, mask, 0, 4);
272:                        name = name
273:                                + "/"
274:                                + InetAddress.getByAddress(mask)
275:                                        .getHostAddress();
276:                    }
277:                } else {
278:                    //IPv6 address or subdomain
279:                    byte[] host = new byte[16];
280:                    System.arraycopy(address, 0, host, 0, 16);
281:                    name = InetAddress.getByAddress(host).getHostAddress();
282:                    if (address.length == 32) {
283:                        // IPv6 subdomain: display prefix length
284:
285:                        // copy subdomain into new array and convert to BitArray
286:                        byte[] maskBytes = new byte[16];
287:                        for (int i = 16; i < 32; i++)
288:                            maskBytes[i - 16] = address[i];
289:                        BitArray ba = new BitArray(16 * 8, maskBytes);
290:                        // Find first zero bit
291:                        int i = 0;
292:                        for (; i < 16 * 8; i++) {
293:                            if (!ba.get(i))
294:                                break;
295:                        }
296:                        name = name + "/" + i;
297:                        // Verify remaining bits 0
298:                        for (; i < 16 * 8; i++) {
299:                            if (ba.get(i)) {
300:                                throw new IOException(
301:                                        "Invalid IPv6 subdomain - set "
302:                                                + "bit " + i
303:                                                + " not contiguous");
304:                            }
305:                        }
306:                    }
307:                }
308:                return name;
309:            }
310:
311:            /**
312:             * Returns this IPAddress name as a byte array.
313:             */
314:            public byte[] getBytes() {
315:                return (byte[]) address.clone();
316:            }
317:
318:            /**
319:             * Compares this name with another, for equality.
320:             *
321:             * @return true iff the names are identical.
322:             */
323:            public boolean equals(Object obj) {
324:                if (this  == obj)
325:                    return true;
326:
327:                if (!(obj instanceof  IPAddressName))
328:                    return false;
329:
330:                byte[] other = ((IPAddressName) obj).getBytes();
331:
332:                if (other.length != address.length)
333:                    return false;
334:
335:                if (address.length == 8 || address.length == 32) {
336:                    // Two subnet addresses
337:                    // Mask each and compare masked values
338:                    int maskLen = address.length / 2;
339:                    byte[] maskedThis = new byte[maskLen];
340:                    byte[] maskedOther = new byte[maskLen];
341:                    for (int i = 0; i < maskLen; i++) {
342:                        maskedThis[i] = (byte) (address[i] & address[i
343:                                + maskLen]);
344:                        maskedOther[i] = (byte) (other[i] & other[i + maskLen]);
345:                        if (maskedThis[i] != maskedOther[i]) {
346:                            return false;
347:                        }
348:                    }
349:                    // Now compare masks
350:                    for (int i = maskLen; i < address.length; i++)
351:                        if (address[i] != other[i])
352:                            return false;
353:                    return true;
354:                } else {
355:                    // Two IPv4 host addresses or two IPv6 host addresses
356:                    // Compare bytes
357:                    return Arrays.equals(other, address);
358:                }
359:            }
360:
361:            /**
362:             * Returns the hash code value for this object.
363:             * 
364:             * @return a hash code value for this object.
365:             */
366:            public int hashCode() {
367:                int retval = 0;
368:
369:                for (int i = 0; i < address.length; i++)
370:                    retval += address[i] * i;
371:
372:                return retval;
373:            }
374:
375:            /**
376:             * Return type of constraint inputName places on this name:<ul>
377:             *   <li>NAME_DIFF_TYPE = -1: input name is different type from name 
378:             *       (i.e. does not constrain).
379:             *   <li>NAME_MATCH = 0: input name matches name.
380:             *   <li>NAME_NARROWS = 1: input name narrows name (is lower in the naming 
381:             *       subtree)
382:             *   <li>NAME_WIDENS = 2: input name widens name (is higher in the naming 
383:             *       subtree)
384:             *   <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but 
385:             *       is same type.
386:             * </ul>.  These results are used in checking NameConstraints during
387:             * certification path verification.
388:             * <p>
389:             * [RFC2459] The syntax of iPAddress MUST be as described in section 
390:             * 4.2.1.7 with the following additions specifically for Name Constraints.  
391:             * For IPv4 addresses, the ipAddress field of generalName MUST contain 
392:             * eight (8) octets, encoded in the style of RFC 1519 (CIDR) to represent an
393:             * address range.[RFC 1519]  For IPv6 addresses, the ipAddress field
394:             * MUST contain 32 octets similarly encoded.  For example, a name
395:             * constraint for "class C" subnet 10.9.8.0 shall be represented as the
396:             * octets 0A 09 08 00 FF FF FF 00, representing the CIDR notation
397:             * 10.9.8.0/255.255.255.0.
398:             * <p>
399:             * @param inputName to be checked for being constrained
400:             * @returns constraint type above
401:             * @throws UnsupportedOperationException if name is not exact match, but 
402:             * narrowing and widening are not supported for this name type.
403:             */
404:            public int constrains(GeneralNameInterface inputName)
405:                    throws UnsupportedOperationException {
406:                int constraintType;
407:                if (inputName == null)
408:                    constraintType = NAME_DIFF_TYPE;
409:                else if (inputName.getType() != NAME_IP)
410:                    constraintType = NAME_DIFF_TYPE;
411:                else if (((IPAddressName) inputName).equals(this ))
412:                    constraintType = NAME_MATCH;
413:                else {
414:                    byte[] otherAddress = ((IPAddressName) inputName)
415:                            .getBytes();
416:                    if (otherAddress.length == 4 && address.length == 4)
417:                        // Two host addresses
418:                        constraintType = NAME_SAME_TYPE;
419:                    else if ((otherAddress.length == 8 && address.length == 8)
420:                            || (otherAddress.length == 32 && address.length == 32)) {
421:                        // Two subnet addresses
422:                        // See if one address fully encloses the other address
423:                        boolean otherSubsetOfThis = true;
424:                        boolean this SubsetOfOther = true;
425:                        boolean this Empty = false;
426:                        boolean otherEmpty = false;
427:                        int maskOffset = address.length / 2;
428:                        for (int i = 0; i < maskOffset; i++) {
429:                            if ((byte) (address[i] & address[i + maskOffset]) != address[i])
430:                                this Empty = true;
431:                            if ((byte) (otherAddress[i] & otherAddress[i
432:                                    + maskOffset]) != otherAddress[i])
433:                                otherEmpty = true;
434:                            if (!(((byte) (address[i + maskOffset] & otherAddress[i
435:                                    + maskOffset]) == address[i + maskOffset]) && ((byte) (address[i] & address[i
436:                                    + maskOffset]) == (byte) (otherAddress[i] & address[i
437:                                    + maskOffset])))) {
438:                                otherSubsetOfThis = false;
439:                            }
440:                            if (!(((byte) (otherAddress[i + maskOffset] & address[i
441:                                    + maskOffset]) == otherAddress[i
442:                                    + maskOffset]) && ((byte) (otherAddress[i] & otherAddress[i
443:                                    + maskOffset]) == (byte) (address[i] & otherAddress[i
444:                                    + maskOffset])))) {
445:                                this SubsetOfOther = false;
446:                            }
447:                        }
448:                        if (this Empty || otherEmpty) {
449:                            if (this Empty && otherEmpty)
450:                                constraintType = NAME_MATCH;
451:                            else if (this Empty)
452:                                constraintType = NAME_WIDENS;
453:                            else
454:                                constraintType = NAME_NARROWS;
455:                        } else if (otherSubsetOfThis)
456:                            constraintType = NAME_NARROWS;
457:                        else if (this SubsetOfOther)
458:                            constraintType = NAME_WIDENS;
459:                        else
460:                            constraintType = NAME_SAME_TYPE;
461:                    } else if (otherAddress.length == 8
462:                            || otherAddress.length == 32) {
463:                        //Other is a subnet, this is a host address
464:                        int i = 0;
465:                        int maskOffset = otherAddress.length / 2;
466:                        for (; i < maskOffset; i++) {
467:                            // Mask this address by other address mask and compare to other address
468:                            // If all match, then this address is in other address subnet
469:                            if ((address[i] & otherAddress[i + maskOffset]) != otherAddress[i])
470:                                break;
471:                        }
472:                        if (i == maskOffset)
473:                            constraintType = NAME_WIDENS;
474:                        else
475:                            constraintType = NAME_SAME_TYPE;
476:                    } else if (address.length == 8 || address.length == 32) {
477:                        //This is a subnet, other is a host address
478:                        int i = 0;
479:                        int maskOffset = address.length / 2;
480:                        for (; i < maskOffset; i++) {
481:                            // Mask other address by this address mask and compare to this address
482:                            if ((otherAddress[i] & address[i + maskOffset]) != address[i])
483:                                break;
484:                        }
485:                        if (i == maskOffset)
486:                            constraintType = NAME_NARROWS;
487:                        else
488:                            constraintType = NAME_SAME_TYPE;
489:                    } else {
490:                        constraintType = NAME_SAME_TYPE;
491:                    }
492:                }
493:                return constraintType;
494:            }
495:
496:            /**
497:             * Return subtree depth of this name for purposes of determining
498:             * NameConstraints minimum and maximum bounds and for calculating
499:             * path lengths in name subtrees.
500:             *
501:             * @returns distance of name from root
502:             * @throws UnsupportedOperationException if not supported for this name type
503:             */
504:            public int subtreeDepth() throws UnsupportedOperationException {
505:                throw new UnsupportedOperationException(
506:                        "subtreeDepth() not defined for IPAddressName");
507:            }
508:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.