Source Code Cross Referenced for ArgumentsParser.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.File;
021:        import java.io.IOException;
022:        import java.io.InputStreamReader;
023:        import java.security.KeyStore;
024:        import java.security.KeyStoreException;
025:        import java.security.NoSuchAlgorithmException;
026:        import java.security.NoSuchProviderException;
027:        import java.security.UnrecoverableKeyException;
028:        import java.security.cert.CertificateException;
029:
030:        /**
031:         * The class to interact with the user - parse the program arguments, ask for
032:         * confirmations, and necessary parameters which haven't been set in the command
033:         * line.
034:         */
035:
036:        class ArgumentsParser {
037:            // used to get additional data prompted
038:            static InputStreamReader in = new InputStreamReader(System.in);
039:
040:            // buffer for the data read
041:            static char[] readData = new char[256];
042:
043:            // number of symbols read
044:            static int charsRead;
045:
046:            // minimum password length permitted
047:            static int minPwdLength = 6;
048:
049:            // maximum number of attempts to set the password
050:            static int maxNrOfAttempts = 3;
051:
052:            // length of the "\r\n" which is added to the end of the line,
053:            // when ENTER is pressed.
054:            private static int newLineLength = 2;
055:
056:            // options names to compare to //
057:            // commands
058:            final static String sGenkey = "-genkey";
059:
060:            final static String sSelfcert = "-selfcert";
061:
062:            final static String sImport = "-import";
063:
064:            final static String sExport = "-export";
065:
066:            final static String sStorepasswd = "-storepasswd";
067:
068:            final static String sKeypasswd = "-keypasswd";
069:
070:            final static String sCertreq = "-certreq";
071:
072:            final static String sCheck = "-checkcrl";
073:
074:            final static String sConvert = "-convert";
075:
076:            final static String sVerify = "-verify";
077:
078:            final static String sPrintcert = "-printcert";
079:
080:            final static String sKeyclone = "-keyclone";
081:
082:            final static String sDelete = "-delete";
083:
084:            final static String sList = "-list";
085:
086:            final static String sHelp = "-help";
087:
088:            // additional options
089:            final static String sKeystore = "-keystore";
090:
091:            final static String sStoretype = "-storetype";
092:
093:            final static String sProvider = "-provider";
094:
095:            final static String sCertProvider = "-certprovider";
096:
097:            final static String sKeyProvider = "-keyprovider";
098:
099:            final static String sMdProvider = "-mdprovider";
100:
101:            final static String sSigProvider = "-sigprovider";
102:
103:            final static String sKsProvider = "-ksprovider";
104:
105:            final static String sConvKsProvider = "-convprovider";
106:
107:            final static String sStorepass = "-storepass";
108:
109:            final static String sAlias = "-alias";
110:
111:            final static String sKeyalg = "-keyalg";
112:
113:            final static String sKeysize = "-keysize";
114:
115:            final static String sSigalg = "-sigalg";
116:
117:            final static String sDname = "-dname";
118:
119:            final static String sKeypass = "-keypass";
120:
121:            final static String sValidity = "-validity";
122:
123:            final static String sV = "-v";
124:
125:            final static String sJ = "-J";
126:
127:            final static String sFile = "-file";
128:
129:            final static String sNoprompt = "-noprompt";
130:
131:            final static String sTrustcacerts = "-trustcacerts";
132:
133:            final static String sRfc = "-rfc";
134:
135:            final static String sNew = "-new";
136:
137:            final static String sIssuerAlias = "-issuer";
138:
139:            final static String sIssuerPass = "-issuerpass";
140:
141:            final static String sSecretkey = "-secretkey";
142:
143:            final static String sX509Version = "-x509version";
144:
145:            final static String sCertSerial = "-certserial";
146:
147:            final static String sDestAlias = "-dest";
148:
149:            final static String sCRLfile = "-crlfile";
150:
151:            final static String sCA = "-ca";
152:
153:            final static String sConvStorePath = "-convkeystore";
154:
155:            final static String sConvStorePass = "-convstorepass";
156:
157:            final static String sConvStoreType = "-convtype";
158:
159:            final static String sConvKeyEntries = "-convkeys";
160:
161:            final static String sCAcertsPath = "-cacerts";
162:
163:            final static String sCAcertsPass = "-cacertspass";
164:
165:            /**
166:             * The method finds known options in args which is usually taken from
167:             * command line and sets the corresponding fields of the returned
168:             * KeytoolParameters object to given values.
169:             * 
170:             * @param args -
171:             *            String array to parse.
172:             * @return null if args is null or zero-sized, one of the elements of args
173:             *         is null or empty, an unknown option is found or an expected
174:             *         option value is not given or not of an expected type.
175:             * @throws IOException
176:             * @throws NumberFormatException
177:             * @throws KeytoolException
178:             */
179:
180:            static KeytoolParameters parseArgs(String[] args)
181:                    throws NumberFormatException, KeytoolException, IOException {
182:                if (args == null || args.length == 0) {
183:                    return null;
184:                }
185:                KeytoolParameters param = new KeytoolParameters();
186:
187:                // look for known options and get their values.
188:                try {
189:                    for (int i = 0; i < args.length; i++) {
190:
191:                        // commands
192:                        if (args[i].compareToIgnoreCase(sGenkey) == 0) {
193:                            param.setCommand(Command.GENKEY);
194:                            continue;
195:                        }
196:                        if (args[i].compareToIgnoreCase(sSelfcert) == 0) {
197:                            param.setCommand(Command.SELFCERT);
198:                            continue;
199:                        }
200:                        if (args[i].compareToIgnoreCase(sImport) == 0) {
201:                            param.setCommand(Command.IMPORT);
202:                            continue;
203:                        }
204:                        if (args[i].compareToIgnoreCase(sExport) == 0) {
205:                            param.setCommand(Command.EXPORT);
206:                            continue;
207:                        }
208:                        if (args[i].compareToIgnoreCase(sStorepasswd) == 0) {
209:                            param.setCommand(Command.STOREPASSWD);
210:                            continue;
211:                        }
212:                        if (args[i].compareToIgnoreCase(sKeypasswd) == 0) {
213:                            param.setCommand(Command.KEYPASSWD);
214:                            continue;
215:                        }
216:                        if (args[i].compareToIgnoreCase(sCertreq) == 0) {
217:                            param.setCommand(Command.CERTREQ);
218:                            continue;
219:                        }
220:                        if (args[i].compareToIgnoreCase(sCheck) == 0) {
221:                            param.setCommand(Command.CHECK);
222:                            continue;
223:                        }
224:                        if (args[i].compareToIgnoreCase(sConvert) == 0) {
225:                            param.setCommand(Command.CONVERT);
226:                            continue;
227:                        }
228:                        if (args[i].compareToIgnoreCase(sVerify) == 0) {
229:                            param.setCommand(Command.VERIFY);
230:                            continue;
231:                        }
232:                        if (args[i].compareToIgnoreCase(sPrintcert) == 0) {
233:                            param.setCommand(Command.PRINTCERT);
234:                            continue;
235:                        }
236:                        if (args[i].compareToIgnoreCase(sKeyclone) == 0) {
237:                            param.setCommand(Command.KEYCLONE);
238:                            continue;
239:                        }
240:                        if (args[i].compareToIgnoreCase(sDelete) == 0) {
241:                            param.setCommand(Command.DELETE);
242:                            continue;
243:                        }
244:                        if (args[i].compareToIgnoreCase(sList) == 0) {
245:                            param.setCommand(Command.LIST);
246:                            continue;
247:                        }
248:                        if (args[i].compareToIgnoreCase(sHelp) == 0) {
249:                            param.setCommand(Command.HELP);
250:                            if (args.length == i + 2) {
251:                                param.setHelpTopic(args[++i]);
252:                            }
253:                            continue;
254:                        }
255:
256:                        // additional options
257:                        if (args[i].compareToIgnoreCase(sKeystore) == 0) {
258:                            param.setStorePath(args[++i]);
259:                            continue;
260:                        }
261:                        if (args[i].compareToIgnoreCase(sStoretype) == 0) {
262:                            param.setStoreType(args[++i]);
263:                            continue;
264:                        }
265:                        if (args[i].compareToIgnoreCase(sProvider) == 0) {
266:                            param.setProvider(args[++i]);
267:                            continue;
268:                        }
269:                        if (args[i].compareToIgnoreCase(sCertProvider) == 0) {
270:                            param.setCertProvider(args[++i]);
271:                            continue;
272:                        }
273:                        if (args[i].compareToIgnoreCase(sKeyProvider) == 0) {
274:                            param.setKeyProvider(args[++i]);
275:                            continue;
276:                        }
277:                        if (args[i].compareToIgnoreCase(sMdProvider) == 0) {
278:                            param.setMdProvider(args[++i]);
279:                            continue;
280:                        }
281:                        if (args[i].compareToIgnoreCase(sSigProvider) == 0) {
282:                            param.setSigProvider(args[++i]);
283:                            continue;
284:                        }
285:                        if (args[i].compareToIgnoreCase(sKsProvider) == 0) {
286:                            param.setKsProvider(args[++i]);
287:                            continue;
288:                        }
289:                        if (args[i].compareToIgnoreCase(sConvKsProvider) == 0) {
290:                            param.setConvKsProvider(args[++i]);
291:                            continue;
292:                        }
293:                        if (args[i].compareToIgnoreCase(sAlias) == 0) {
294:                            param.setAlias(args[++i]);
295:                            continue;
296:                        }
297:                        if (args[i].compareToIgnoreCase(sKeyalg) == 0) {
298:                            param.setKeyAlg(args[++i]);
299:                            continue;
300:                        }
301:                        if (args[i].compareToIgnoreCase(sSigalg) == 0) {
302:                            param.setSigAlg(args[++i]);
303:                            continue;
304:                        }
305:                        if (args[i].compareToIgnoreCase(sDname) == 0) {
306:                            param.setDName(args[++i]);
307:                            continue;
308:                        }
309:                        if (args[i].compareToIgnoreCase(sFile) == 0) {
310:                            param.setFileName(args[++i]);
311:                            continue;
312:                        }
313:                        if (args[i].compareToIgnoreCase(sIssuerAlias) == 0) {
314:                            param.setIssuerAlias(args[++i]);
315:                            continue;
316:                        }
317:                        if (args[i].compareToIgnoreCase(sStorepass) == 0) {
318:                            param.setStorePass(args[++i].toCharArray());
319:                            continue;
320:                        }
321:                        if (args[i].compareToIgnoreCase(sKeypass) == 0) {
322:                            param.setKeyPass(args[++i].toCharArray());
323:                            continue;
324:                        }
325:                        if (args[i].compareToIgnoreCase(sIssuerPass) == 0) {
326:                            param.setIssuerPass(args[++i].toCharArray());
327:                            continue;
328:                        }
329:                        if (args[i].compareToIgnoreCase(sCRLfile) == 0) {
330:                            param.setCrlFile(args[++i]);
331:                            continue;
332:                        }
333:                        if (args[i].compareToIgnoreCase(sDestAlias) == 0) {
334:                            param.setDestAlias(args[++i]);
335:                            continue;
336:                        }
337:                        if (args[i].compareToIgnoreCase(sNew) == 0) {
338:                            param.setNewPasswd(args[++i].toCharArray());
339:                            continue;
340:                        }
341:                        if (args[i].compareToIgnoreCase(sConvStorePath) == 0) {
342:                            param.setConvertedKeyStorePath(args[++i]);
343:                            continue;
344:                        }
345:                        if (args[i].compareToIgnoreCase(sConvStoreType) == 0) {
346:                            param.setConvertedKeyStoreType(args[++i]);
347:                            continue;
348:                        }
349:                        if (args[i].compareToIgnoreCase(sConvStorePass) == 0) {
350:                            param.setConvertedKeyStorePass(args[++i]
351:                                    .toCharArray());
352:                            continue;
353:                        }
354:                        if (args[i].compareToIgnoreCase(sCAcertsPath) == 0) {
355:                            param.setCacertsPath(args[++i]);
356:                            continue;
357:                        }
358:                        if (args[i].compareToIgnoreCase(sCAcertsPass) == 0) {
359:                            param.setCacertsPass(args[++i].toCharArray());
360:                            continue;
361:                        }
362:                        if (args[i].compareToIgnoreCase(sKeysize) == 0) {
363:
364:                            param.setKeySize((new Integer(args[++i]))
365:                                    .intValue());
366:                            if (param.getKeySize() <= 0) {
367:                                throw new KeytoolException("Key size"
368:                                        + " must be more than zero.");
369:                            }
370:                            continue;
371:                        }
372:                        if (args[i].compareToIgnoreCase(sValidity) == 0) {
373:                            param.setValidity((new Integer(args[++i]))
374:                                    .intValue());
375:                            if (param.getValidity() <= 0) {
376:                                throw new KeytoolException("Validity"
377:                                        + " must be more than zero.");
378:                            }
379:                            continue;
380:                        }
381:                        if (args[i].compareToIgnoreCase(sX509Version) == 0) {
382:                            param.setX509version((new Integer(args[++i]))
383:                                    .intValue());
384:                            if (param.getX509version() < 1
385:                                    || param.getX509version() > 3) {
386:                                throw new KeytoolException(
387:                                        "Certificate version must be "
388:                                                + "1, 2 or 3");
389:                            }
390:                            continue;
391:                        }
392:                        if (args[i].compareToIgnoreCase(sCertSerial) == 0) {
393:                            param.setCertSerialNr((new Integer(args[++i]))
394:                                    .intValue());
395:                            if (param.getCertSerialNr() <= 0) {
396:                                throw new KeytoolException(
397:                                        "Certificate serial number"
398:                                                + " must be more than zero.");
399:                            }
400:                            continue;
401:                        }
402:
403:                        // flags
404:                        if (args[i].compareToIgnoreCase(sNoprompt) == 0) {
405:                            param.setNoPrompt(true);
406:                            continue;
407:                        }
408:                        if (args[i].compareToIgnoreCase(sTrustcacerts) == 0) {
409:                            param.setTrustCACerts(true);
410:                            continue;
411:                        }
412:                        if (args[i].compareToIgnoreCase(sRfc) == 0) {
413:                            param.setRfc(true);
414:                            continue;
415:                        }
416:                        if (args[i].compareToIgnoreCase(sV) == 0) {
417:                            param.setVerbose(true);
418:                            continue;
419:                        }
420:                        if (args[i].compareToIgnoreCase(sSecretkey) == 0) {
421:                            param.setSecretKey(true);
422:                            continue;
423:                        }
424:                        if (args[i].compareToIgnoreCase(sCA) == 0) {
425:                            param.setCA(true);
426:                            continue;
427:                        }
428:                        if (args[i].compareToIgnoreCase(sConvKeyEntries) == 0) {
429:                            param.setConvertKeyEntries(true);
430:                            continue;
431:                        }
432:
433:                        System.out.println("Illegal option: " + args[i]);
434:                        return null;
435:                    }
436:                } catch (ArrayIndexOutOfBoundsException e) {
437:                    // ignore the last option if its value is not provided
438:                }
439:
440:                Command cmd = param.getCommand();
441:
442:                // check whether -v and -rfc options are used separately with -list.
443:                if (cmd == Command.LIST && param.isRfc() && param.isVerbose()) {
444:                    throw new KeytoolException(
445:                            "There must not be both -v and -rfc "
446:                                    + "options specified");
447:                }
448:
449:                // skip the store password setting if -printcert or -help commands were
450:                // given.
451:                if (cmd == Command.PRINTCERT || cmd == Command.HELP) {
452:                    return param;
453:                }
454:
455:                // if the store password has not been entered, prompt for it
456:                if (param.getStorePass() == null) {
457:                    // get path to the store
458:                    String storePath = (param.getStorePath() != null) ? param
459:                            .getStorePath()
460:                            : KeytoolParameters.defaultKeystorePath;
461:                    // get store password
462:                    String prompt = "Enter keystore password: ";
463:                    System.out.print(prompt);
464:                    charsRead = in.read(readData);
465:                    char[] storePass;
466:                    File storeFile = new File(storePath);
467:                    if (storeFile.isDirectory()) {
468:                        throw new KeytoolException("The keystore path "
469:                                + storePath + " points to a directory.");
470:                    }
471:                    // Allow short passwords to unlock existing stores and
472:                    // disallow passwords shorter than minPwdLength symbols for new
473:                    // ones.
474:                    // Check whether the file exists
475:                    if (!storeFile.exists()) {
476:                        // check of password length and additional prompts for
477:                        // password are made here
478:                        storePass = promptLongerPassword(prompt);
479:                    } else {
480:                        // if the store exists don't check the length
481:                        storePass = new char[charsRead - newLineLength];// remove "\r\n"
482:                        System.arraycopy(readData, 0, storePass, 0, charsRead
483:                                - newLineLength);
484:                    }
485:                    if (storePass.length != 0) {
486:                        param.setStorePass(storePass);
487:                    } else {
488:                        param.setStorePass(null);
489:                    }
490:                }
491:
492:                return param;
493:            }
494:
495:            /**
496:             * Checks if the needed values are set and, if not, prompts for them.
497:             * 
498:             * This method must be called after the keystore is loaded.
499:             * 
500:             * @param param
501:             * @return
502:             * @throws KeytoolException
503:             * @throws UnrecoverableKeyException
504:             * @throws NoSuchAlgorithmException
505:             * @throws IOException
506:             * @throws KeyStoreException
507:             * @throws NoSuchProviderException 
508:             * @throws CertificateException 
509:             */
510:            static void getAdditionalParameters(KeytoolParameters param)
511:                    throws KeytoolException, IOException, KeyStoreException,
512:                    UnrecoverableKeyException, NoSuchAlgorithmException,
513:                    CertificateException, NoSuchProviderException {
514:                // this method must be called after the keystore is loaded.
515:                KeyStore keyStore = param.getKeyStore();
516:
517:                // set the alias to "mykey" if it's not set up
518:                Command command = param.getCommand();
519:                if (param.getAlias() == null
520:                        && (command == Command.KEYCLONE
521:                                || command == Command.EXPORT
522:                                || command == Command.CERTREQ
523:                                || command == Command.GENKEY
524:                                || command == Command.SELFCERT
525:                                || command == Command.IMPORT || command == Command.KEYPASSWD)) {
526:                    param.setAlias("mykey");
527:                }
528:                String alias = param.getAlias();
529:
530:                // check if the alias exists
531:                if (command == Command.CERTREQ
532:                        || command == Command.DELETE
533:                        || command == Command.EXPORT
534:                        || command == Command.KEYCLONE
535:                        || command == Command.KEYPASSWD
536:                        || command == Command.SELFCERT
537:                        || (command == Command.LIST && param.getAlias() != null)) {
538:                    if (!keyStore.containsAlias(param.getAlias())) {
539:                        throw new KeytoolException("Alias <" + alias
540:                                + "> doesn't exist");
541:                    }
542:                } else if (command == Command.GENKEY) {
543:                    if (keyStore.containsAlias(param.getAlias())) {
544:                        throw new KeytoolException(
545:                                "Key(s) not generated, alias <" + alias
546:                                        + "> already exists.");
547:                    }
548:                }
549:
550:                // if the key password has not been entered and the password is required
551:                // to get the key (it is not a password for a newly created entry)
552:                if (param.getKeyPass() == null
553:                        && (command == Command.KEYCLONE
554:                                || command == Command.EXPORT
555:                                || command == Command.CERTREQ
556:                                || command == Command.KEYPASSWD
557:                                || command == Command.SELFCERT
558:                        // if keystore contains alias, import of a certificate reply
559:                        // is considered, otherwise password is unnecessary.
560:                        || (command == Command.IMPORT && keyStore
561:                                .containsAlias(alias)))) {
562:                    param.setKeyPass(tryStorePassAsKeyPass(keyStore, alias,
563:                            param.getStorePass()));
564:                }
565:
566:                switch (command) {
567:                case GENKEY:
568:                    // if the distinguished name is not specified, get the
569:                    // necessary data
570:                    if (param.getDName() == null && !param.isSecretKey()) {
571:                        param.setDName(getDistinguishedName());
572:                    }
573:                    // if the key password has not been entered (and can equal store
574:                    // password)
575:                    if (param.getKeyPass() == null) {
576:                        param.setKeyPass(getNewPassword(null, alias, param
577:                                .getStorePass()));
578:                    }
579:
580:                    String issuerAlias = param.getIssuerAlias();
581:                    // if the newly generated certificate should be signed with 
582:                    // another certificate chain from the keystore. 
583:                    if (issuerAlias != null && !param.isSecretKey()) {
584:                        // Check if the issuer password was entered. If not, try storepass.
585:                        // If it's not ok, prompt the user.
586:                        if (param.getIssuerPass() == null) {
587:                            param.setIssuerPass(tryStorePassAsKeyPass(keyStore,
588:                                    issuerAlias, param.getStorePass()));
589:                        }
590:                    }
591:
592:                    break;
593:
594:                case KEYCLONE:
595:                    // prompt for a destination alias, if one is not specified
596:                    if (param.getDestAlias() == null) {
597:                        System.out.print("Enter destination alias name: ");
598:                        charsRead = in.read(readData);
599:                        if (charsRead <= newLineLength) {
600:                            throw new KeytoolException(
601:                                    "Must specify destination alias");
602:                        } else {
603:                            param.setDestAlias(new String(readData).substring(
604:                                    0, charsRead - newLineLength));
605:                        }
606:                    }
607:                    // if the password for a newly created entry is not specified,
608:                    // ask for it.
609:                    if (param.getNewPasswd() == null) {
610:                        param.setNewPasswd(getNewPassword(alias, param
611:                                .getDestAlias(), param.getKeyPass()));
612:                    }
613:                    break;
614:                case DELETE:
615:                    // prompt for an alias to delete, if one is not specified
616:                    if (alias == null) {
617:                        System.out.print("Enter alias name: ");
618:                        charsRead = in.read(readData);
619:                        if (charsRead <= newLineLength) {
620:                            throw new KeytoolException("Must specify alias");
621:                        } else {
622:                            param.setAlias(new String(readData).substring(0,
623:                                    charsRead - newLineLength));
624:                        }
625:                    }
626:                    break;
627:                case STOREPASSWD:
628:                case KEYPASSWD:
629:                    String prompt;
630:                    String promptReenter;
631:                    // prompt for a new password, if it is not specified
632:                    if (command == Command.KEYPASSWD) {
633:                        prompt = "Enter new key password for <" + alias + ">: ";
634:                        promptReenter = "Re-enter new keystore password for <"
635:                                + alias + ">: ";
636:                    } else { // if param.getCommand() == Command.STOREPASSWD
637:                        // prompt for a new store password, if it is not specified
638:                        prompt = "Enter new keystore password: ";
639:                        promptReenter = "Re-enter new keystore password: ";
640:                    }
641:
642:                    // if the new password is not entered
643:                    if (param.getNewPasswd() == null) {
644:                        System.out.print(prompt);
645:                        charsRead = in.read(readData);
646:                        char[] password = promptLongerPassword(prompt);
647:                        System.out.print(promptReenter);
648:                        charsRead = in.read(readData);
649:                        if (charsRead == password.length + newLineLength) {
650:                            for (int i = 0; i < password.length; i++) {
651:                                if (readData[i] != password[i]) {
652:                                    throw new KeytoolException(
653:                                            "Passwords do not match");
654:                                }
655:                            }
656:                            param.setNewPasswd(password);
657:                        } else {
658:                            throw new KeytoolException("Passwords do not match");
659:                        }
660:                        // if entered a short password in the command line
661:                    } else if (param.getNewPasswd().length < minPwdLength) {
662:                        throw new KeytoolException(
663:                                "The password must be at least " + minPwdLength
664:                                        + " characters");
665:                    }
666:
667:                    break;
668:                case LIST:
669:                    if (alias != null) {
670:                        // This check is not where the same thing for other
671:                        // commands done, because (alias != null) check is
672:                        // necessary.
673:                        if (keyStore.entryInstanceOf(alias,
674:                                KeyStore.SecretKeyEntry.class)
675:                                && param.getKeyPass() == null) {
676:                            param.setKeyPass(tryStorePassAsKeyPass(keyStore,
677:                                    alias, param.getStorePass()));
678:                        }
679:                    }
680:                    break;
681:                }// switch (param.getCommand())
682:
683:            }
684:
685:            /**
686:             * The method prompts user to enter data to initialize an X.500
687:             * Distinguished Name to create a new certificate. It gets the data asks if
688:             * it is correct, and if it is returns the String representing the
689:             * distinguished name, if the data entered is not correct prompts to enter
690:             * it again.
691:             * 
692:             * @return - String representing the distinguished names
693:             */
694:            private static String getDistinguishedName() throws IOException,
695:                    KeytoolException {
696:                // X.500 principal: CN, OU, O, L, ST, C;
697:                String[] dnFields = { "CN=", ", OU=", ", O=", ", L=", ", ST=",
698:                        ", C=" };
699:                // the flag is set to true, when the user confirms that
700:                // the data he (or she) entered is correct.
701:                boolean isCorrect = false;
702:                // X.500 Distinguished Name. It will look like:
703:                // "CN=user_name, OU=org_unit, O=organization, L=city, ST=state,
704:                // C=com"
705:                StringBuffer dname = new StringBuffer(256);
706:                // the flag is set to true when there are spaces and/or commas in
707:                // the fields of the distinguished name
708:                boolean needQuotes = false;
709:
710:                // data that user enters is saved here
711:                StringBuffer[] dnFieldsData = new StringBuffer[] {
712:                        new StringBuffer("Unknown"),
713:                        new StringBuffer("Unknown"),
714:                        new StringBuffer("Unknown"),
715:                        new StringBuffer("Unknown"),
716:                        new StringBuffer("Unknown"),
717:                        new StringBuffer("Unknown") };
718:
719:                // prompts to show to user when asking to enter some data
720:                String[] prompts = { "Enter your first and last name: ",
721:                        "Enter the name of your organizational unit: ",
722:                        "Enter the name of your organization: ",
723:                        "Enter the name of your city or locality: ",
724:                        "Enter the name of your state or province: ",
725:                        "Enter the two-letter country code for the unit: ",
726:                        "Is the information you entered correct? [no]: " };
727:
728:                // do it until user confirms that the data he entered is true.
729:                while (!isCorrect) {
730:                    // clear dname if it is not empty
731:                    if (dname.length() > 0) {
732:                        dname.delete(0, dname.length());
733:                    }
734:                    for (int i = 0; i < dnFieldsData.length; i++) {
735:                        // ask the user to enter info
736:                        System.out.println(prompts[i]);
737:                        // print the current value of the field
738:                        System.out.print("[" + dnFieldsData[i] + "]: ");
739:                        dname.append(dnFields[i]);
740:                        charsRead = in.read(readData);
741:                        // if something was entered put the new value to
742:                        // dnFieldsData
743:                        // else don't change what was entered before.
744:                        if (charsRead > newLineLength) {
745:                            // check whether quotes are needed.
746:                            needQuotes = false;
747:                            for (int j = 0; j < charsRead - newLineLength; j++) {
748:                                if (readData[j] == ',' || readData[j] == ' ') {
749:                                    needQuotes = true;
750:                                    break;
751:                                }
752:                            }
753:                            // if quotes are not needed
754:                            if (!needQuotes) {
755:                                // copy the read data into the StringBuffer.
756:                                // don't need the '\r' and \n' in the end
757:                                dnFieldsData[i].insert(0, readData, 0,
758:                                        charsRead - newLineLength);
759:                                dnFieldsData[i].delete(charsRead
760:                                        - newLineLength, dnFieldsData[i]
761:                                        .length());
762:                            } else {// if quotes are needed, add them to the begin
763:                                // and to the end
764:                                dnFieldsData[i].insert(0, '\"');
765:                                dnFieldsData[i].insert(1, readData, 0,
766:                                        charsRead - newLineLength);
767:                                dnFieldsData[i].insert(charsRead - 1, '\"');
768:                                dnFieldsData[i].delete(charsRead,
769:                                        dnFieldsData[i].length());
770:                            }
771:                        }
772:                        dname.append(dnFieldsData[i]);
773:                    }
774:                    // print the distinguished name with the fields filled
775:                    System.out.println(dname);
776:                    // confirm, if the user enters 'y' or "yes"
777:                    // any other input results in asking the questions again
778:                    isCorrect = getConfirmation(prompts[prompts.length - 1],
779:                            true);
780:                }
781:                // save the data when got the confirmation from the user
782:                return new String(dname);
783:            }
784:
785:            /**
786:             * The method should be called only after the password was entered and put into
787:             * readData. charsRead also shouldn't be changed after the password was
788:             * entered and before the method is called. If charsRead is less than
789:             * minPwdLength + newLineLength, the method just copies the password from
790:             * readData into a newly created char array; otherwise it prompts for a
791:             * longer password for maxNrOfAttempts times.
792:             * 
793:             * @param prompt
794:             * @return new password of length equal or longer than minPwdLength
795:             * @throws IOException
796:             * @throws KeytoolException
797:             */
798:            private static char[] promptLongerPassword(String prompt)
799:                    throws IOException, KeytoolException {
800:                int cntAttempts = 0;
801:                while (charsRead < minPwdLength + newLineLength) {
802:                    System.out.println("The password must be at least "
803:                            + minPwdLength + " characters");
804:                    System.out.print(prompt);
805:                    charsRead = in.read(readData);
806:                    ++cntAttempts;
807:                    if (cntAttempts >= maxNrOfAttempts) {
808:                        throw new KeytoolException("Too many failures. "
809:                                + "Please, try again later.");
810:                    }
811:                }
812:                char[] password = new char[charsRead - newLineLength];
813:                System.arraycopy(readData, 0, password, 0, charsRead
814:                        - newLineLength);
815:                return password;
816:            }
817:
818:            /**
819:             * Does all work to get from the user a password for a newly created (cloned
820:             * or generated) key.
821:             * 
822:             * @param -
823:             *            srcAlias is the alias of the entry to clone, or if it is null,
824:             *            the keystore password will be prompted to use.
825:             * @param -
826:             *            destAlias is the alias of the newly created entry.
827:             * @param -
828:             *            srcPass is the password to be used with a new entry if the
829:             *            user doesn't enter a new one.
830:             * 
831:             * @return - char array representing the password for the entry. It can be
832:             *         equal to the keystore password or the password of a cloned key.
833:             */
834:            private static char[] getNewPassword(String srcAlias,
835:                    String destAlias, char[] srcPass) throws IOException,
836:                    KeytoolException {
837:                if (destAlias == null) {
838:                    return null;
839:                }
840:                String prompt = "Enter key password for <" + destAlias + ">: ";
841:                System.out.print(prompt);
842:                if (srcAlias == null) {
843:                    System.out.print("(Press RETURN if same as for keystore) ");
844:                } else {
845:                    System.out.print("(Press RETURN if same as for <"
846:                            + srcAlias + ">) ");
847:                }
848:                charsRead = in.read(readData);
849:                char[] destPass;
850:                // if RETURN was pressed
851:                if (charsRead <= newLineLength) {
852:                    destPass = new char[srcPass.length];
853:                    System.arraycopy(srcPass, 0, destPass, 0, srcPass.length);
854:                } else {// if some password was entered
855:                    destPass = promptLongerPassword(prompt);
856:                }
857:                return destPass;
858:            }
859:
860:            /**
861:             * Prints a promt. Reads what the user enters. If the user has entered
862:             * 'y'/"yes" or 'n'/"no" (case insensitively) the method returns
863:             * respectively true or false. Depending on acceptAnother parameter the
864:             * method can return false if anything except 'y' or "yes" is entered, or it
865:             * can prompt for a correct answer. If only ENTER is pressed false is
866:             * returned.
867:             * 
868:             * @param promt -
869:             *            text printed to ask the user for a confirmation
870:             * @param acceptAnother -
871:             *            if set to true, the method returns true if and only if the
872:             *            user enters 'y' or "yes"; if set to false prompts to reenter
873:             *            the answer from user until 'y'/"yes" or 'n'/"no" is entered.
874:             * @return true if the user confirms the request, false - otherwise.
875:             * @throws IOException
876:             */
877:            static boolean getConfirmation(String promt, boolean acceptAnother)
878:                    throws IOException, KeytoolException {
879:                int counter = 0;
880:                while (counter++ < 100) {
881:                    System.out.print(promt);
882:                    charsRead = in.read(readData);
883:                    // if pressed ENTER return the default value
884:                    if (charsRead == newLineLength) {
885:                        return false;
886:                    }
887:                    // confirm, if the user enters 'y' or "yes"
888:                    if ((charsRead == newLineLength + 1 && (readData[0] == 'y' || readData[0] == 'Y'))
889:                            || (charsRead == newLineLength + 3 && "yes"
890:                                    .equalsIgnoreCase(new String(readData)
891:                                            .substring(0, 3)))) {
892:                        return true;
893:                    } else if (acceptAnother) {
894:                        return false;
895:                    } else {
896:                        // if entered 'n' or "no"
897:                        if (readData[0] == 'n'
898:                                || readData[0] == 'N'
899:                                && ((charsRead == newLineLength + 1) || (charsRead == newLineLength + 2
900:                                        && readData[0] == 'o' || readData[0] == 'O'))) {
901:                            return false;
902:                        } else {
903:                            System.out
904:                                    .println("Wrong answer, please, try again");
905:                        }
906:                    }
907:                }
908:                throw new KeytoolException("Too many failures. ");
909:            }
910:
911:            // method tries to get the key, associated with alias, using the storePass,
912:            // if it can be recovered using the password storePass is returned,
913:            // otherwise - the password is prompted for. Another attempt to recover the
914:            // key with entered password. If it is ok, it is returned, otherwise
915:            // UnrecoverableKeyException is thrown.
916:            private static char[] tryStorePassAsKeyPass(KeyStore keyStore,
917:                    String alias, char[] storePass) throws KeyStoreException,
918:                    IOException, UnrecoverableKeyException,
919:                    NoSuchAlgorithmException {
920:                try {
921:                    // try to get a key with keystore password
922:                    // if succeed set key password same as that for keystore
923:                    keyStore.getKey(alias, storePass);
924:
925:                    // will not come here if exception is thrown
926:                    return storePass;
927:                } catch (UnrecoverableKeyException e) {
928:                    // if key password is not equal to store password, ask for it.
929:                    System.out
930:                            .print("Enter key password for <" + alias + ">: ");
931:                    charsRead = in.read(readData);
932:                    char[] keyPass = new char[charsRead - newLineLength];
933:                    System.arraycopy(readData, 0, keyPass, 0, charsRead
934:                            - newLineLength);
935:                    // if the new password is incorrect an exception will be thrown
936:                    try {
937:                        keyStore.getKey(alias, keyPass);
938:                    } catch (NoSuchAlgorithmException nsae) {
939:                        throw new NoSuchAlgorithmException(
940:                                "Cannot find the algorithm to recover the key. ",
941:                                e);
942:                    }
943:                    return keyPass;
944:                } catch (NoSuchAlgorithmException e) {
945:                    throw new NoSuchAlgorithmException(
946:                            "Cannot find the algorithm to recover the key. ", e);
947:                }
948:            }
949:
950:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.