Source Code Cross Referenced for ASN1Choice.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » security » asn1 » 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.asn1 
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:         * @author Vladimir N. Molotkov, Stepan M. Mishura
019:         * @version $Revision$
020:         */package org.apache.harmony.security.asn1;
021:
022:        import java.io.IOException;
023:        import java.math.BigInteger;
024:        import java.util.Arrays;
025:        import java.util.Iterator;
026:        import java.util.Map;
027:        import java.util.TreeMap;
028:
029:        import org.apache.harmony.security.internal.nls.Messages;
030:
031:        /**
032:         * This abstract class represents ASN.1 Choice type.
033:         * 
034:         * To implement custom ASN.1 choice type an application class
035:         * must provide implementation for the following methods:
036:         *     getIndex()
037:         *     getObjectToEncode()
038:         * 
039:         * There are two ways to implement custom ASN.1 choice type:
040:         * with application class that represents ASN.1 custom choice type or without. 
041:         * The key point is how a value of choice type is stored by application classes.
042:         * 
043:         * For example, let's consider the following ASN.1 notations
044:         * (see http://www.ietf.org/rfc/rfc3280.txt)
045:         * 
046:         * Time ::= CHOICE {
047:         *       utcTime        UTCTime,
048:         *       generalTime    GeneralizedTime
049:         * }
050:         * 
051:         * Validity ::= SEQUENCE {
052:         *       notBefore      Time,
053:         *       notAfter       Time 
054:         *  }
055:         * 
056:         * 1)First approach:
057:         * No application class to represent ASN.1 Time notation
058:         * 
059:         * The Time notation is a choice of different time formats: UTC and Generalized.
060:         * Both of them are mapped to java.util.Date object, so an application
061:         * class that represents ASN.1 Validity notation may keep values
062:         * as Date objects.
063:         * 
064:         * So a custom ASN.1 Time choice type should map its notation to Date object.
065:         * 
066:         * class Time {
067:         * 
068:         *     // custom ASN.1 choice class: maps Time to is notation
069:         *     public static final ASN1Choice asn1 = new ASN1Choice(new ASN1Type[] {
070:         *         ASN1GeneralizedTime.asn1, ASN1UTCTime.asn1 }) {
071:         *
072:         *         public int getIndex(java.lang.Object object) {
073:         *             return 0; // always encode as ASN1GeneralizedTime
074:         *         }
075:         *
076:         *         public Object getObjectToEncode(Object object) {
077:         *         
078:         *             // A value to be encoded value is a Date object
079:         *             // pass it to custom time class  
080:         *             return object;
081:         *         }
082:         *     };
083:         * }
084:         * 
085:         * class Validity {
086:         * 
087:         *     private Date notBefore;    // choice as Date 
088:         *     private Date notAfter;     // choice as Date
089:         * 
090:         *     ... // constructors and other methods go here
091:         * 
092:         *     // custom ASN.1 sequence class: maps Validity class to is notation
093:         *     public static final ASN1Sequence ASN1
094:         *         = new ASN1Sequence(new ASN1Type[] {Time.asn1, Time.asn1 }) {
095:         * 
096:         *         protected Object getObject(Object[] values) {
097:         * 
098:         *             // ASN.1 Time choice passed Data object - use it 
099:         *             return new Validity((Date) values[0], (Date) values[1]);
100:         *         }
101:         *
102:         *         protected void getValues(Object object, Object[] values) {
103:         *
104:         *             Validity validity = (Validity) object;
105:         *
106:         *             // pass Date objects to ASN.1 Time choice
107:         *             values[0] = validity.notBefore;
108:         *             values[1] = validity.notAfter;
109:         *         }
110:         *     }
111:         * }
112:         * 
113:         * 2)Second approach:
114:         * There is an application class to represent ASN.1 Time notation
115:         * 
116:         * If it is a matter what time format should be used to decode/encode
117:         * Date objects a class to represent ASN.1 Time notation must be created.
118:         * 
119:         * For example,
120:         *  
121:         * class Time {
122:         * 
123:         *     private Date utcTime; 
124:         *     private Date gTime;
125:         * 
126:         *     ... // constructors and other methods go here
127:         *  
128:         *     // custom ASN.1 choice class: maps Time to is notation
129:         *     public static final ASN1Choice asn1 = new ASN1Choice(new ASN1Type[] {
130:         *         ASN1GeneralizedTime.asn1, ASN1UTCTime.asn1 }) {
131:         *
132:         *         public Object getDecodedObject(BerInputStream in) {
133:         *
134:         *             // create Time object to pass as decoded value
135:         *             Time time = new Time();
136:         * 
137:         *             if (in.choiceIndex==0) {
138:         *                 // we decoded GeneralizedTime
139:         *                 // store decoded Date value in corresponding field
140:         *                 time.gTime = in.content;
141:         *                 // return it
142:         *                 return time;
143:         *             } else {
144:         *                 // we decoded UTCTime
145:         *                 // store decoded Date value in corresponding field
146:         *                 time.utcTime = in.content;
147:         *                 // return it
148:         *                 return time;
149:         *             }
150:         *         }
151:         *
152:         *         public int getIndex(java.lang.Object object) {
153:         *             Time time = (Time)object;
154:         *             if(time.utcTime!=null){
155:         *                 // encode Date as UTCTime
156:         *                 return 1;
157:         *             } else {
158:         *                 // otherwise encode Date as GeneralizedTime
159:         *                 return 0;
160:         *             } 
161:         *         }
162:         *
163:         *         public Object getObjectToEncode(Object object) {
164:         *             Time time = (Time)object;
165:         *             if(time.utcTime!=null){
166:         *                 // encode Date as UTCTime
167:         *                 return 1;
168:         *             } else {
169:         *                 // otherwise encode Date as GeneralizedTime
170:         *                 return 0;
171:         *             } 
172:         *         }
173:         *     };
174:         * }
175:         *
176:         * So now Validity class must keep all values in Time object
177:         * and its custom ASN.1 sequence class must handle this class of objects
178:         *
179:         * class Validity {
180:         * 
181:         *     private Time notBefore;    // now it is a Time!!! 
182:         *     private Time notAfter;     // now it is a Time!!!
183:         * 
184:         *     ... // constructors and other methods go here
185:         * 
186:         *     // custom ASN.1 sequence class: maps Validity class to is notation
187:         *     public static final ASN1Sequence ASN1
188:         *         = new ASN1Sequence(new ASN1Type[] {Time.asn1, Time.asn1 }) {
189:         * 
190:         *         protected Object getObject(Object[] values) {
191:         * 
192:         *             // We've gotten Time objects here !!!
193:         *             return new Validity((Time) values[0], (Time) values[1]);
194:         *         }
195:         *
196:         *         protected void getValues(Object object, Object[] values) {
197:         *
198:         *             Validity validity = (Validity) object;
199:         *
200:         *             // pass Time objects to ASN.1 Time choice
201:         *             values[0] = validity.notBefore;
202:         *             values[1] = validity.notAfter;
203:         *         }
204:         *     }
205:         * }
206:         * 
207:         * @see http://asn1.elibel.tm.fr/en/standards/index.htm
208:         */
209:
210:        public abstract class ASN1Choice extends ASN1Type {
211:
212:            public final ASN1Type[] type;
213:
214:            // identifiers table: [2][number of distinct identifiers]
215:            // identifiers[0]: stores identifiers (includes nested choices)
216:            // identifiers[1]: stores identifiers' indexes in array of types
217:            private final int[][] identifiers;
218:
219:            /**
220:             * Constructs ASN.1 choice type.
221:             * 
222:             * @param type -
223:             *            an array of one or more ASN.1 type alternatives.
224:             * @throws IllegalArgumentException -
225:             *             type parameter is invalid
226:             */
227:            public ASN1Choice(ASN1Type[] type) {
228:                super (TAG_CHOICE); // has not tag number
229:
230:                if (type.length == 0) {
231:                    throw new IllegalArgumentException(Messages.getString(
232:                            "security.10E", //$NON-NLS-1$
233:                            getClass().getName()));
234:                }
235:
236:                // create map of all identifiers
237:                TreeMap map = new TreeMap();
238:                for (int index = 0; index < type.length; index++) {
239:
240:                    ASN1Type t = type[index];
241:
242:                    if (t instanceof  ASN1Any) {
243:                        // ASN.1 ANY is not allowed,
244:                        // even it is a single component (not good for nested choices)
245:                        throw new IllegalArgumentException(Messages.getString(
246:                                "security.10F", //$NON-NLS-1$
247:                                getClass().getName())); // FIXME name
248:                    } else if (t instanceof  ASN1Choice) {
249:
250:                        // add all choice's identifiers
251:                        int[][] choiceToAdd = ((ASN1Choice) t).identifiers;
252:                        for (int j = 0; j < choiceToAdd[0].length; j++) {
253:                            addIdentifier(map, choiceToAdd[0][j], index);
254:                        }
255:                        continue;
256:                    }
257:
258:                    // add primitive identifier
259:                    if (t.checkTag(t.id)) {
260:                        addIdentifier(map, t.id, index);
261:                    }
262:
263:                    // add constructed identifier
264:                    if (t.checkTag(t.constrId)) {
265:                        addIdentifier(map, t.constrId, index);
266:                    }
267:                }
268:
269:                // fill identifiers array
270:                int size = map.size();
271:                identifiers = new int[2][size];
272:                Iterator it = map.entrySet().iterator();
273:
274:                for (int i = 0; i < size; i++) {
275:                    Map.Entry entry = (Map.Entry) it.next();
276:                    BigInteger identifier = (BigInteger) entry.getKey();
277:
278:                    identifiers[0][i] = identifier.intValue();
279:                    identifiers[1][i] = ((BigInteger) entry.getValue())
280:                            .intValue();
281:                }
282:
283:                this .type = type;
284:            }
285:
286:            private void addIdentifier(TreeMap map, int identifier, int index) {
287:                if (map.put(BigInteger.valueOf(identifier), BigInteger
288:                        .valueOf(index)) != null) {
289:                    throw new IllegalArgumentException(Messages.getString(
290:                            "security.10F", //$NON-NLS-1$
291:                            getClass().getName())); // FIXME name
292:                }
293:            }
294:
295:            //
296:            //
297:            // DECODE
298:            //
299:            //
300:
301:            /**
302:             * Tests whether one of choice alternatives has the same identifier or not.
303:             * 
304:             * @param identifier -
305:             *            ASN.1 identifier to be verified
306:             * @return - true if one of choice alternatives has the same identifier,
307:             *         otherwise false;
308:             */
309:            public final boolean checkTag(int identifier) {
310:                return Arrays.binarySearch(identifiers[0], identifier) >= 0;
311:            }
312:
313:            public Object decode(BerInputStream in) throws IOException {
314:
315:                int index = Arrays.binarySearch(identifiers[0], in.tag);
316:                if (index < 0) {
317:                    throw new ASN1Exception(Messages.getString("security.110", //$NON-NLS-1$
318:                            getClass().getName()));// FIXME message
319:                }
320:
321:                index = identifiers[1][index];
322:
323:                in.content = type[index].decode(in);
324:
325:                // set index for getDecodedObject method
326:                in.choiceIndex = index;
327:
328:                if (in.isVerify) {
329:                    return null;
330:                }
331:                return getDecodedObject(in);
332:            }
333:
334:            //
335:            //
336:            // ENCODE
337:            //
338:            //
339:
340:            public void encodeASN(BerOutputStream out) {
341:                encodeContent(out);
342:            }
343:
344:            public final void encodeContent(BerOutputStream out) {
345:                out.encodeChoice(this );
346:            }
347:
348:            /**
349:             * TODO Put method description here
350:             *
351:             * @param object - an object to be encoded
352:             * @return
353:             */
354:            public abstract int getIndex(Object object);
355:
356:            public abstract Object getObjectToEncode(Object object);
357:
358:            public final void setEncodingContent(BerOutputStream out) {
359:                out.getChoiceLength(this);
360:            }
361:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.