Source Code Cross Referenced for KeyStoreCallbackHandler.java in  » Web-Services » spring-ws-1.0.0 » org » springframework » ws » soap » security » xwss » callback » 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 » Web Services » spring ws 1.0.0 » org.springframework.ws.soap.security.xwss.callback 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2006 the original author or authors.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.springframework.ws.soap.security.xwss.callback;
018:
019:        import java.io.File;
020:        import java.io.IOException;
021:        import java.math.BigInteger;
022:        import java.security.GeneralSecurityException;
023:        import java.security.InvalidAlgorithmParameterException;
024:        import java.security.KeyStore;
025:        import java.security.PrivateKey;
026:        import java.security.PublicKey;
027:        import java.security.cert.CertPathBuilder;
028:        import java.security.cert.CertPathBuilderException;
029:        import java.security.cert.Certificate;
030:        import java.security.cert.CertificateExpiredException;
031:        import java.security.cert.CertificateNotYetValidException;
032:        import java.security.cert.PKIXBuilderParameters;
033:        import java.security.cert.X509CertSelector;
034:        import java.security.cert.X509Certificate;
035:        import java.util.Arrays;
036:        import java.util.Enumeration;
037:        import javax.crypto.SecretKey;
038:
039:        import com.sun.xml.wss.impl.callback.CertificateValidationCallback;
040:        import com.sun.xml.wss.impl.callback.DecryptionKeyCallback;
041:        import com.sun.xml.wss.impl.callback.EncryptionKeyCallback;
042:        import com.sun.xml.wss.impl.callback.SignatureKeyCallback;
043:        import com.sun.xml.wss.impl.callback.SignatureVerificationKeyCallback;
044:        import org.apache.xml.security.utils.RFC2253Parser;
045:        import org.springframework.beans.factory.InitializingBean;
046:        import org.springframework.core.io.FileSystemResource;
047:        import org.springframework.core.io.Resource;
048:        import org.springframework.util.StringUtils;
049:        import org.springframework.ws.soap.security.support.KeyStoreFactoryBean;
050:
051:        /**
052:         * Callback handler that uses Java Security <code>KeyStore</code>s to handle cryptographic callbacks. Allows for
053:         * specific key stores to be set for various cryptographic operations.
054:         * <p/>
055:         * This handler requires one or more key stores to be set. You can configure them in your application context by using a
056:         * <code>KeyStoreFactoryBean</code>. The exact stores to be set depends on the cryptographic operations that are to be
057:         * performed by this handler. The table underneath show the key store to be used for each operation: <table border="1">
058:         * <tr> <td><strong>Cryptographic operation</strong></td> <td><strong>Key store used</strong></td> </tr> <tr>
059:         * <td>Certificate validation</td> <td>first <code>keyStore</code>, then <code>trustStore</code></td> </tr> <tr>
060:         * <td>Decryption based on private key</td> <td><code>keyStore</code></td> </tr> <tr> <td>Decryption based on symmetric
061:         * key</td> <td><code>symmetricStore</code></td> </tr> <tr> <td>Encryption based on certificate</td>
062:         * <td><code>trustStore</code></td> </tr> <tr> <td>Encryption based on symmetric key</td>
063:         * <td><code>symmetricStore</code></td> </tr> <tr> <td>Signing</td> <td><code>keyStore</code></td> </tr> <tr>
064:         * <td>Signature verification</td> <td><code>trustStore</code></td> </tr> </table>
065:         * <p/>
066:         * <h3>Default key stores</h3> If the <code>symmetricStore</code> is not set, it will default to the
067:         * <code>keyStore</code>. If the key or trust store is not set, this handler will use the standard Java mechanism to
068:         * load or create it. See {@link #loadDefaultKeyStore()} and {@link #loadDefaultTrustStore()}.
069:         * <p/>
070:         * <h3>Examples</h3> For instance, if you want to use the <code>KeyStoreCallbackHandler</code> to validate incoming
071:         * certificates or signatures, you would use a trust store, like so:
072:         * <pre>
073:         * &lt;bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler"&gt;
074:         *     &lt;property name="trustStore" ref="trustStore"/&gt;
075:         * &lt;/bean&gt;
076:         * <p/>
077:         * &lt;bean id="trustStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean"&gt;
078:         *     &lt;property name="location" value="classpath:truststore.jks"/&gt;
079:         *     &lt;property name="password" value="changeit"/&gt;
080:         * &lt;/bean&gt;
081:         * </pre>
082:         * If you want to use it to decrypt incoming certificates or sign outgoing messages, you would use a key store, like
083:         * so:
084:         * <pre>
085:         * &lt;bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler"&gt;
086:         *     &lt;property name="keyStore" ref="keyStore"/&gt;
087:         *     &lt;property name="privateKeyPassword" value="changeit"/&gt;
088:         * &lt;/bean&gt;
089:         * <p/>
090:         * &lt;bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean"&gt;
091:         *     &lt;property name="location" value="classpath:keystore.jks"/&gt;
092:         *     &lt;property name="password" value="changeit"/&gt;
093:         * &lt;/bean&gt;
094:         * </pre>
095:         * <p/>
096:         * <h3>Handled callbacks</h3> This class handles <code>CertificateValidationCallback</code>s,
097:         * <code>DecryptionKeyCallback</code>s, <code>EncryptionKeyCallback</code>s, <code>SignatureKeyCallback</code>s, and
098:         * <code>SignatureVerificationKeyCallback</code>s. It throws an <code>UnsupportedCallbackException</code> for others.
099:         *
100:         * @author Arjen Poutsma
101:         * @see KeyStore
102:         * @see org.springframework.ws.soap.security.support.KeyStoreFactoryBean
103:         * @see CertificateValidationCallback
104:         * @see DecryptionKeyCallback
105:         * @see EncryptionKeyCallback
106:         * @see SignatureKeyCallback
107:         * @see SignatureVerificationKeyCallback
108:         * @see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html#X509TrustManager">The
109:         *      standard Java trust store mechanism</a>
110:         */
111:        public class KeyStoreCallbackHandler extends
112:                CryptographyCallbackHandler implements  InitializingBean {
113:
114:            private static final String X_509_CERTIFICATE_TYPE = "X.509";
115:
116:            private static final String SUBJECT_KEY_IDENTIFIER_OID = "2.5.29.14";
117:
118:            private KeyStore keyStore;
119:
120:            private KeyStore symmetricStore;
121:
122:            private KeyStore trustStore;
123:
124:            private String defaultAlias;
125:
126:            private char[] privateKeyPassword;
127:
128:            private char[] symmetricKeyPassword;
129:
130:            private static X509Certificate getCertificate(String alias,
131:                    KeyStore store) throws IOException {
132:                try {
133:                    return (X509Certificate) store.getCertificate(alias);
134:                } catch (GeneralSecurityException e) {
135:                    throw new IOException(e.getMessage());
136:                }
137:            }
138:
139:            private static X509Certificate getCertificate(PublicKey pk,
140:                    KeyStore store) throws IOException {
141:                try {
142:                    Enumeration aliases = store.aliases();
143:                    while (aliases.hasMoreElements()) {
144:                        String alias = (String) aliases.nextElement();
145:                        Certificate cert = store.getCertificate(alias);
146:                        if (cert == null
147:                                || !X_509_CERTIFICATE_TYPE.equals(cert
148:                                        .getType())) {
149:                            continue;
150:                        }
151:                        X509Certificate x509Cert = (X509Certificate) cert;
152:                        if (x509Cert.getPublicKey().equals(pk)) {
153:                            return x509Cert;
154:                        }
155:                    }
156:                } catch (GeneralSecurityException e) {
157:                    throw new IOException(e.getMessage());
158:                }
159:                return null;
160:            }
161:
162:            /** Sets the key store alias for the default certificate and private key. */
163:            public void setDefaultAlias(String defaultAlias) {
164:                this .defaultAlias = defaultAlias;
165:            }
166:
167:            /**
168:             * Sets the default key store. This property is required for decription based on private keys, and signing. If this
169:             * property is not set, a default key store is loaded.
170:             *
171:             * @see org.springframework.ws.soap.security.support.KeyStoreFactoryBean
172:             * @see #loadDefaultTrustStore()
173:             */
174:            public void setKeyStore(KeyStore keyStore) {
175:                this .keyStore = keyStore;
176:            }
177:
178:            /**
179:             * Sets the password used to retrieve private keys from the keystore. This property is required for decription based
180:             * on private keys, and signing.
181:             */
182:            public void setPrivateKeyPassword(String privateKeyPassword) {
183:                if (privateKeyPassword != null) {
184:                    this .privateKeyPassword = privateKeyPassword.toCharArray();
185:                }
186:            }
187:
188:            /**
189:             * Sets the password used to retrieve keys from the symmetric keystore. If this property is not set, it default to
190:             * the private key password.
191:             *
192:             * @see #setPrivateKeyPassword(String)
193:             */
194:            public void setSymmetricKeyPassword(String symmetricKeyPassword) {
195:                if (symmetricKeyPassword != null) {
196:                    this .symmetricKeyPassword = symmetricKeyPassword
197:                            .toCharArray();
198:                }
199:            }
200:
201:            /**
202:             * Sets the key store used for encryption and decryption using symmetric keys. If this property is not set, it
203:             * defaults to the <code>keyStore</code> property.
204:             *
205:             * @see org.springframework.ws.soap.security.support.KeyStoreFactoryBean
206:             * @see #setKeyStore(java.security.KeyStore)
207:             */
208:            public void setSymmetricStore(KeyStore symmetricStore) {
209:                this .symmetricStore = symmetricStore;
210:            }
211:
212:            /**
213:             * Sets the key store used for signature verifications and encryptions. If this property is not set, a default key
214:             * store will be loaded.
215:             *
216:             * @see org.springframework.ws.soap.security.support.KeyStoreFactoryBean
217:             * @see #loadDefaultTrustStore()
218:             */
219:            public void setTrustStore(KeyStore trustStore) {
220:                this .trustStore = trustStore;
221:            }
222:
223:            public void afterPropertiesSet() throws Exception {
224:                if (keyStore == null) {
225:                    loadDefaultKeyStore();
226:                }
227:                if (trustStore == null) {
228:                    loadDefaultTrustStore();
229:                }
230:                if (symmetricStore == null) {
231:                    symmetricStore = keyStore;
232:                }
233:                if (symmetricKeyPassword == null) {
234:                    symmetricKeyPassword = privateKeyPassword;
235:                }
236:            }
237:
238:            protected final void handleAliasPrivKeyCertRequest(
239:                    SignatureKeyCallback callback,
240:                    SignatureKeyCallback.AliasPrivKeyCertRequest request)
241:                    throws IOException {
242:                PrivateKey privateKey = getPrivateKey(request.getAlias());
243:                X509Certificate certificate = getCertificate(request.getAlias());
244:                request.setPrivateKey(privateKey);
245:                request.setX509Certificate(certificate);
246:            }
247:
248:            protected final void handleAliasSymmetricKeyRequest(
249:                    DecryptionKeyCallback callback,
250:                    DecryptionKeyCallback.AliasSymmetricKeyRequest request)
251:                    throws IOException {
252:                SecretKey secretKey = getSymmetricKey(request.getAlias());
253:                request.setSymmetricKey(secretKey);
254:            }
255:
256:            //
257:            // Encryption
258:            //
259:
260:            protected final void handleAliasSymmetricKeyRequest(
261:                    EncryptionKeyCallback callback,
262:                    EncryptionKeyCallback.AliasSymmetricKeyRequest request)
263:                    throws IOException {
264:                SecretKey secretKey = getSymmetricKey(request.getAlias());
265:                request.setSymmetricKey(secretKey);
266:            }
267:
268:            protected final void handleAliasX509CertificateRequest(
269:                    EncryptionKeyCallback callback,
270:                    EncryptionKeyCallback.AliasX509CertificateRequest request)
271:                    throws IOException {
272:                X509Certificate certificate = getCertificateFromTrustStore(request
273:                        .getAlias());
274:                request.setX509Certificate(certificate);
275:            }
276:
277:            //
278:            // Certificate validation
279:            //
280:
281:            protected final void handleCertificateValidationCallback(
282:                    CertificateValidationCallback callback) {
283:                callback.setValidator(new KeyStoreCertificateValidator());
284:            }
285:
286:            //
287:            // Signing
288:            //
289:
290:            protected final void handleDefaultPrivKeyCertRequest(
291:                    SignatureKeyCallback callback,
292:                    SignatureKeyCallback.DefaultPrivKeyCertRequest request)
293:                    throws IOException {
294:                PrivateKey privateKey = getPrivateKey(defaultAlias);
295:                X509Certificate certificate = getCertificate(defaultAlias);
296:                request.setPrivateKey(privateKey);
297:                request.setX509Certificate(certificate);
298:            }
299:
300:            protected final void handleDefaultX509CertificateRequest(
301:                    EncryptionKeyCallback callback,
302:                    EncryptionKeyCallback.DefaultX509CertificateRequest request)
303:                    throws IOException {
304:                X509Certificate certificate = getCertificateFromTrustStore(defaultAlias);
305:                request.setX509Certificate(certificate);
306:            }
307:
308:            protected final void handlePublicKeyBasedPrivKeyCertRequest(
309:                    SignatureKeyCallback callback,
310:                    SignatureKeyCallback.PublicKeyBasedPrivKeyCertRequest request)
311:                    throws IOException {
312:                PrivateKey privateKey = getPrivateKey(request.getPublicKey());
313:                X509Certificate certificate = getCertificate(request
314:                        .getPublicKey());
315:                request.setPrivateKey(privateKey);
316:                request.setX509Certificate(certificate);
317:            }
318:
319:            //
320:            // Decryption
321:            //
322:            protected final void handlePublicKeyBasedPrivKeyRequest(
323:                    DecryptionKeyCallback callback,
324:                    DecryptionKeyCallback.PublicKeyBasedPrivKeyRequest request)
325:                    throws IOException {
326:                PrivateKey key = getPrivateKey(request.getPublicKey());
327:                request.setPrivateKey(key);
328:            }
329:
330:            protected final void handlePublicKeyBasedRequest(
331:                    EncryptionKeyCallback callback,
332:                    EncryptionKeyCallback.PublicKeyBasedRequest request)
333:                    throws IOException {
334:                X509Certificate certificate = getCertificateFromTrustStore(request
335:                        .getPublicKey());
336:                request.setX509Certificate(certificate);
337:            }
338:
339:            protected final void handlePublicKeyBasedRequest(
340:                    SignatureVerificationKeyCallback callback,
341:                    SignatureVerificationKeyCallback.PublicKeyBasedRequest request)
342:                    throws IOException {
343:                X509Certificate certificate = getCertificateFromTrustStore(request
344:                        .getPublicKey());
345:                request.setX509Certificate(certificate);
346:            }
347:
348:            protected final void handleX509CertificateBasedRequest(
349:                    DecryptionKeyCallback callback,
350:                    DecryptionKeyCallback.X509CertificateBasedRequest request)
351:                    throws IOException {
352:                PrivateKey privKey = getPrivateKey(request.getX509Certificate());
353:                request.setPrivateKey(privKey);
354:            }
355:
356:            protected final void handleX509IssuerSerialBasedRequest(
357:                    DecryptionKeyCallback callback,
358:                    DecryptionKeyCallback.X509IssuerSerialBasedRequest request)
359:                    throws IOException {
360:                PrivateKey key = getPrivateKey(request.getIssuerName(), request
361:                        .getSerialNumber());
362:                request.setPrivateKey(key);
363:            }
364:
365:            protected final void handleX509IssuerSerialBasedRequest(
366:                    SignatureVerificationKeyCallback callback,
367:                    SignatureVerificationKeyCallback.X509IssuerSerialBasedRequest request)
368:                    throws IOException {
369:                X509Certificate certificate = getCertificateFromTrustStore(
370:                        request.getIssuerName(), request.getSerialNumber());
371:                request.setX509Certificate(certificate);
372:            }
373:
374:            protected final void handleX509SubjectKeyIdentifierBasedRequest(
375:                    DecryptionKeyCallback callback,
376:                    DecryptionKeyCallback.X509SubjectKeyIdentifierBasedRequest request)
377:                    throws IOException {
378:                PrivateKey key = getPrivateKey(request
379:                        .getSubjectKeyIdentifier());
380:                request.setPrivateKey(key);
381:            }
382:
383:            //
384:            // Signature verification
385:            //
386:
387:            protected final void handleX509SubjectKeyIdentifierBasedRequest(
388:                    SignatureVerificationKeyCallback callback,
389:                    SignatureVerificationKeyCallback.X509SubjectKeyIdentifierBasedRequest request)
390:                    throws IOException {
391:                X509Certificate certificate = getCertificateFromTrustStore(request
392:                        .getSubjectKeyIdentifier());
393:                request.setX509Certificate(certificate);
394:            }
395:
396:            // Certificate methods
397:
398:            protected X509Certificate getCertificate(String alias)
399:                    throws IOException {
400:                return getCertificate(alias, keyStore);
401:            }
402:
403:            protected X509Certificate getCertificate(PublicKey pk)
404:                    throws IOException {
405:                return getCertificate(pk, keyStore);
406:            }
407:
408:            protected X509Certificate getCertificateFromTrustStore(String alias)
409:                    throws IOException {
410:                return getCertificate(alias, trustStore);
411:            }
412:
413:            protected X509Certificate getCertificateFromTrustStore(
414:                    byte[] subjectKeyIdentifier) throws IOException {
415:                try {
416:                    Enumeration aliases = trustStore.aliases();
417:                    while (aliases.hasMoreElements()) {
418:                        String alias = (String) aliases.nextElement();
419:                        Certificate cert = trustStore.getCertificate(alias);
420:                        if (cert == null
421:                                || !X_509_CERTIFICATE_TYPE.equals(cert
422:                                        .getType())) {
423:                            continue;
424:                        }
425:                        X509Certificate x509Cert = (X509Certificate) cert;
426:                        byte[] keyId = getSubjectKeyIdentifier(x509Cert);
427:                        if (keyId == null) {
428:                            // Cert does not contain a key identifier
429:                            continue;
430:                        }
431:                        if (Arrays.equals(subjectKeyIdentifier, keyId)) {
432:                            return x509Cert;
433:                        }
434:                    }
435:                } catch (GeneralSecurityException e) {
436:                    throw new IOException(e.getMessage());
437:                }
438:                return null;
439:            }
440:
441:            protected X509Certificate getCertificateFromTrustStore(PublicKey pk)
442:                    throws IOException {
443:                return getCertificate(pk, trustStore);
444:            }
445:
446:            protected X509Certificate getCertificateFromTrustStore(
447:                    String issuerName, BigInteger serialNumber)
448:                    throws IOException {
449:                try {
450:                    Enumeration aliases = trustStore.aliases();
451:                    while (aliases.hasMoreElements()) {
452:                        String alias = (String) aliases.nextElement();
453:                        Certificate cert = trustStore.getCertificate(alias);
454:                        if (cert == null
455:                                || !X_509_CERTIFICATE_TYPE.equals(cert
456:                                        .getType())) {
457:                            continue;
458:                        }
459:                        X509Certificate x509Cert = (X509Certificate) cert;
460:                        String this IssuerName = RFC2253Parser
461:                                .normalize(x509Cert.getIssuerDN().getName());
462:                        BigInteger this SerialNumber = x509Cert
463:                                .getSerialNumber();
464:                        if (this IssuerName.equals(issuerName)
465:                                && this SerialNumber.equals(serialNumber)) {
466:                            return x509Cert;
467:                        }
468:                    }
469:                } catch (GeneralSecurityException e) {
470:                    throw new IOException(e.getMessage());
471:                }
472:                return null;
473:            }
474:
475:            // Private Key methods
476:
477:            protected PrivateKey getPrivateKey(String alias) throws IOException {
478:                try {
479:                    return (PrivateKey) keyStore.getKey(alias,
480:                            privateKeyPassword);
481:                } catch (GeneralSecurityException e) {
482:                    throw new IOException(e.getMessage());
483:                }
484:            }
485:
486:            protected PrivateKey getPrivateKey(PublicKey publicKey)
487:                    throws IOException {
488:                try {
489:                    Enumeration aliases = keyStore.aliases();
490:                    while (aliases.hasMoreElements()) {
491:                        String alias = (String) aliases.nextElement();
492:                        if (keyStore.isKeyEntry(alias)) {
493:                            // Just returning the first one here
494:                            return (PrivateKey) keyStore.getKey(alias,
495:                                    privateKeyPassword);
496:                        }
497:                    }
498:                } catch (GeneralSecurityException e) {
499:                    throw new IOException(e.getMessage());
500:                }
501:                return null;
502:            }
503:
504:            protected PrivateKey getPrivateKey(X509Certificate certificate)
505:                    throws IOException {
506:                try {
507:                    Enumeration aliases = keyStore.aliases();
508:                    while (aliases.hasMoreElements()) {
509:                        String alias = (String) aliases.nextElement();
510:                        if (!keyStore.isKeyEntry(alias)) {
511:                            continue;
512:                        }
513:                        Certificate cert = keyStore.getCertificate(alias);
514:                        if (cert != null && cert.equals(certificate)) {
515:                            return (PrivateKey) keyStore.getKey(alias,
516:                                    privateKeyPassword);
517:                        }
518:                    }
519:                } catch (GeneralSecurityException e) {
520:                    throw new IOException(e.getMessage());
521:                }
522:                return null;
523:            }
524:
525:            protected PrivateKey getPrivateKey(byte[] keyIdentifier)
526:                    throws IOException {
527:                try {
528:                    Enumeration aliases = keyStore.aliases();
529:                    while (aliases.hasMoreElements()) {
530:                        String alias = (String) aliases.nextElement();
531:                        if (!keyStore.isKeyEntry(alias)) {
532:                            continue;
533:                        }
534:                        Certificate cert = keyStore.getCertificate(alias);
535:                        if (cert == null || !"X.509".equals(cert.getType())) {
536:                            continue;
537:                        }
538:                        X509Certificate x509Cert = (X509Certificate) cert;
539:                        byte[] keyId = getSubjectKeyIdentifier(x509Cert);
540:                        if (keyId == null) {
541:                            // Cert does not contain a key identifier
542:                            continue;
543:                        }
544:                        if (Arrays.equals(keyIdentifier, keyId)) {
545:                            return (PrivateKey) keyStore.getKey(alias,
546:                                    privateKeyPassword);
547:                        }
548:                    }
549:                } catch (GeneralSecurityException e) {
550:                    throw new IOException(e.getMessage());
551:                }
552:                return null;
553:            }
554:
555:            protected PrivateKey getPrivateKey(String issuerName,
556:                    BigInteger serialNumber) throws IOException {
557:                try {
558:                    Enumeration aliases = keyStore.aliases();
559:                    while (aliases.hasMoreElements()) {
560:                        String alias = (String) aliases.nextElement();
561:                        if (!keyStore.isKeyEntry(alias)) {
562:                            continue;
563:                        }
564:                        Certificate cert = keyStore.getCertificate(alias);
565:                        if (cert == null || !"X.509".equals(cert.getType())) {
566:                            continue;
567:                        }
568:                        X509Certificate x509Cert = (X509Certificate) cert;
569:                        String this IssuerName = RFC2253Parser
570:                                .normalize(x509Cert.getIssuerDN().getName());
571:                        BigInteger this SerialNumber = x509Cert
572:                                .getSerialNumber();
573:                        if (this IssuerName.equals(issuerName)
574:                                && this SerialNumber.equals(serialNumber)) {
575:                            return (PrivateKey) keyStore.getKey(alias,
576:                                    privateKeyPassword);
577:                        }
578:                    }
579:                } catch (GeneralSecurityException e) {
580:                    throw new IOException(e.getMessage());
581:                }
582:                return null;
583:            }
584:
585:            // Utility methods
586:
587:            protected final byte[] getSubjectKeyIdentifier(X509Certificate cert) {
588:                byte[] subjectKeyIdentifier = cert
589:                        .getExtensionValue(SUBJECT_KEY_IDENTIFIER_OID);
590:                if (subjectKeyIdentifier == null) {
591:                    return null;
592:                }
593:                byte[] dest = new byte[subjectKeyIdentifier.length - 4];
594:                System.arraycopy(subjectKeyIdentifier, 4, dest, 0,
595:                        subjectKeyIdentifier.length - 4);
596:                return dest;
597:            }
598:
599:            //
600:            // Symmetric key methods
601:            //
602:
603:            protected SecretKey getSymmetricKey(String alias)
604:                    throws IOException {
605:                try {
606:                    return (SecretKey) symmetricStore.getKey(alias,
607:                            symmetricKeyPassword);
608:                } catch (GeneralSecurityException e) {
609:                    throw new IOException(e.getMessage());
610:                }
611:            }
612:
613:            /**
614:             * Loads the key store indicated by system properties. This method tries to load a key store by consulting the
615:             * following system properties:<code>javax.net.ssl.keyStore</code>, <code>javax.net.ssl.keyStorePassword</code>, and
616:             * <code>javax.net.ssl.keyStoreType</code>.
617:             * <p/>
618:             * If these properties specify a file with an appropriate password, the factory uses this file for the key store. If
619:             * that file does not exist, then a default, empty keystore is created.
620:             * <p/>
621:             * This behavior corresponds to the standard J2SDK behavior for SSL key stores.
622:             *
623:             * @see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html#X509KeyManager">The
624:             *      standard J2SDK SSL key store mechanism</a>
625:             */
626:            protected void loadDefaultKeyStore() {
627:                Resource location = null;
628:                String type = null;
629:                String password = null;
630:                String locationProperty = System
631:                        .getProperty("javax.net.ssl.keyStore");
632:                if (StringUtils.hasLength(locationProperty)) {
633:                    File f = new File(locationProperty);
634:                    if (f.exists() && f.isFile() && f.canRead()) {
635:                        location = new FileSystemResource(f);
636:                    }
637:                    String passwordProperty = System
638:                            .getProperty("javax.net.ssl.keyStorePassword");
639:                    if (StringUtils.hasLength(passwordProperty)) {
640:                        password = passwordProperty;
641:                    }
642:                    type = System.getProperty("javax.net.ssl.trustStore");
643:                }
644:                // use the factory bean here, easier to setup
645:                KeyStoreFactoryBean factoryBean = new KeyStoreFactoryBean();
646:                factoryBean.setLocation(location);
647:                factoryBean.setPassword(password);
648:                factoryBean.setType(type);
649:                try {
650:                    factoryBean.afterPropertiesSet();
651:                    this .trustStore = (KeyStore) factoryBean.getObject();
652:                    if (logger.isDebugEnabled()) {
653:                        logger.debug("Loaded default key store");
654:                    }
655:                } catch (Exception ex) {
656:                    logger.warn("Could not open default key store", ex);
657:                }
658:            }
659:
660:            /**
661:             * Loads a default trust store. This method uses the following algorithm: <ol> <li> If the system property
662:             * <code>javax.net.ssl.trustStore</code> is defined, its value is loaded. If the
663:             * <code>javax.net.ssl.trustStorePassword</code> system property is also defined, its value is used as a password.
664:             * If the <code>javax.net.ssl.trustStoreType</code> system property is defined, its value is used as a key store
665:             * type.
666:             * <p/>
667:             * If <code>javax.net.ssl.trustStore</code> is defined but the specified file does not exist, then a default, empty
668:             * trust store is created. </li> <li> If the <code>javax.net.ssl.trustStore</code> system property was not
669:             * specified, but if the file <code>$JAVA_HOME/lib/security/jssecacerts</code> exists, that file is used. </li>
670:             * Otherwise, <li>If the file <code>$JAVA_HOME/lib/security/cacerts</code> exists, that file is used. </ol>
671:             * <p/>
672:             * This behavior corresponds to the standard J2SDK behavior for SSL trust stores.
673:             *
674:             * @see <a href="http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html#X509TrustManager">The
675:             *      standard J2SDK SSL trust store mechanism</a>
676:             */
677:            protected void loadDefaultTrustStore() {
678:                Resource location = null;
679:                String type = null;
680:                String password = null;
681:                String locationProperty = System
682:                        .getProperty("javax.net.ssl.trustStore");
683:                if (StringUtils.hasLength(locationProperty)) {
684:                    File f = new File(locationProperty);
685:                    if (f.exists() && f.isFile() && f.canRead()) {
686:                        location = new FileSystemResource(f);
687:                    }
688:                    String passwordProperty = System
689:                            .getProperty("javax.net.ssl.trustStorePassword");
690:                    if (StringUtils.hasLength(passwordProperty)) {
691:                        password = passwordProperty;
692:                    }
693:                    type = System.getProperty("javax.net.ssl.trustStoreType");
694:                } else {
695:                    String javaHome = System.getProperty("java.home");
696:                    location = new FileSystemResource(javaHome
697:                            + "/lib/security/jssecacerts");
698:                    if (!location.exists()) {
699:                        location = new FileSystemResource(javaHome
700:                                + "/lib/security/cacerts");
701:                    }
702:                }
703:                // use the factory bean here, easier to setup
704:                KeyStoreFactoryBean factoryBean = new KeyStoreFactoryBean();
705:                factoryBean.setLocation(location);
706:                factoryBean.setPassword(password);
707:                factoryBean.setType(type);
708:                try {
709:                    factoryBean.afterPropertiesSet();
710:                    this .trustStore = (KeyStore) factoryBean.getObject();
711:                    if (logger.isDebugEnabled()) {
712:                        logger.debug("Loaded default trust store");
713:                    }
714:                } catch (Exception ex) {
715:                    logger.warn("Could not open default trust store", ex);
716:                }
717:            }
718:
719:            //
720:            // Inner classes
721:            //
722:
723:            private class KeyStoreCertificateValidator implements 
724:                    CertificateValidationCallback.CertificateValidator {
725:
726:                public boolean validate(X509Certificate certificate)
727:                        throws CertificateValidationCallback.CertificateValidationException {
728:                    if (isOwnedCert(certificate)) {
729:                        if (logger.isDebugEnabled()) {
730:                            logger.debug("Certificate with DN ["
731:                                    + certificate.getSubjectX500Principal()
732:                                            .getName()
733:                                    + "] is in private keystore");
734:                        }
735:                        return true;
736:                    } else if (trustStore == null) {
737:                        return false;
738:                    }
739:
740:                    try {
741:                        certificate.checkValidity();
742:                    } catch (CertificateExpiredException e) {
743:                        if (logger.isDebugEnabled()) {
744:                            logger.debug("Certificate with DN ["
745:                                    + certificate.getSubjectX500Principal()
746:                                            .getName() + "] has expired");
747:                        }
748:                        return false;
749:                    } catch (CertificateNotYetValidException e) {
750:                        if (logger.isDebugEnabled()) {
751:                            logger.debug("Certificate with DN ["
752:                                    + certificate.getSubjectX500Principal()
753:                                            .getName() + "] is not yet valid");
754:                        }
755:                        return false;
756:                    }
757:
758:                    X509CertSelector certSelector = new X509CertSelector();
759:                    certSelector.setCertificate(certificate);
760:
761:                    PKIXBuilderParameters parameters;
762:                    CertPathBuilder builder;
763:                    try {
764:                        parameters = new PKIXBuilderParameters(trustStore,
765:                                certSelector);
766:                        parameters.setRevocationEnabled(false);
767:                        builder = CertPathBuilder.getInstance("PKIX");
768:                    } catch (GeneralSecurityException ex) {
769:                        throw new CertificateValidationCallback.CertificateValidationException(
770:                                "Could not create PKIX CertPathBuilder", ex);
771:                    }
772:
773:                    try {
774:                        builder.build(parameters);
775:                    } catch (CertPathBuilderException e) {
776:                        if (logger.isDebugEnabled()) {
777:                            logger
778:                                    .debug("Certification path of certificate with DN ["
779:                                            + certificate
780:                                                    .getSubjectX500Principal()
781:                                                    .getName()
782:                                            + "] could not be validated");
783:                        }
784:                        return false;
785:                    } catch (InvalidAlgorithmParameterException e) {
786:                        if (logger.isDebugEnabled()) {
787:                            logger.debug("Algorithm of certificate with DN ["
788:                                    + certificate.getSubjectX500Principal()
789:                                            .getName()
790:                                    + "] could not be validated");
791:                        }
792:                        return false;
793:                    }
794:                    if (logger.isDebugEnabled()) {
795:                        logger.debug("Certificate with DN ["
796:                                + certificate.getSubjectX500Principal()
797:                                        .getName() + "] validated");
798:                    }
799:                    return true;
800:                }
801:
802:                private boolean isOwnedCert(X509Certificate cert)
803:                        throws CertificateValidationCallback.CertificateValidationException {
804:                    if (keyStore == null) {
805:                        return false;
806:                    }
807:                    try {
808:                        Enumeration aliases = keyStore.aliases();
809:                        while (aliases.hasMoreElements()) {
810:                            String alias = (String) aliases.nextElement();
811:                            if (keyStore.isKeyEntry(alias)) {
812:                                X509Certificate x509Cert = (X509Certificate) keyStore
813:                                        .getCertificate(alias);
814:                                if (x509Cert != null) {
815:                                    if (x509Cert.equals(cert)) {
816:                                        return true;
817:                                    }
818:                                }
819:                            }
820:                        }
821:                        return false;
822:                    } catch (GeneralSecurityException e) {
823:                        throw new CertificateValidationCallback.CertificateValidationException(
824:                                "Could not determine whether certificate is contained in main key store",
825:                                e);
826:                    }
827:                }
828:            }
829:        }
w__w___w__.j__av__a_2___s___.__com__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.