Source Code Cross Referenced for X509Key.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:         * @(#)X509Key.java	1.89 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.*;
031:        import java.util.Arrays;
032:        import java.util.Properties;
033:        import java.security.Key;
034:        import java.security.PublicKey;
035:        import java.security.KeyFactory;
036:        import java.security.Security;
037:        import java.security.Provider;
038:        import java.security.InvalidKeyException;
039:        import java.security.NoSuchAlgorithmException;
040:        import java.security.spec.InvalidKeySpecException;
041:        import java.security.spec.X509EncodedKeySpec;
042:
043:        import sun.misc.HexDumpEncoder;
044:        import sun.security.util.*;
045:
046:        /**
047:         * Holds an X.509 key, for example a public key found in an X.509
048:         * certificate.  Includes a description of the algorithm to be used
049:         * with the key; these keys normally are used as
050:         * "SubjectPublicKeyInfo".
051:         *
052:         * <P>While this class can represent any kind of X.509 key, it may be
053:         * desirable to provide subclasses which understand how to parse keying
054:         * data.   For example, RSA public keys have two members, one for the
055:         * public modulus and one for the prime exponent.  If such a class is
056:         * provided, it is used when parsing X.509 keys.  If one is not provided,
057:         * the key still parses correctly.
058:         *
059:         * @version 1.81, 02/02/00
060:         * @author David Brownell 
061:         */
062:        public class X509Key implements  PublicKey {
063:
064:            /** use serialVersionUID from JDK 1.1. for interoperability */
065:            private static final long serialVersionUID = -5359250853002055002L;
066:
067:            /* The algorithm information (name, parameters, etc). */
068:            protected AlgorithmId algid;
069:
070:            /**
071:             * The key bytes, without the algorithm information.
072:             * @deprecated Use the BitArray form which does not require keys to
073:             * be byte aligned.
074:             * @see sun.security.x509.X509Key#setKey(BitArray)
075:             * @see sun.security.x509.X509Key#getKey()
076:             */
077:            protected byte[] key = null;
078:
079:            /*
080:             * The number of bits unused in the last byte of the key.
081:             * Added to keep the byte[] key form consistent with the BitArray
082:             * form. Can de deleted when byte[] key is deleted.
083:             */
084:            private int unusedBits = 0;
085:
086:            /* BitArray form of key */
087:            private BitArray bitStringKey = null;
088:
089:            /* The encoding for the key. */
090:            protected byte[] encodedKey;
091:
092:            /**
093:             * Default constructor.  The key constructed must have its key
094:             * and algorithm initialized before it may be used, for example
095:             * by using <code>decode</code>.
096:             */
097:            public X509Key() {
098:            }
099:
100:            /*
101:             * Build and initialize as a "default" key.  All X.509 key
102:             * data is stored and transmitted losslessly, but no knowledge
103:             * about this particular algorithm is available.
104:             */
105:            private X509Key(AlgorithmId algid, BitArray key)
106:                    throws InvalidKeyException {
107:                this .algid = algid;
108:                setKey(key);
109:                encode();
110:            }
111:
112:            /**
113:             * Sets the key in the BitArray form.
114:             */
115:            protected void setKey(BitArray key) {
116:                this .bitStringKey = (BitArray) key.clone();
117:
118:                /*
119:                 * Do this to keep the byte array form consistent with
120:                 * this. Can delete when byte[] key is deleted.
121:                 */
122:                this .key = key.toByteArray();
123:                int remaining = key.length() % 8;
124:                this .unusedBits = ((remaining == 0) ? 0 : 8 - remaining);
125:            }
126:
127:            /**
128:             * Gets the key. The key may or may not be byte aligned.
129:             * @return a BitArray containing the key.
130:             */
131:            protected BitArray getKey() {
132:                /*
133:                 * Do this for consistency in case a subclass
134:                 * modifies byte[] key directly. Remove when
135:                 * byte[] key is deleted.
136:                 * Note: the consistency checks fail when the subclass
137:                 * modifies a non byte-aligned key (into a byte-aligned key) 
138:                 * using the deprecated byte[] key field.
139:                 */
140:                this .bitStringKey = new BitArray(this .key.length * 8
141:                        - this .unusedBits, this .key);
142:
143:                return (BitArray) bitStringKey.clone();
144:            }
145:
146:            /**
147:             * Construct X.509 subject public key from a DER value.  If
148:             * the runtime environment is configured with a specific class for
149:             * this kind of key, a subclass is returned.  Otherwise, a generic
150:             * X509Key object is returned.
151:             * 
152:             * <P>This mechanism gurantees that keys (and algorithms) may be
153:             * freely manipulated and transferred, without risk of losing
154:             * information.  Also, when a key (or algorithm) needs some special
155:             * handling, that specific need can be accomodated.
156:             *
157:             * @param in the DER-encoded SubjectPublicKeyInfo value
158:             * @exception IOException on data format errors
159:             */
160:            public static PublicKey parse(DerValue in) throws IOException {
161:                AlgorithmId algorithm;
162:                PublicKey subjectKey;
163:
164:                if (in.tag != DerValue.tag_Sequence)
165:                    throw new IOException("corrupt subject key");
166:
167:                algorithm = AlgorithmId.parse(in.data.getDerValue());
168:                try {
169:                    subjectKey = buildX509Key(algorithm, in.data
170:                            .getUnalignedBitString());
171:
172:                } catch (InvalidKeyException e) {
173:                    throw new IOException("subject key, " + e.getMessage());
174:                }
175:
176:                if (in.data.available() != 0)
177:                    throw new IOException("excess subject key");
178:                return subjectKey;
179:            }
180:
181:            /**
182:             * Parse the key bits.  This may be redefined by subclasses to take
183:             * advantage of structure within the key.  For example, RSA public
184:             * keys encapsulate two unsigned integers (modulus and exponent) as
185:             * DER values within the <code>key</code> bits; Diffie-Hellman and
186:             * DSS/DSA keys encapsulate a single unsigned integer.
187:             *
188:             * <P>This function is called when creating X.509 SubjectPublicKeyInfo
189:             * values using the X509Key member functions, such as <code>parse</code>
190:             * and <code>decode</code>.
191:             *
192:             * @exception IOException on parsing errors.
193:             * @exception InvalidKeyException on invalid key encodings.
194:             */
195:            protected void parseKeyBits() throws IOException,
196:                    InvalidKeyException {
197:                encode();
198:            }
199:
200:            /*
201:             * Factory interface, building the kind of key associated with this
202:             * specific algorithm ID or else returning this generic base class.
203:             * See the description above.
204:             */
205:            static PublicKey buildX509Key(AlgorithmId algid, BitArray key)
206:                    throws IOException, InvalidKeyException {
207:                /*
208:                 * Use the algid and key parameters to produce the ASN.1 encoding
209:                 * of the key, which will then be used as the input to the
210:                 * key factory.
211:                 */
212:                DerOutputStream x509EncodedKeyStream = new DerOutputStream();
213:                encode(x509EncodedKeyStream, algid, key);
214:                X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(
215:                        x509EncodedKeyStream.toByteArray());
216:
217:                try {
218:                    // Instantiate the key factory of the appropriate algorithm
219:                    KeyFactory keyFac = KeyFactory.getInstance(algid.getName());
220:
221:                    // Generate the public key
222:                    return keyFac.generatePublic(x509KeySpec);
223:                } catch (NoSuchAlgorithmException e) {
224:                    // Return generic X509Key with opaque key data (see below)
225:                } catch (InvalidKeySpecException e) {
226:                    throw new InvalidKeyException(e.getMessage());
227:                }
228:
229:                /*
230:                 * Try again using JDK1.1-style for backwards compatibility.
231:                 */
232:                String classname = "";
233:                try {
234:                    Properties props;
235:                    String keytype;
236:                    Provider sunProvider;
237:
238:                    sunProvider = Security.getProvider("SUN");
239:                    if (sunProvider == null)
240:                        throw new InstantiationException();
241:                    classname = sunProvider.getProperty("PublicKey.X.509."
242:                            + algid.getName());
243:                    if (classname == null) {
244:                        throw new InstantiationException();
245:                    }
246:
247:                    Class keyClass = null;
248:                    try {
249:                        keyClass = Class.forName(classname);
250:                    } catch (ClassNotFoundException e) {
251:                        ClassLoader cl = ClassLoader.getSystemClassLoader();
252:                        if (cl != null) {
253:                            keyClass = cl.loadClass(classname);
254:                        }
255:                    }
256:
257:                    Object inst = null;
258:                    X509Key result;
259:
260:                    if (keyClass != null)
261:                        inst = keyClass.newInstance();
262:                    if (inst instanceof  X509Key) {
263:                        result = (X509Key) inst;
264:                        result.algid = algid;
265:                        result.setKey(key);
266:                        result.parseKeyBits();
267:                        return result;
268:                    }
269:                } catch (ClassNotFoundException e) {
270:                } catch (InstantiationException e) {
271:                } catch (IllegalAccessException e) {
272:                    // this should not happen.
273:                    throw new IOException(classname + " [internal error]");
274:                }
275:
276:                X509Key result = new X509Key(algid, key);
277:                return result;
278:            }
279:
280:            /**
281:             * Returns the algorithm to be used with this key.
282:             */
283:            public String getAlgorithm() {
284:                return algid.getName();
285:            }
286:
287:            /**
288:             * Returns the algorithm ID to be used with this key.
289:             */
290:            public AlgorithmId getAlgorithmId() {
291:                return algid;
292:            }
293:
294:            /**
295:             * Encode SubjectPublicKeyInfo sequence on the DER output stream.
296:             *
297:             * @exception IOException on encoding errors.
298:             */
299:            public final void encode(DerOutputStream out) throws IOException {
300:                encode(out, this .algid, getKey());
301:            }
302:
303:            /**
304:             * Returns the DER-encoded form of the key as a byte array.
305:             */
306:            public byte[] getEncoded() {
307:                try {
308:                    return (byte[]) getEncodedInternal().clone();
309:                } catch (InvalidKeyException e) {
310:                    //
311:                }
312:                return null;
313:            }
314:
315:            public byte[] getEncodedInternal() throws InvalidKeyException {
316:                byte[] encoded = encodedKey;
317:                if (encoded == null) {
318:                    try {
319:                        DerOutputStream out = new DerOutputStream();
320:                        encode(out);
321:                        encoded = out.toByteArray();
322:                    } catch (IOException e) {
323:                        throw new InvalidKeyException("IOException : "
324:                                + e.getMessage());
325:                    }
326:                    encodedKey = encoded;
327:                }
328:                return encoded;
329:            }
330:
331:            /**
332:             * Returns the format for this key: "X.509"
333:             */
334:            public String getFormat() {
335:                return "X.509";
336:            }
337:
338:            /**
339:             * Returns the DER-encoded form of the key as a byte array.
340:             *
341:             * @exception InvalidKeyException on encoding errors.
342:             */
343:            public byte[] encode() throws InvalidKeyException {
344:                return (byte[]) getEncodedInternal().clone();
345:            }
346:
347:            /*
348:             * Returns a printable representation of the key
349:             */
350:            public String toString() {
351:                HexDumpEncoder encoder = new HexDumpEncoder();
352:
353:                return "algorithm = " + algid.toString()
354:                        + ", unparsed keybits = \n" + encoder.encodeBuffer(key);
355:            }
356:
357:            /** 
358:             * Initialize an X509Key object from an input stream.  The data on that
359:             * input stream must be encoded using DER, obeying the X.509
360:             * <code>SubjectPublicKeyInfo</code> format.  That is, the data is a
361:             * sequence consisting of an algorithm ID and a bit string which holds
362:             * the key.  (That bit string is often used to encapsulate another DER
363:             * encoded sequence.)
364:             *
365:             * <P>Subclasses should not normally redefine this method; they should
366:             * instead provide a <code>parseKeyBits</code> method to parse any
367:             * fields inside the <code>key</code> member.
368:             *
369:             * <P>The exception to this rule is that since private keys need not
370:             * be encoded using the X.509 <code>SubjectPublicKeyInfo</code> format,
371:             * private keys may override this method, <code>encode</code>, and
372:             * of course <code>getFormat</code>.
373:             *
374:             * @param in an input stream with a DER-encoded X.509
375:             *		SubjectPublicKeyInfo value
376:             * @exception InvalidKeyException on parsing errors.
377:             */
378:            public void decode(InputStream in) throws InvalidKeyException {
379:                DerValue val;
380:
381:                try {
382:                    val = new DerValue(in);
383:                    if (val.tag != DerValue.tag_Sequence)
384:                        throw new InvalidKeyException("invalid key format");
385:
386:                    algid = AlgorithmId.parse(val.data.getDerValue());
387:                    setKey(val.data.getUnalignedBitString());
388:                    parseKeyBits();
389:                    if (val.data.available() != 0)
390:                        throw new InvalidKeyException("excess key data");
391:
392:                } catch (IOException e) {
393:                    // e.printStackTrace ();
394:                    throw new InvalidKeyException("IOException: "
395:                            + e.getMessage());
396:                }
397:            }
398:
399:            public void decode(byte[] encodedKey) throws InvalidKeyException {
400:                decode(new ByteArrayInputStream(encodedKey));
401:            }
402:
403:            /**
404:             * Serialization write ... X.509 keys serialize as
405:             * themselves, and they're parsed when they get read back.
406:             */
407:            private synchronized void writeObject(
408:                    java.io.ObjectOutputStream stream) throws IOException {
409:                // no need to clone, because getEncoded() already returns a clone
410:                stream.write(getEncoded());
411:            }
412:
413:            /**
414:             * Serialization read ... X.509 keys serialize as
415:             * themselves, and they're parsed when they get read back.
416:             */
417:            private synchronized void readObject(ObjectInputStream stream)
418:                    throws IOException {
419:
420:                try {
421:                    decode(stream);
422:
423:                } catch (InvalidKeyException e) {
424:                    e.printStackTrace();
425:                    throw new IOException("deserialized key is invalid: "
426:                            + e.getMessage());
427:                }
428:            }
429:
430:            public boolean equals(Object obj) {
431:                if (this  == obj) {
432:                    return true;
433:                }
434:                if (obj instanceof  Key == false) {
435:                    return false;
436:                }
437:                try {
438:                    byte[] this Encoded = this .getEncodedInternal();
439:                    byte[] otherEncoded;
440:                    if (obj instanceof  X509Key) {
441:                        otherEncoded = ((X509Key) obj).getEncodedInternal();
442:                    } else {
443:                        otherEncoded = ((Key) obj).getEncoded();
444:                    }
445:                    return Arrays.equals(this Encoded, otherEncoded);
446:                } catch (InvalidKeyException e) {
447:                    return false;
448:                }
449:            }
450:
451:            /**
452:             * Calculates a hash code value for the object. Objects
453:             * which are equal will also have the same hashcode.
454:             */
455:            public int hashCode() {
456:                try {
457:                    byte[] b1 = getEncodedInternal();
458:                    int r = b1.length;
459:                    for (int i = 0; i < b1.length; i++) {
460:                        r += (b1[i] & 0xff) * 37;
461:                    }
462:                    return r;
463:                } catch (InvalidKeyException e) {
464:                    // should not happen
465:                    return 0;
466:                }
467:            }
468:
469:            /*
470:             * Produce SubjectPublicKey encoding from algorithm id and key material.
471:             */
472:            static void encode(DerOutputStream out, AlgorithmId algid,
473:                    BitArray key) throws IOException {
474:                DerOutputStream tmp = new DerOutputStream();
475:                algid.encode(tmp);
476:                tmp.putUnalignedBitString(key);
477:                out.write(DerValue.tag_Sequence, tmp);
478:            }
479:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.