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


001:        /*
002:         * @(#)DerValue.java	1.60 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.util;
029:
030:        import java.io.*;
031:        import java.math.BigInteger;
032:        import java.util.Date;
033:
034:        /**
035:         * Represents a single DER-encoded value.  DER encoding rules are a subset
036:         * of the "Basic" Encoding Rules (BER), but they only support a single way
037:         * ("Definite" encoding) to encode any given value.
038:         *
039:         * <P>All DER-encoded data are triples <em>{type, length, data}</em>.  This
040:         * class represents such tagged values as they have been read (or constructed),
041:         * and provides structured access to the encoded data.
042:         *
043:         * <P>At this time, this class supports only a subset of the types of DER
044:         * data encodings which are defined.  That subset is sufficient for parsing
045:         * most X.509 certificates, and working with selected additional formats
046:         * (such as PKCS #10 certificate requests, and some kinds of PKCS #7 data).
047:         *
048:         * A note with respect to T61/Teletex strings: From RFC 1617, section 4.1.3
049:         * and RFC 2459, section 4.1.2.4., we assume that this kind of string will
050:         * contain ISO-8859-1 characters only.
051:         *
052:         * @version 1.60, 10/10/06
053:         *
054:         * @author David Brownell
055:         * @author Amit Kapoor
056:         * @author Hemma Prafullchandra
057:         */
058:        public class DerValue {
059:            /** The tag class types */
060:            public static final byte TAG_UNIVERSAL = (byte) 0x000;
061:            public static final byte TAG_APPLICATION = (byte) 0x040;
062:            public static final byte TAG_CONTEXT = (byte) 0x080;
063:            public static final byte TAG_PRIVATE = (byte) 0x0c0;
064:
065:            /** The DER tag of the value; one of the tag_ constants. */
066:            public byte tag;
067:
068:            protected DerInputBuffer buffer;
069:
070:            /**
071:             * The DER-encoded data of the value.
072:             */
073:            public DerInputStream data;
074:
075:            private int length;
076:
077:            /*
078:             * The type starts at the first byte of the encoding, and
079:             * is one of these tag_* values.  That may be all the type
080:             * data that is needed.
081:             */
082:
083:            /*
084:             * These tags are the "universal" tags ... they mean the same
085:             * in all contexts.  (Mask with 0x1f -- five bits.)
086:             */
087:
088:            /** Tag value indicating an ASN.1 "BOOLEAN" value. */
089:            public final static byte tag_Boolean = 0x01;
090:
091:            /** Tag value indicating an ASN.1 "INTEGER" value. */
092:            public final static byte tag_Integer = 0x02;
093:
094:            /** Tag value indicating an ASN.1 "BIT STRING" value. */
095:            public final static byte tag_BitString = 0x03;
096:
097:            /** Tag value indicating an ASN.1 "OCTET STRING" value. */
098:            public final static byte tag_OctetString = 0x04;
099:
100:            /** Tag value indicating an ASN.1 "NULL" value. */
101:            public final static byte tag_Null = 0x05;
102:
103:            /** Tag value indicating an ASN.1 "OBJECT IDENTIFIER" value. */
104:            public final static byte tag_ObjectId = 0x06;
105:
106:            /** Tag value including an ASN.1 "ENUMERATED" value */
107:            public final static byte tag_Enumerated = 0x0A;
108:
109:            /** Tag value indicating an ASN.1 "UTF8String" value. */
110:            public final static byte tag_UTF8String = 0x0C;
111:
112:            /** Tag value including a "printable" string */
113:            public final static byte tag_PrintableString = 0x13;
114:
115:            /** Tag value including a "teletype" string */
116:            public final static byte tag_T61String = 0x14;
117:
118:            /** Tag value including an ASCII string */
119:            public final static byte tag_IA5String = 0x16;
120:
121:            /** Tag value indicating an ASN.1 "UTCTime" value. */
122:            public final static byte tag_UtcTime = 0x17;
123:
124:            /** Tag value indicating an ASN.1 "GeneralizedTime" value. */
125:            public final static byte tag_GeneralizedTime = 0x18;
126:
127:            /** Tag value indicating an ASN.1 "GenerallString" value. */
128:            public final static byte tag_GeneralString = 0x1B;
129:
130:            /** Tag value indicating an ASN.1 "UniversalString" value. */
131:            public final static byte tag_UniversalString = 0x1C;
132:
133:            /** Tag value indicating an ASN.1 "BMPString" value. */
134:            public final static byte tag_BMPString = 0x1E;
135:
136:            // CONSTRUCTED seq/set
137:
138:            /** 
139:             * Tag value indicating an ASN.1
140:             * "SEQUENCE" (zero to N elements, order is significant). 
141:             */
142:            public final static byte tag_Sequence = 0x30;
143:
144:            /**
145:             * Tag value indicating an ASN.1
146:             * "SEQUENCE OF" (one to N elements, order is significant).
147:             */
148:            public final static byte tag_SequenceOf = 0x30;
149:
150:            /** 
151:             * Tag value indicating an ASN.1
152:             * "SET" (zero to N members, order does not matter).
153:             */
154:            public final static byte tag_Set = 0x31;
155:
156:            /** 
157:             * Tag value indicating an ASN.1
158:             * "SET OF" (one to N members, order does not matter).
159:             */
160:            public final static byte tag_SetOf = 0x31;
161:
162:            /*
163:             * These values are the high order bits for the other kinds of tags.
164:             */
165:
166:            /**
167:             * Returns true if the tag class is UNIVERSAL.
168:             */
169:            public boolean isUniversal() {
170:                return ((tag & 0x0c0) == 0x000);
171:            }
172:
173:            /**
174:             * Returns true if the tag class is APPLICATION.
175:             */
176:            public boolean isApplication() {
177:                return ((tag & 0x0c0) == 0x040);
178:            }
179:
180:            /**
181:             * Returns true iff the CONTEXT SPECIFIC bit is set in the type tag.
182:             * This is associated with the ASN.1 "DEFINED BY" syntax.
183:             */
184:            public boolean isContextSpecific() {
185:                return ((tag & 0x0c0) == 0x080);
186:            }
187:
188:            /**
189:             * Returns true iff the CONTEXT SPECIFIC TAG matches the passed tag.
190:             */
191:            public boolean isContextSpecific(byte cntxtTag) {
192:                if (!isContextSpecific()) {
193:                    return false;
194:                }
195:                return ((tag & 0x01f) == cntxtTag);
196:            }
197:
198:            boolean isPrivate() {
199:                return ((tag & 0x0c0) == 0x0c0);
200:            }
201:
202:            /** Returns true iff the CONSTRUCTED bit is set in the type tag. */
203:            public boolean isConstructed() {
204:                return ((tag & 0x020) == 0x020);
205:            }
206:
207:            /**
208:             * Returns true iff the CONSTRUCTED TAG matches the passed tag.
209:             */
210:            public boolean isConstructed(byte constructedTag) {
211:                if (!isConstructed()) {
212:                    return false;
213:                }
214:                return ((tag & 0x01f) == constructedTag);
215:            }
216:
217:            /**
218:             * Creates a PrintableString or UTF8string DER value from a string
219:             */
220:            public DerValue(String value) throws IOException {
221:                boolean isPrintableString = true;
222:                for (int i = 0; i < value.length(); i++) {
223:                    if (!isPrintableStringChar(value.charAt(i))) {
224:                        isPrintableString = false;
225:                        break;
226:                    }
227:                }
228:
229:                init(isPrintableString ? tag_PrintableString : tag_UTF8String,
230:                        value);
231:            }
232:
233:            /**
234:             * Creates a string type DER value from a String object
235:             * @param stringTag the tag for the DER value to create
236:             * @param value the String object to use for the DER value
237:             */
238:            public DerValue(byte stringTag, String value) throws IOException {
239:                init(stringTag, value);
240:            }
241:
242:            /**
243:             * Creates a DerValue from a tag and some DER-encoded data.
244:             *
245:             * @param tag the DER type tag
246:             * @param data the DER-encoded data
247:             */
248:            public DerValue(byte tag, byte[] data) {
249:                this .tag = tag;
250:                buffer = new DerInputBuffer((byte[]) data.clone());
251:                length = data.length;
252:                this .data = new DerInputStream(buffer);
253:                this .data.mark(Integer.MAX_VALUE);
254:            }
255:
256:            /*
257:             * package private
258:             */
259:            DerValue(DerInputBuffer in) throws IOException {
260:                // TODO: must also parse BER-encoded constructed
261:                // values such as sequences, sets...
262:
263:                tag = (byte) in.read();
264:                byte lenByte = (byte) in.read();
265:                length = DerInputStream.getLength((lenByte & 0xff), in);
266:                if (length == -1) { // indefinite length encoding found
267:                    DerInputBuffer inbuf = in.dup();
268:                    int readLen = inbuf.available();
269:                    int offset = 2; // for tag and length bytes
270:                    byte[] indefData = new byte[readLen + offset];
271:                    indefData[0] = tag;
272:                    indefData[1] = lenByte;
273:                    DataInputStream dis = new DataInputStream(inbuf);
274:                    dis.readFully(indefData, offset, readLen);
275:                    dis.close();
276:                    DerIndefLenConverter derIn = new DerIndefLenConverter();
277:                    inbuf = new DerInputBuffer(derIn.convert(indefData));
278:                    if (tag != inbuf.read())
279:                        throw new IOException(
280:                                "Indefinite length encoding not supported");
281:                    length = DerInputStream.getLength(inbuf);
282:                    buffer = inbuf.dup();
283:                    buffer.truncate(length);
284:                    data = new DerInputStream(buffer);
285:                    // indefinite form is encoded by sending a length field with a 
286:                    // length of 0. - i.e. [1000|0000].  
287:                    // the object is ended by sending two zero bytes.
288:                    in.skip(length + offset);
289:                } else {
290:
291:                    buffer = in.dup();
292:                    buffer.truncate(length);
293:                    data = new DerInputStream(buffer);
294:
295:                    in.skip(length);
296:                }
297:            }
298:
299:            /**
300:             * Get an ASN.1/DER encoded datum from a buffer.  The
301:             * entire buffer must hold exactly one datum, including
302:             * its tag and length.
303:             *
304:             * @param buf buffer holding a single DER-encoded datum.
305:             */
306:            public DerValue(byte[] buf) throws IOException {
307:                init(true, new ByteArrayInputStream(buf));
308:            }
309:
310:            /**
311:             * Get an ASN.1/DER encoded datum from part of a buffer.
312:             * That part of the buffer must hold exactly one datum, including
313:             * its tag and length.
314:             *
315:             * @param buf the buffer
316:             * @param offset start point of the single DER-encoded dataum
317:             * @param length how many bytes are in the encoded datum
318:             */
319:            public DerValue(byte[] buf, int offset, int len) throws IOException {
320:                init(true, new ByteArrayInputStream(buf, offset, len));
321:            }
322:
323:            /**
324:             * Get an ASN1/DER encoded datum from an input stream.  The
325:             * stream may have additional data following the encoded datum.
326:             * In case of indefinite length encoded datum, the input stream
327:             * must hold only one datum.
328:             *
329:             * @param in the input stream holding a single DER datum,
330:             *	which may be followed by additional data
331:             */
332:            public DerValue(InputStream in) throws IOException {
333:                init(false, in);
334:            }
335:
336:            private void init(byte stringTag, String value) throws IOException {
337:                String enc = null;
338:
339:                tag = stringTag;
340:
341:                switch (stringTag) {
342:                case tag_PrintableString:
343:                case tag_IA5String:
344:                case tag_GeneralString:
345:                    enc = "ASCII";
346:                    break;
347:                case tag_T61String:
348:                    enc = "ISO-8859-1";
349:                    break;
350:                case tag_BMPString:
351:                    enc = "UnicodeBigUnmarked";
352:                    break;
353:                case tag_UTF8String:
354:                    enc = "UTF8";
355:                    break;
356:                // TBD: Need encoder for UniversalString before it can
357:                // be handled.
358:                default:
359:                    throw new IllegalArgumentException(
360:                            "Unsupported DER string type");
361:                }
362:
363:                byte[] buf = value.getBytes(enc);
364:                length = buf.length;
365:                buffer = new DerInputBuffer(buf);
366:                data = new DerInputStream(buffer);
367:                data.mark(Integer.MAX_VALUE);
368:            }
369:
370:            /*
371:             * helper routine
372:             */
373:            private void init(boolean fullyBuffered, InputStream in)
374:                    throws IOException {
375:
376:                tag = (byte) in.read();
377:                byte lenByte = (byte) in.read();
378:                length = DerInputStream.getLength((lenByte & 0xff), in);
379:                if (length == -1) { // indefinite length encoding found
380:                    int readLen = in.available();
381:                    int offset = 2; // for tag and length bytes
382:                    byte[] indefData = new byte[readLen + offset];
383:                    indefData[0] = tag;
384:                    indefData[1] = lenByte;
385:                    DataInputStream dis = new DataInputStream(in);
386:                    dis.readFully(indefData, offset, readLen);
387:                    dis.close();
388:                    DerIndefLenConverter derIn = new DerIndefLenConverter();
389:                    in = new ByteArrayInputStream(derIn.convert(indefData));
390:                    if (tag != in.read())
391:                        throw new IOException(
392:                                "Indefinite length encoding not supported");
393:                    length = DerInputStream.getLength(in);
394:                }
395:                if (length == 0)
396:                    return;
397:
398:                if (fullyBuffered && in.available() != length)
399:                    throw new IOException(
400:                            "extra data given to DerValue constructor");
401:
402:                byte[] bytes = new byte[length];
403:
404:                // n.b. readFully not needed in normal fullyBuffered case
405:                DataInputStream dis = new DataInputStream(in);
406:
407:                dis.readFully(bytes);
408:                buffer = new DerInputBuffer(bytes);
409:                data = new DerInputStream(buffer);
410:            }
411:
412:            /**
413:             * Encode an ASN1/DER encoded datum onto a DER output stream.
414:             */
415:            public void encode(DerOutputStream out) throws IOException {
416:                out.write(tag);
417:                out.putLength(length);
418:                // excess copies ... DerInputBuffer.write(OutStream)
419:                if (length > 0) {
420:                    byte[] value = new byte[length];
421:                    synchronized (buffer) {
422:                        buffer.reset();
423:                        if (buffer.read(value) != length) {
424:                            throw new IOException(
425:                                    "short DER value read (encode)");
426:                        }
427:                        out.write(value);
428:                    }
429:                }
430:            }
431:
432:            public final DerInputStream getData() {
433:                return data;
434:            }
435:
436:            public final byte getTag() {
437:                return tag;
438:            }
439:
440:            /**
441:             * Returns an ASN.1 BOOLEAN
442:             *
443:             * @return the boolean held in this DER value
444:             */
445:            public boolean getBoolean() throws IOException {
446:                if (tag != tag_Boolean) {
447:                    throw new IOException("DerValue.getBoolean, not a BOOLEAN "
448:                            + tag);
449:                }
450:                if (length != 1) {
451:                    throw new IOException(
452:                            "DerValue.getBoolean, invalid length " + length);
453:                }
454:                if (buffer.read() != 0) {
455:                    return true;
456:                }
457:                return false;
458:            }
459:
460:            /**
461:             * Returns an ASN.1 OBJECT IDENTIFIER.
462:             *
463:             * @return the OID held in this DER value
464:             */
465:            public ObjectIdentifier getOID() throws IOException {
466:                if (tag != tag_ObjectId)
467:                    throw new IOException("DerValue.getOID, not an OID " + tag);
468:                return new ObjectIdentifier(buffer);
469:            }
470:
471:            private byte[] append(byte[] a, byte[] b) {
472:                if (a == null)
473:                    return b;
474:
475:                byte[] ret = new byte[a.length + b.length];
476:                System.arraycopy(a, 0, ret, 0, a.length);
477:                System.arraycopy(b, 0, ret, a.length, b.length);
478:
479:                return ret;
480:            }
481:
482:            /**
483:             * Returns an ASN.1 OCTET STRING
484:             *
485:             * @return the octet string held in this DER value
486:             */
487:            public byte[] getOctetString() throws IOException {
488:                byte[] bytes;
489:
490:                if (tag != tag_OctetString && !isConstructed(tag_OctetString)) {
491:                    throw new IOException(
492:                            "DerValue.getOctetString, not an Octet String: "
493:                                    + tag);
494:                }
495:                bytes = new byte[length];
496:                if (buffer.read(bytes) != length)
497:                    throw new IOException("short read on DerValue buffer");
498:                if (isConstructed()) {
499:                    DerInputStream in = new DerInputStream(bytes);
500:                    bytes = null;
501:                    while (in.available() != 0) {
502:                        bytes = append(bytes, in.getOctetString());
503:                    }
504:                }
505:                return bytes;
506:            }
507:
508:            /**
509:             * Returns an ASN.1 INTEGER value as an integer. 
510:             *
511:             * @return the integer held in this DER value.
512:             */
513:            public int getInteger() throws IOException {
514:                if (tag != tag_Integer) {
515:                    throw new IOException("DerValue.getInteger, not an int "
516:                            + tag);
517:                }
518:                return buffer.getInteger(data.available());
519:            }
520:
521:            /**
522:             * Returns an ASN.1 INTEGER value as a BigInteger.
523:             *
524:             * @return the integer held in this DER value as a BigInteger.
525:             */
526:            public BigInteger getBigInteger() throws IOException {
527:                if (tag != tag_Integer)
528:                    throw new IOException("DerValue.getBigInteger, not an int "
529:                            + tag);
530:                return buffer.getBigInteger(data.available());
531:            }
532:
533:            /**
534:             * Returns an ASN.1 ENUMERATED value.
535:             *
536:             * @return the integer held in this DER value.
537:             */
538:            public int getEnumerated() throws IOException {
539:                if (tag != tag_Enumerated) {
540:                    throw new IOException(
541:                            "DerValue.getEnumerated, incorrect tag: " + tag);
542:                }
543:                return buffer.getInteger(data.available());
544:            }
545:
546:            /**
547:             * Returns an ASN.1 BIT STRING value.  The bit string must be byte-aligned.
548:             *
549:             * @return the bit string held in this value
550:             */
551:            public byte[] getBitString() throws IOException {
552:                if (tag != tag_BitString)
553:                    throw new IOException(
554:                            "DerValue.getBitString, not a bit string " + tag);
555:
556:                return buffer.getBitString();
557:            }
558:
559:            /**
560:             * Returns an ASN.1 BIT STRING value that need not be byte-aligned.
561:             *
562:             * @return a BitArray representing the bit string held in this value
563:             */
564:            public BitArray getUnalignedBitString() throws IOException {
565:                if (tag != tag_BitString)
566:                    throw new IOException(
567:                            "DerValue.getBitString, not a bit string " + tag);
568:
569:                return buffer.getUnalignedBitString();
570:            }
571:
572:            /**
573:             * Returns the name component as a Java string, regardless of its
574:             * encoding restrictions (ASCII, T61, Printable, IA5, BMP, UTF8).
575:             */
576:            // TBD: Need encoder for UniversalString before it can be handled.
577:            public String getAsString() throws IOException {
578:                if (tag == tag_UTF8String)
579:                    return getUTF8String();
580:                else if (tag == tag_PrintableString)
581:                    return getPrintableString();
582:                else if (tag == tag_T61String)
583:                    return getT61String();
584:                else if (tag == tag_IA5String)
585:                    return getIA5String();
586:                /*
587:                  else if (tag == tag_UniversalString)
588:                  return getUniversalString();
589:                 */
590:                else if (tag == tag_BMPString)
591:                    return getBMPString();
592:                else if (tag == tag_GeneralString)
593:                    return getGeneralString();
594:                else
595:                    return null;
596:            }
597:
598:            /**
599:             * Returns an ASN.1 BIT STRING value, with the tag assumed implicit
600:             * based on the parameter.  The bit string must be byte-aligned.
601:             *
602:             * @params tagImplicit if true, the tag is assumed implicit.
603:             * @return the bit string held in this value
604:             */
605:            public byte[] getBitString(boolean tagImplicit) throws IOException {
606:                if (!tagImplicit) {
607:                    if (tag != tag_BitString)
608:                        throw new IOException(
609:                                "DerValue.getBitString, not a bit string "
610:                                        + tag);
611:                }
612:                return buffer.getBitString();
613:            }
614:
615:            /**
616:             * Returns an ASN.1 BIT STRING value, with the tag assumed implicit
617:             * based on the parameter.  The bit string need not be byte-aligned.
618:             *
619:             * @params tagImplicit if true, the tag is assumed implicit.
620:             * @return the bit string held in this value
621:             */
622:            public BitArray getUnalignedBitString(boolean tagImplicit)
623:                    throws IOException {
624:                if (!tagImplicit) {
625:                    if (tag != tag_BitString)
626:                        throw new IOException(
627:                                "DerValue.getBitString, not a bit string "
628:                                        + tag);
629:                }
630:                return buffer.getUnalignedBitString();
631:            }
632:
633:            /**
634:             * Helper routine to return all the bytes contained in the
635:             * DerInputStream associated with this object.
636:             */
637:            public byte[] getDataBytes() throws IOException {
638:                byte[] retVal = new byte[length];
639:                synchronized (data) {
640:                    data.reset();
641:                    data.getBytes(retVal);
642:                }
643:                return retVal;
644:            }
645:
646:            /**
647:             * Returns an ASN.1 STRING value
648:             *
649:             * @return the printable string held in this value
650:             */
651:            public String getPrintableString() throws IOException {
652:                if (tag != tag_PrintableString)
653:                    throw new IOException(
654:                            "DerValue.getPrintableString, not a string " + tag);
655:
656:                return new String(getDataBytes(), "ASCII");
657:            }
658:
659:            /**
660:             * Returns an ASN.1 T61 (Teletype) STRING value
661:             *
662:             * @return the teletype string held in this value
663:             */
664:            public String getT61String() throws IOException {
665:                if (tag != tag_T61String)
666:                    throw new IOException("DerValue.getT61String, not T61 "
667:                            + tag);
668:
669:                return new String(getDataBytes(), "ISO-8859-1");
670:            }
671:
672:            /**
673:             * Returns an ASN.1 IA5 (ASCII) STRING value
674:             *
675:             * @return the ASCII string held in this value
676:             */
677:            public String getIA5String() throws IOException {
678:                if (tag != tag_IA5String)
679:                    throw new IOException("DerValue.getIA5String, not IA5 "
680:                            + tag);
681:
682:                return new String(getDataBytes(), "ASCII");
683:            }
684:
685:            /**
686:             * Returns the ASN.1 BMP (Unicode) STRING value as a Java string.
687:             *
688:             * @return a string corresponding to the encoded BMPString held in 
689:             * this value
690:             */
691:            public String getBMPString() throws IOException {
692:                if (tag != tag_BMPString)
693:                    throw new IOException("DerValue.getBMPString, not BMP "
694:                            + tag);
695:
696:                // BMPString is the same as Unicode in big endian, unmarked
697:                // format.
698:                return new String(getDataBytes(), "UnicodeBigUnmarked");
699:            }
700:
701:            /**
702:             * Returns the ASN.1 UTF-8 STRING value as a Java String.
703:             *
704:             * @return a string corresponding to the encoded UTF8String held in 
705:             * this value
706:             */
707:            public String getUTF8String() throws IOException {
708:                if (tag != tag_UTF8String)
709:                    throw new IOException("DerValue.getUTF8String, not UTF-8 "
710:                            + tag);
711:
712:                return new String(getDataBytes(), "UTF8");
713:            }
714:
715:            /**
716:             * Returns the ASN.1 GENERAL STRING value as a Java String.
717:             *
718:             * @return a string corresponding to the encoded GeneralString held in 
719:             * this value
720:             */
721:            public String getGeneralString() throws IOException {
722:                if (tag != tag_GeneralString)
723:                    throw new IOException(
724:                            "DerValue.getGeneralString, not GeneralString "
725:                                    + tag);
726:
727:                return new String(getDataBytes(), "ASCII");
728:            }
729:
730:            /**
731:             * Returns a Date if the DerValue is UtcTime.
732:             *
733:             * @return the Date held in this DER value
734:             */
735:            public Date getUTCTime() throws IOException {
736:                if (tag != tag_UtcTime) {
737:                    throw new IOException(
738:                            "DerValue.getUTCTime, not a UtcTime: " + tag);
739:                }
740:                return buffer.getUTCTime(data.available());
741:            }
742:
743:            /**
744:             * Returns a Date if the DerValue is GeneralizedTime.
745:             *
746:             * @return the Date held in this DER value
747:             */
748:            public Date getGeneralizedTime() throws IOException {
749:                if (tag != tag_GeneralizedTime) {
750:                    throw new IOException(
751:                            "DerValue.getGeneralizedTime, not a GeneralizedTime: "
752:                                    + tag);
753:                }
754:                return buffer.getGeneralizedTime(data.available());
755:            }
756:
757:            /**
758:             * Returns true iff the other object is a DER value which
759:             * is bitwise equal to this one.
760:             *
761:             * @param other the object being compared with this one
762:             */
763:            public boolean equals(Object other) {
764:                if (other instanceof  DerValue)
765:                    return equals((DerValue) other);
766:                else
767:                    return false;
768:            }
769:
770:            /**
771:             * Bitwise equality comparison.  DER encoded values have a single
772:             * encoding, so that bitwise equality of the encoded values is an
773:             * efficient way to establish equivalence of the unencoded values.
774:             *
775:             * @param other the object being compared with this one
776:             */
777:            public boolean equals(DerValue other) {
778:                data.reset();
779:                other.data.reset();
780:                if (this  == other)
781:                    return true;
782:                else if (tag != other.tag) {
783:                    return false;
784:                } else {
785:                    return buffer.equals(other.buffer);
786:                }
787:            }
788:
789:            /**
790:             * Returns a printable representation of the value.
791:             *
792:             * @return printable representation of the value
793:             */
794:            public String toString() {
795:                try {
796:
797:                    String str = getAsString();
798:                    if (str != null)
799:                        return "\"" + str + "\"";
800:                    if (tag == tag_Null)
801:                        return "[DerValue, null]";
802:                    if (tag == tag_ObjectId)
803:                        return "OID." + getOID();
804:
805:                    // integers
806:                    else
807:                        return "[DerValue, tag = " + tag + ", length = "
808:                                + length + "]";
809:                } catch (IOException e) {
810:                    throw new IllegalArgumentException("misformatted DER value");
811:                }
812:            }
813:
814:            /**
815:             * Returns a DER-encoded value, such that if it's passed to the
816:             * DerValue constructor, a value equivalent to "this" is returned.
817:             *
818:             * @return DER-encoded value, including tag and length.
819:             */
820:            public byte[] toByteArray() throws IOException {
821:                DerOutputStream out = new DerOutputStream();
822:
823:                encode(out);
824:                data.reset();
825:                return out.toByteArray();
826:            }
827:
828:            /**
829:             * For "set" and "sequence" types, this function may be used
830:             * to return a DER stream of the members of the set or sequence.
831:             * This operation is not supported for primitive types such as
832:             * integers or bit strings.
833:             */
834:            public DerInputStream toDerInputStream() throws IOException {
835:                if (tag == tag_Sequence || tag == tag_Set)
836:                    return new DerInputStream(buffer);
837:                throw new IOException("toDerInputStream rejects tag type "
838:                        + tag);
839:            }
840:
841:            /**
842:             * Get the length of the encoded value.
843:             */
844:            public int length() {
845:                return length;
846:            }
847:
848:            /**
849:             * Determine if a character is one of the permissible characters for
850:             * PrintableString:
851:             * A-Z, a-z, 0-9, space, apostrophe (39), left and right parentheses,
852:             * plus sign, comma, hyphen, period, slash, colon, equals sign,
853:             * and question mark.
854:             *
855:             * Characters that are *not* allowed in PrintableString include
856:             * exclamation point, quotation mark, number sign, dollar sign,
857:             * percent sign, ampersand, asterisk, semicolon, less than sign,
858:             * greater than sign, at sign, left and right square brackets,
859:             * backslash, circumflex (94), underscore, back quote (96),
860:             * left and right curly brackets, vertical line, tilde,
861:             * and the control codes (0-31 and 127).
862:             *
863:             * This list is based on X.680 (the ASN.1 spec).
864:             */
865:            public static boolean isPrintableStringChar(char ch) {
866:                if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
867:                        || (ch >= '0' && ch <= '9')) {
868:                    return true;
869:                } else {
870:                    switch (ch) {
871:                    case ' ': /* space */
872:                    case '\'': /* apostrophe */
873:                    case '(': /* left paren */
874:                    case ')': /* right paren */
875:                    case '+': /* plus */
876:                    case ',': /* comma */
877:                    case '-': /* hyphen */
878:                    case '.': /* period */
879:                    case '/': /* slash */
880:                    case ':': /* colon */
881:                    case '=': /* equals */
882:                    case '?': /* question mark */
883:                        return true;
884:                    default:
885:                        return false;
886:                    }
887:                }
888:            }
889:
890:            /**
891:             * Create the tag of the attribute.
892:             *
893:             * @params class the tag class type, one of UNIVERSAL, CONTEXT,
894:             *               APPLICATION or PRIVATE
895:             * @params form if true, the value is constructed, otherwise it
896:             * is primitive.
897:             * @params val the tag value
898:             */
899:            public static byte createTag(byte tagClass, boolean form, byte val) {
900:                byte tag = (byte) (tagClass | val);
901:                if (form) {
902:                    tag |= (byte) 0x20;
903:                }
904:                return (tag);
905:            }
906:
907:            /**
908:             * Set the tag of the attribute. Commonly used to reset the
909:             * tag value used for IMPLICIT encodings.
910:             *
911:             * @params tag the tag value
912:             */
913:            public void resetTag(byte tag) {
914:                this .tag = tag;
915:            }
916:
917:            /**
918:             * Returns a hashcode for this DerValue.
919:             *
920:             * @return a hashcode for this DerValue.
921:             */
922:            public int hashCode() {
923:                return toString().hashCode();
924:            }
925:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.