Source Code Cross Referenced for CertChainVerifier.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » tools » keytool » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » org package » org.apache.harmony.tools.keytool 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         * http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014:         * License for the specific language governing permissions and limitations under
015:         * the License.
016:         */
017:
018:        package org.apache.harmony.tools.keytool;
019:
020:        import java.io.FileNotFoundException;
021:        import java.io.IOException;
022:        import java.security.InvalidAlgorithmParameterException;
023:        import java.security.KeyStore;
024:        import java.security.KeyStoreException;
025:        import java.security.NoSuchAlgorithmException;
026:        import java.security.NoSuchProviderException;
027:        import java.security.PublicKey;
028:        import java.security.SignatureException;
029:        import java.security.cert.CertPathBuilder;
030:        import java.security.cert.CertPathBuilderException;
031:        import java.security.cert.CertPathBuilderResult;
032:        import java.security.cert.CertStore;
033:        import java.security.cert.CertStoreException;
034:        import java.security.cert.CertificateEncodingException;
035:        import java.security.cert.CertificateException;
036:        import java.security.cert.CollectionCertStoreParameters;
037:        import java.security.cert.PKIXBuilderParameters;
038:        import java.security.cert.TrustAnchor;
039:        import java.security.cert.X509CertSelector;
040:        import java.security.cert.X509Certificate;
041:        import java.util.ArrayList;
042:        import java.util.Arrays;
043:        import java.util.Collection;
044:        import java.util.Enumeration;
045:        import java.util.HashSet;
046:        import java.util.Iterator;
047:        import java.util.List;
048:        import java.util.NoSuchElementException;
049:        import java.util.Set;
050:
051:        import javax.security.auth.x500.X500Principal;
052:
053:        /**
054:         * A class for checking X.509 certificates and building and verifying X.509
055:         * certificate chains.
056:         */
057:        public class CertChainVerifier {
058:            private final static String strFailed = "Failed to build a certificate chain from reply.\n";
059:
060:            /**
061:             * A cerificate chain is built by looking up the certificate of the issuer
062:             * of the current certificate. If a sertificate is self-signed it is assumed
063:             * to be the root CA. After that the certificates are searched in the lists
064:             * of revoked certificates. Certificate signatures are checked and
065:             * certificate path is built in the same way as in import operation. If an
066:             * error occurs the flow is not stopped but an attempt to continue is made.
067:             * The results of the verification are printed to stdout.
068:             * 
069:             * @param param
070:             * @throws NoSuchAlgorithmException
071:             * @throws NoSuchProviderException
072:             * @throws FileNotFoundException
073:             * @throws CertificateException
074:             * @throws IOException
075:             * @throws KeytoolException
076:             * @throws KeyStoreException 
077:             */
078:            static void verifyChain(KeytoolParameters param)
079:                    throws NoSuchAlgorithmException, NoSuchProviderException,
080:                    FileNotFoundException, CertificateException, IOException,
081:                    KeytoolException, KeyStoreException {
082:
083:                try {
084:                    if (param.getCrlFile() != null) {
085:                        CRLManager.checkRevoked(param);
086:                    } else {
087:                        System.out
088:                                .println("Certificates revocation status is not checked, "
089:                                        + "CRL file name is not supplied.");
090:                    }
091:                } catch (Exception e) {
092:                    System.out.println(e);
093:                    System.out.println("Failed to check revocation status.");
094:                }
095:
096:                String provider = param.getProvider();
097:                String certProvider = (param.getCertProvider() != null) ? param
098:                        .getCertProvider() : provider;
099:                String sigProvider = (param.getSigProvider() != null) ? param
100:                        .getSigProvider() : provider;
101:                String mdProvider = (param.getMdProvider() != null) ? param
102:                        .getMdProvider() : provider;
103:
104:                // Don't catch exceptions here, because if exception is
105:                // thrown here, there is no need to proceed.
106:                Collection<X509Certificate> certs = CertReader.readCerts(param
107:                        .getFileName(), false, certProvider);
108:                X509Certificate[] ordered = orderChain(certs);
109:
110:                try {
111:                    for (int i = 0; i < ordered.length - 1; i++) {
112:                        checkSignature(ordered[i], ordered[i + 1]
113:                                .getPublicKey(), sigProvider, mdProvider);
114:                    }
115:                    // check the signature of the last element of the ordered chain
116:                    boolean lastSignChecked = findIssuerAndCheckSignature(param
117:                            .getKeyStore(), ordered[ordered.length - 1],
118:                            sigProvider, mdProvider);
119:                    // if haven't found issuer's certificate in main keystore
120:                    if (!lastSignChecked) {
121:                        if (param.isTrustCACerts()) {
122:                            // make the search and check again
123:                            lastSignChecked = findIssuerAndCheckSignature(param
124:                                    .getCacerts(), ordered[ordered.length - 1],
125:                                    sigProvider, mdProvider);
126:                        }
127:
128:                        if (!lastSignChecked) {
129:                            System.out
130:                                    .println("Failed to find the issuer's certificate.");
131:                            System.out
132:                                    .println("Failed to check the signature of certificate:");
133:                            KeyStoreCertPrinter.printX509CertDetailed(
134:                                    ordered[ordered.length - 1], mdProvider);
135:                        }
136:                    }
137:                } catch (Exception e) {
138:                    System.out.println(e);
139:                    System.out.println("Signature check failed.");
140:                }
141:
142:                try {
143:                    buildCertPath(param, ordered[0]);
144:
145:                    // won't come here if exception is thrown
146:                    System.out
147:                            .println("Certificate path is built successfully.");
148:                } catch (Exception e) {
149:                    // Exception's own message contains strFailed string,
150:                    // but its cause can be more informative here.
151:                    System.out.println(e.getCause());
152:                    System.out.println("Failed to build a certificate path.");
153:                }
154:                System.out.println("Verification complete.");
155:            }
156:
157:            // Checks the signature, prints the result. Returns true if
158:            // signature verification process succeeds (no exceptions or
159:            // SignatureException thrown)
160:            private static boolean checkSignature(X509Certificate cert,
161:                    PublicKey pubKey, String sigProvider, String mdProvider)
162:                    throws CertificateEncodingException,
163:                    NoSuchAlgorithmException, NoSuchProviderException {
164:                try {
165:                    if (sigProvider == null) {
166:                        cert.verify(pubKey);
167:                    } else {
168:                        cert.verify(pubKey, sigProvider);
169:                    }
170:                } catch (SignatureException e) {
171:                    System.out
172:                            .println("The signature is incorrect for certificate: ");
173:                    KeyStoreCertPrinter.printX509CertDetailed(cert, mdProvider);
174:                } catch (Exception e) {
175:                    System.out.println(e);
176:                    System.out
177:                            .println("Signature verification failed for certificate: ");
178:                    KeyStoreCertPrinter.printX509CertDetailed(cert, mdProvider);
179:                    return false;
180:                }
181:                return true;
182:            }
183:
184:            // Searches for cert issuer's certificate in keyStore and checks if
185:            // cert was signed using the private key corresponding to public key
186:            // wrapped into the found certificate.
187:            private static boolean findIssuerAndCheckSignature(
188:                    KeyStore keyStore, X509Certificate cert,
189:                    String sigProvider, String mdProvider)
190:                    throws KeyStoreException, CertificateEncodingException,
191:                    NoSuchAlgorithmException, NoSuchProviderException {
192:
193:                Enumeration keyStoreAliases = keyStore.aliases();
194:                while (keyStoreAliases.hasMoreElements()) {
195:                    // get a certificate from keyStore
196:                    X509Certificate nextKScert = (X509Certificate) keyStore
197:                            .getCertificate((String) keyStoreAliases
198:                                    .nextElement());
199:                    if (nextKScert == null) {
200:                        continue;
201:                    }
202:                    if (Arrays.equals(cert.getIssuerX500Principal()
203:                            .getEncoded(), nextKScert.getSubjectX500Principal()
204:                            .getEncoded())) {
205:                        checkSignature(cert, keyStore.getCertificate(
206:                                (String) keyStoreAliases.nextElement())
207:                                .getPublicKey(), sigProvider, mdProvider);
208:                        return true;
209:                    }
210:                }
211:                return false;
212:            }
213:
214:            /**
215:             * Builds a certificate chain from the given X509Certificate newCert to a
216:             * self-signed root CA whose certificate is contained in the keystore or
217:             * cacerts file (if "-trustcacerts" option is specified).
218:             * 
219:             * @param param -
220:             *            specifies the keystore, provider name and other options (such
221:             *            as "-trustcacerts").
222:             * @param newCert -
223:             *            certificate to start the chain
224:             * @return the chain as an array of X509Certificate-s. If the chain cannot
225:             *         be built for some reason an exception is thrown.
226:             * @throws KeyStoreException
227:             * @throws FileNotFoundException
228:             * @throws NoSuchAlgorithmException
229:             * @throws CertificateException
230:             * @throws IOException
231:             * @throws KeytoolException
232:             * @throws NoSuchProviderException
233:             * @throws CertPathBuilderException
234:             */
235:            static X509Certificate[] buildFullCertPath(KeytoolParameters param,
236:                    X509Certificate newCert) throws KeyStoreException,
237:                    FileNotFoundException, NoSuchAlgorithmException,
238:                    CertificateException, IOException, KeytoolException,
239:                    CertPathBuilderException, NoSuchProviderException {
240:
241:                X509CertSelector selector = new X509CertSelector();
242:                selector.setCertificate(newCert);
243:
244:                Collection[] trustedSeparated = separateTrusted(param);
245:                Set selfSignedTAs = (Set) trustedSeparated[0];
246:                Collection trustedCerts = trustedSeparated[1];
247:                Collection selfSignedTAsCerts = trustedSeparated[2];
248:
249:                String certProvider = (param.getCertProvider() != null) ? param
250:                        .getCertProvider() : param.getProvider();
251:
252:                CertPathBuilderResult bldResult = buildCertPath(certProvider,
253:                        newCert, selfSignedTAs, trustedCerts);
254:
255:                // The validation of the certificate path.
256:                // According to black-box testing, RI keytool doesn't perform
257:                // the certificate path validation procedure. Therefore this
258:                // implementation also doesn't validate the certificate chain
259:                // The path validation procedure can be done in future as an
260:                // extension of the current functionality.
261:
262:                // The imported certificate should be included in the chain;
263:                // The root CA is not included in it.
264:                X509Certificate[] newChainNoCA = (X509Certificate[]) bldResult
265:                        .getCertPath().getCertificates().toArray(
266:                                new X509Certificate[0]);
267:
268:                // get the subject of the root CA which will be the last element of the
269:                // chain
270:                X500Principal caSubject = newChainNoCA[newChainNoCA.length - 1]
271:                        .getIssuerX500Principal();
272:
273:                // set the search parameter for the root CA
274:                selector.setCertificate(null);
275:                selector.setSubject(caSubject);
276:
277:                // add all root CAs to the CertStore to search through them
278:                CollectionCertStoreParameters rootCAs = new CollectionCertStoreParameters(
279:                        selfSignedTAsCerts);
280:                CertStore rootCAsCertStore;
281:                try {
282:                    rootCAsCertStore = CertStore.getInstance("Collection",
283:                            rootCAs);
284:                } catch (Exception e) {
285:                    throw new KeytoolException(strFailed, e);
286:                }
287:
288:                // find certificate to add to the end of the certificate chain
289:                X509Certificate rootCA;
290:                try {
291:                    rootCA = (X509Certificate) rootCAsCertStore
292:                            .getCertificates(selector).iterator().next();
293:                } catch (CertStoreException e) {
294:                    throw new KeytoolException(strFailed, e);
295:                }
296:                // create a new array of certificates with the root CA in it.
297:                X509Certificate[] newChain = new X509Certificate[newChainNoCA.length + 1];
298:                System.arraycopy(newChainNoCA, 0, newChain, 0,
299:                        newChainNoCA.length);
300:                newChain[newChain.length - 1] = rootCA;
301:
302:                return newChain;
303:            }
304:
305:            /**
306:             * Build a certificate chain up to the trust anchor, based on trusted
307:             * certificates contained in the keystore and possibly cacerts file (if
308:             * param.isTrustCACerts() returns true).
309:             * 
310:             * @param param
311:             * @param newCert
312:             * @return
313:             * @throws NoSuchAlgorithmException
314:             * @throws CertificateException
315:             * @throws KeyStoreException
316:             * @throws CertPathBuilderException
317:             * @throws IOException
318:             * @throws KeytoolException
319:             * @throws NoSuchProviderException
320:             */
321:            static CertPathBuilderResult buildCertPath(KeytoolParameters param,
322:                    X509Certificate newCert) throws NoSuchAlgorithmException,
323:                    CertificateException, KeyStoreException,
324:                    CertPathBuilderException, IOException, KeytoolException,
325:                    NoSuchProviderException {
326:                Collection[] trustedSeparated = separateTrusted(param);
327:                Set selfSignedTAs = (Set) trustedSeparated[0];
328:                Collection trustedCerts = trustedSeparated[1];
329:
330:                String certProvider = (param.getCertProvider() != null) ? param
331:                        .getCertProvider() : param.getProvider();
332:
333:                return buildCertPath(certProvider, newCert, selfSignedTAs,
334:                        trustedCerts);
335:            }
336:
337:            // Build a certificate chain up to the self-signed trust anchor, based on
338:            // trusted certificates given.
339:            // 
340:            // @param certProvider
341:            // @param newCert
342:            //            is a certificate to build chain for.
343:            // @param selfSignedTAs
344:            //            are used as trust anchors.
345:            // @param trustedCerts
346:            //            elements of trustedCerts are used as chain links It can be
347:            //            null if no intermediate certificates allowed.
348:            private static CertPathBuilderResult buildCertPath(
349:                    String certProvider, X509Certificate newCert,
350:                    Set selfSignedTAs, Collection trustedCerts)
351:                    throws NoSuchAlgorithmException, CertificateException,
352:                    IOException, KeyStoreException, CertPathBuilderException,
353:                    KeytoolException, NoSuchProviderException {
354:
355:                X509CertSelector selector = new X509CertSelector();
356:                selector.setCertificate(newCert);
357:
358:                String strPKIX = "PKIX";
359:                String strNoSelfSigned = "Possibly, keystore doesn't "
360:                        + "contain any self-signed (root CA) trusted certificates. ";
361:
362:                // this parameter will be used to generate the certificate chain
363:                PKIXBuilderParameters builderParam = null;
364:                try {
365:                    // set the search parameters with selector
366:                    // and TrustAnchors with selfSignedTAs
367:                    builderParam = new PKIXBuilderParameters(selfSignedTAs,
368:                            selector);
369:                } catch (InvalidAlgorithmParameterException e) {
370:                    throw new KeytoolException(strFailed + strNoSelfSigned, e);
371:                }
372:
373:                if (trustedCerts != null) {
374:                    CollectionCertStoreParameters trustedCertsCCSParams = new CollectionCertStoreParameters(
375:                            trustedCerts);
376:                    CertStore trustedCertStore;
377:                    try {
378:                        trustedCertStore = CertStore.getInstance("Collection",
379:                                trustedCertsCCSParams);
380:                    } catch (Exception e) {
381:                        throw new KeytoolException(strFailed, e);
382:                    }
383:
384:                    // add certificates to use as chain links
385:                    builderParam.addCertStore(trustedCertStore);
386:                }
387:
388:                // disable the revocation checking
389:                builderParam.setRevocationEnabled(false);
390:
391:                CertPathBuilder cpBuilder;
392:                try {
393:                    if (certProvider == null) {
394:                        cpBuilder = CertPathBuilder.getInstance(strPKIX);
395:                    } else {
396:                        cpBuilder = CertPathBuilder.getInstance(strPKIX,
397:                                certProvider);
398:                    }
399:                } catch (NoSuchAlgorithmException e) {
400:                    throw new NoSuchAlgorithmException("The algorithm "
401:                            + strPKIX + " is not available.", e);
402:                } catch (NoSuchProviderException e) {
403:                    throw (NoSuchProviderException) new NoSuchProviderException(
404:                            "The certProvider " + certProvider
405:                                    + " is not found in the environment.")
406:                            .initCause(e);
407:                }
408:
409:                CertPathBuilderResult bldResult = null;
410:                try {
411:                    // the actual building of the certificate chain is done here
412:                    bldResult = cpBuilder.build(builderParam);
413:                } catch (CertPathBuilderException e) {
414:                    throw new CertPathBuilderException(strFailed, e);
415:                } catch (InvalidAlgorithmParameterException e) {
416:                    throw new KeytoolException(strFailed + strNoSelfSigned, e);
417:                }
418:
419:                return bldResult;
420:            }
421:
422:            // Separates the trusted certificates from keystore (and cacerts file if
423:            // "-trustcacerts" option is specified) into self-signed certificate
424:            // authority certificates and non-self-signed certificates.
425:            // @return - Returns an array of Collection-s.
426:            // The first element of the array is Set<TrustAnchors> - self-signed CAs.
427:            // The second - ArrayList of non-self-signed trusted certificates.
428:            // The third - ArrayList of self-signed certificates which correspond to
429:            // TrustAnchors contained in the first element of the array.
430:            private static Collection[] separateTrusted(KeytoolParameters param)
431:                    throws KeyStoreException, FileNotFoundException,
432:                    IOException, NoSuchAlgorithmException,
433:                    CertificateException, KeytoolException,
434:                    NoSuchProviderException {
435:                // Are there any trusted certificates in the keyStore?
436:                boolean trustedExistInKS = false;
437:                // Is "-trustcacerts" option specified?
438:                boolean trustCaCerts = param.isTrustCACerts();
439:                String strNoTrusted = "Possibly, keystore doesn't "
440:                        + "contain any trusted certificates. ";
441:
442:                // This one is temporary. Used just to get trusted certificates
443:                // from keyStore.
444:                PKIXBuilderParameters keyStoreBuilderParam = null;
445:                X509CertSelector selector = new X509CertSelector();
446:
447:                // After getting the trusted certificates, they will be sorted into
448:                // self-signed (they are considered to be CAs) and interim trusted
449:                // certs.
450:
451:                // self-signed trust anchors. The CertPath is ok if it finishes
452:                // on such trust anchor.
453:                Set selfSignedTAs = null;
454:                // certificates of selfSignedTAs
455:                Collection selfSignedTAsCerts = null;
456:                // trusted certificates which can be the chain links of the CertPath
457:                Collection trustedCerts = null;
458:                try {
459:                    keyStoreBuilderParam = new PKIXBuilderParameters(param
460:                            .getKeyStore(), selector);
461:
462:                    // won't come here if exception is thrown
463:                    trustedExistInKS = true;
464:                } catch (InvalidAlgorithmParameterException e) {
465:                    // if "-trustcacerts" option is NOT specified
466:                    if (!trustCaCerts) {
467:                        throw new KeytoolException(strFailed + strNoTrusted);
468:                    }
469:                }
470:
471:                // if there are trusted certificates in the keyStore
472:                if (keyStoreBuilderParam != null) {
473:                    // trustAnchorsSet is a set of trusted certificates
474:                    // contained in keyStore
475:                    Set trustAnchorsSet = keyStoreBuilderParam
476:                            .getTrustAnchors();
477:                    int halfSize = trustAnchorsSet.size() / 2;
478:                    selfSignedTAs = new HashSet(halfSize);
479:                    selfSignedTAsCerts = new ArrayList(halfSize);
480:                    trustedCerts = new ArrayList(halfSize);
481:
482:                    Iterator trustAnchorsIter = trustAnchorsSet.iterator();
483:                    while (trustAnchorsIter.hasNext()) {
484:                        TrustAnchor ta = (TrustAnchor) trustAnchorsIter.next();
485:                        X509Certificate trCert = ta.getTrustedCert();
486:                        // if the trusted certificate is self-signed,
487:                        // add it to the selfSignedTAs.
488:                        if (Arrays.equals(trCert.getSubjectX500Principal()
489:                                .getEncoded(), trCert.getIssuerX500Principal()
490:                                .getEncoded())) {
491:                            selfSignedTAs.add(ta);
492:                            selfSignedTAsCerts.add(trCert);
493:                        } else {// otherwise just add it to the list of
494:                            // trusted certs
495:                            trustedCerts.add(trCert);
496:                        }
497:                    }
498:                }
499:
500:                // if "-trustcacerts" is specified, add CAs from cacerts
501:                if (trustCaCerts) {
502:                    KeyStore cacertsFile = null;
503:                    try {
504:                        cacertsFile = param.getCacerts();
505:                    } catch (Exception e) {
506:                        if (trustedExistInKS) {
507:                            // if there are trusted certificates in keyStore,
508:                            // just print the notification
509:                            System.err.println(e.getMessage());
510:                        } else {// otherwise quit
511:                            throw new KeytoolException(strFailed, e);
512:                        }
513:                    }
514:
515:                    // if cacerts loaded
516:                    if (cacertsFile != null) {
517:                        PKIXBuilderParameters cacertsBuilderParam = null;
518:                        try {
519:                            cacertsBuilderParam = new PKIXBuilderParameters(
520:                                    cacertsFile, selector);
521:                        } catch (InvalidAlgorithmParameterException e) {
522:                            if (!trustedExistInKS) {
523:                                throw new KeytoolException(strFailed
524:                                        + strNoTrusted);
525:                            } else {
526:                                // if there are trusted certificates in keyStore,
527:                                // just return what have now
528:                                return new Collection[] { selfSignedTAs,
529:                                        trustedCerts, selfSignedTAsCerts };
530:                            }
531:                        }
532:
533:                        Set<TrustAnchor> cacertsCAs = cacertsBuilderParam
534:                                .getTrustAnchors();
535:
536:                        // if there are no trusted certificates in the
537:                        // keyStore
538:                        if (!trustedExistInKS) {
539:                            Set trustAnchorsSet = cacertsBuilderParam
540:                                    .getTrustAnchors();
541:                            int size = trustAnchorsSet.size();
542:                            // usually only self-signed CAs are in the
543:                            // cacerts file, so selfSignedTAs is of the
544:                            // same size as trustAnchorsSet.
545:                            selfSignedTAs = new HashSet(size);
546:                            selfSignedTAsCerts = new HashSet(size);
547:                            trustedCerts = new ArrayList();
548:                        }
549:
550:                        Iterator cacertsCAsIter = cacertsCAs.iterator();
551:                        while (cacertsCAsIter.hasNext()) {
552:                            TrustAnchor ta = (TrustAnchor) cacertsCAsIter
553:                                    .next();
554:                            X509Certificate trCert = ta.getTrustedCert();
555:                            // if the trusted certificate is self-signed,
556:                            // add it to the selfSignedTAs.
557:                            if (Arrays.equals(trCert.getSubjectX500Principal()
558:                                    .getEncoded(), trCert
559:                                    .getIssuerX500Principal().getEncoded())) {
560:                                selfSignedTAs.add(ta);
561:                                selfSignedTAsCerts.add(trCert);
562:                            } else {// otherwise just add it to the list of
563:                                // trusted certs
564:                                trustedCerts.add(trCert);
565:                            }
566:                        }
567:                    }// if (cacertsFile != null)...
568:                }// if (trustCacerts)...
569:                return new Collection[] { selfSignedTAs, trustedCerts,
570:                        selfSignedTAsCerts };
571:            }
572:
573:            /**
574:             * Orders a collection of certificates into a certificate chain beginning
575:             * with the certificate which has public key equal to aliasPubKey.
576:             * 
577:             * @throws KeytoolException
578:             */
579:            static X509Certificate[] orderChain(
580:                    Collection<X509Certificate> certs, PublicKey aliasPubKey)
581:                    throws KeytoolException {
582:
583:                String strOrderFailed = "Failed to order the certificate chain.";
584:
585:                // add certificates to the certstore to ease the search
586:                CollectionCertStoreParameters chainCCSParams = new CollectionCertStoreParameters(
587:                        certs);
588:                CertStore certStore;
589:                try {
590:                    certStore = CertStore.getInstance("Collection",
591:                            chainCCSParams);
592:                } catch (Exception e) {
593:                    throw new KeytoolException(strOrderFailed, e);
594:                }
595:
596:                // set up selector to search the certificates
597:                X509CertSelector selector = new X509CertSelector();
598:                // try to find the first certificate in the chain
599:                selector.setSubjectPublicKey(aliasPubKey);
600:
601:                // current certificate
602:                X509Certificate current = null;
603:                try {
604:                    current = (X509Certificate) certStore.getCertificates(
605:                            selector).iterator().next();
606:                } catch (CertStoreException e) {
607:                    // do nothing
608:                } catch (NoSuchElementException e) {
609:                    // do nothing
610:                }
611:
612:                if (current == null) {
613:                    throw new KeytoolException(
614:                            "Failed to find the requested public key "
615:                                    + "in certificate reply.");
616:                }
617:                // number of certificates in collection
618:                int colSize = certs.size();
619:                // new chain to return
620:                X509Certificate[] ordered = new X509Certificate[colSize];
621:                ordered[0] = current;
622:                selector.setSubjectPublicKey((PublicKey) null);
623:
624:                // counter of ordered certificates
625:                // it will be incremented later
626:                int orderedCnt = 0;
627:
628:                if (!Arrays.equals(current.getSubjectX500Principal()
629:                        .getEncoded(), current.getIssuerX500Principal()
630:                        .getEncoded())) {
631:                    // orderedCnt = 1, because the first certificate is already in
632:                    // the resulting array
633:                    for (orderedCnt = 1; orderedCnt < colSize; orderedCnt++) {
634:                        // set new filter
635:                        selector.setSubject(current.getIssuerX500Principal());
636:                        try {
637:                            // get issuer's certificate
638:                            current = (X509Certificate) certStore
639:                                    .getCertificates(selector).iterator()
640:                                    .next();
641:                        } catch (CertStoreException e) {
642:                            throw new KeytoolException(strOrderFailed, e);
643:                        } catch (NoSuchElementException e) {
644:                            break;
645:                        }
646:
647:                        if (Arrays.equals(current.getSubjectX500Principal()
648:                                .getEncoded(), current.getIssuerX500Principal()
649:                                .getEncoded())) {
650:                            // if self-signed, save it and quit. It is the last.
651:                            ordered[orderedCnt] = current;
652:                            break;
653:                        } else {
654:                            // add current certificate to the chain and continue
655:                            ordered[orderedCnt] = current;
656:                        }
657:                    }
658:                }
659:
660:                // If the certificate collection contains certificates which
661:                // are not a part of the chain.
662:                // ++orderedCnt is used because 'break's don't let the
663:                // variable be incremented when it should be.
664:                if (++orderedCnt < colSize) {
665:                    X509Certificate[] orderedShort = new X509Certificate[orderedCnt];
666:                    System.arraycopy(ordered, 0, orderedShort, 0, orderedCnt);
667:                    return orderedShort;
668:                }
669:
670:                return ordered;
671:            }
672:
673:            // orders a chain without a starting element given
674:            static X509Certificate[] orderChain(
675:                    Collection<X509Certificate> certs) throws KeytoolException {
676:
677:                int certsLen = certs.size();
678:                int startPos = -1;
679:
680:                List<X509Certificate> certsList = new ArrayList<X509Certificate>(
681:                        certs);
682:
683:                // searching for the first element of the chain
684:                for (int i = 0; i < certsLen; i++) {
685:                    X509Certificate curCert = certsList.get(i);
686:                    for (int j = 0; j < certsLen; j++) {
687:                        if (j != i) {
688:                            // if the subject is the issuer of another cert, it is not
689:                            // the first in the chain.
690:                            if (Arrays.equals(curCert.getSubjectX500Principal()
691:                                    .getEncoded(), certsList.get(j)
692:                                    .getIssuerX500Principal().getEncoded())) {
693:                                break;
694:                            }
695:                        }
696:                        // If the certificate's subject is not found to be an issuer to
697:                        // any other cert in this chain, then it is the first element.
698:                        if (j == certsLen - 1) {
699:                            startPos = i;
700:                            break;
701:                        }
702:                    }
703:                    // don't search any more, if the first element is found.
704:                    if (startPos > -1) {
705:                        break;
706:                    }
707:                }
708:
709:                return orderChain(certsList, certsList.get(startPos)
710:                        .getPublicKey());
711:            }
712:
713:            /**
714:             * Checks if the X509Certificate cert is contained as a trusted certificate
715:             * entry in keystore and possibly cacerts file (if "-trustcacerts" option is
716:             * specified).
717:             * 
718:             * @param param
719:             * @param cert
720:             * @return true if the certificate is trusted, false - otherwise.
721:             * @throws FileNotFoundException
722:             * @throws NoSuchAlgorithmException
723:             * @throws CertificateException
724:             * @throws IOException
725:             * @throws KeyStoreException
726:             * @throws NoSuchProviderException
727:             */
728:            static boolean isTrusted(KeytoolParameters param,
729:                    X509Certificate cert) throws FileNotFoundException,
730:                    NoSuchAlgorithmException, CertificateException,
731:                    IOException, KeyStoreException, NoSuchProviderException {
732:                // check the main keyStore
733:                KeyStore keyStore = param.getKeyStore();
734:                String alias = keyStore.getCertificateAlias(cert);
735:                if (alias != null) {
736:                    if (keyStore.isCertificateEntry(alias)) {
737:                        return true;
738:                    }
739:                }
740:
741:                if (!param.isTrustCACerts()) {
742:                    return false;
743:                } else {// check cacerts file
744:                    KeyStore cacerts = param.getCacerts();
745:                    alias = cacerts.getCertificateAlias(cert);
746:                    if (alias != null) {
747:                        if (cacerts.isCertificateEntry(alias)) {
748:                            return true;
749:                        }
750:                    }
751:                    return false;
752:                }
753:            }
754:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.