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


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