001/* 002 * Copyright 2017-2022 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2017-2022 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2017-2022 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.util.ssl.cert; 037 038 039 040import java.io.BufferedInputStream; 041import java.io.BufferedReader; 042import java.io.ByteArrayInputStream; 043import java.io.File; 044import java.io.FileInputStream; 045import java.io.FileOutputStream; 046import java.io.InputStream; 047import java.io.InputStreamReader; 048import java.io.IOException; 049import java.io.OutputStream; 050import java.io.PrintStream; 051import java.nio.file.Files; 052import java.net.InetAddress; 053import java.security.Key; 054import java.security.KeyPair; 055import java.security.KeyStore; 056import java.security.PrivateKey; 057import java.security.Provider; 058import java.security.PublicKey; 059import java.security.UnrecoverableKeyException; 060import java.security.cert.Certificate; 061import java.text.SimpleDateFormat; 062import java.util.ArrayList; 063import java.util.Arrays; 064import java.util.Collections; 065import java.util.Date; 066import java.util.Enumeration; 067import java.util.Iterator; 068import java.util.LinkedHashMap; 069import java.util.LinkedHashSet; 070import java.util.List; 071import java.util.Map; 072import java.util.Set; 073import java.util.concurrent.LinkedBlockingQueue; 074import java.util.concurrent.TimeUnit; 075import java.util.concurrent.atomic.AtomicReference; 076 077import com.unboundid.asn1.ASN1BitString; 078import com.unboundid.asn1.ASN1Element; 079import com.unboundid.ldap.sdk.DN; 080import com.unboundid.ldap.sdk.LDAPConnectionOptions; 081import com.unboundid.ldap.sdk.LDAPException; 082import com.unboundid.ldap.sdk.ResultCode; 083import com.unboundid.ldap.sdk.Version; 084import com.unboundid.util.Base64; 085import com.unboundid.util.BouncyCastleFIPSHelper; 086import com.unboundid.util.ByteStringBuffer; 087import com.unboundid.util.CommandLineTool; 088import com.unboundid.util.CryptoHelper; 089import com.unboundid.util.Debug; 090import com.unboundid.util.NotNull; 091import com.unboundid.util.Nullable; 092import com.unboundid.util.OID; 093import com.unboundid.util.ObjectPair; 094import com.unboundid.util.PasswordReader; 095import com.unboundid.util.StaticUtils; 096import com.unboundid.util.ThreadSafety; 097import com.unboundid.util.ThreadSafetyLevel; 098import com.unboundid.util.Validator; 099import com.unboundid.util.args.ArgumentException; 100import com.unboundid.util.args.ArgumentParser; 101import com.unboundid.util.args.BooleanArgument; 102import com.unboundid.util.args.BooleanValueArgument; 103import com.unboundid.util.args.DNArgument; 104import com.unboundid.util.args.FileArgument; 105import com.unboundid.util.args.IA5StringArgumentValueValidator; 106import com.unboundid.util.args.IPAddressArgumentValueValidator; 107import com.unboundid.util.args.IntegerArgument; 108import com.unboundid.util.args.OIDArgumentValueValidator; 109import com.unboundid.util.args.StringArgument; 110import com.unboundid.util.args.TimestampArgument; 111import com.unboundid.util.args.SubCommand; 112import com.unboundid.util.ssl.JVMDefaultTrustManager; 113import com.unboundid.util.ssl.PKCS11KeyManager; 114 115import static com.unboundid.util.ssl.cert.CertMessages.*; 116 117 118 119/** 120 * This class provides a tool that can be used to manage X.509 certificates for 121 * use in TLS communication. 122 */ 123@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 124public final class ManageCertificates 125 extends CommandLineTool 126{ 127 /** 128 * The path to the keystore with the JVM's set of default trusted issuer 129 * certificates. 130 */ 131 @Nullable private static final File JVM_DEFAULT_CACERTS_FILE; 132 static 133 { 134 File caCertsFile; 135 try 136 { 137 caCertsFile = JVMDefaultTrustManager.getInstance().getCACertsFile(); 138 } 139 catch (final Exception e) 140 { 141 Debug.debugException(e); 142 caCertsFile = null; 143 } 144 145 JVM_DEFAULT_CACERTS_FILE = caCertsFile; 146 } 147 148 149 150 /** 151 * The name of the keystore type that should be used for the Bouncy Castle 152 * FIPS 140-2-compliant keystore. 153 */ 154 @NotNull private static final String BCFKS_KEYSTORE_TYPE = 155 BouncyCastleFIPSHelper.FIPS_KEY_STORE_TYPE; 156 157 158 159 /** 160 * The name of the BCFKS keystore type, formatted in all lowercase. 161 */ 162 @NotNull private static final String BCFKS_KEYSTORE_TYPE_LC = 163 BCFKS_KEYSTORE_TYPE.toLowerCase(); 164 165 166 167 /** 168 * The name of a system property that can be used to specify the default 169 * keystore type for new keystores. 170 */ 171 @NotNull private static final String PROPERTY_DEFAULT_KEYSTORE_TYPE = 172 ManageCertificates.class.getName() + ".defaultKeystoreType"; 173 174 175 176 /** 177 * The default keystore type that will be used for new keystores when the 178 * type is not specified. 179 */ 180 @NotNull private static final String DEFAULT_KEYSTORE_TYPE; 181 static 182 { 183 final String propertyValue = 184 StaticUtils.getSystemProperty(PROPERTY_DEFAULT_KEYSTORE_TYPE); 185 if (CryptoHelper.usingFIPSMode() || 186 ((propertyValue != null) && propertyValue.equalsIgnoreCase( 187 BCFKS_KEYSTORE_TYPE))) 188 { 189 DEFAULT_KEYSTORE_TYPE = BCFKS_KEYSTORE_TYPE; 190 } 191 else if ((propertyValue != null) && 192 (propertyValue.equalsIgnoreCase("PKCS12") || 193 propertyValue.equalsIgnoreCase("PKCS#12") || 194 propertyValue.equalsIgnoreCase("PKCS #12") || 195 propertyValue.equalsIgnoreCase("PKCS 12"))) 196 { 197 DEFAULT_KEYSTORE_TYPE = CryptoHelper.KEY_STORE_TYPE_PKCS_12; 198 } 199 else 200 { 201 DEFAULT_KEYSTORE_TYPE = CryptoHelper.KEY_STORE_TYPE_JKS; 202 } 203 } 204 205 206 207 /** 208 * The column at which to wrap long lines of output. 209 */ 210 private static final int WRAP_COLUMN = StaticUtils.TERMINAL_WIDTH_COLUMNS - 1; 211 212 213 214 /** 215 * The set of values that will be allowed for the keystore type argument. 216 */ 217 @NotNull private static final Set<String> ALLOWED_KEYSTORE_TYPE_VALUES = 218 StaticUtils.setOf("jks", 219 "pkcs11", "pkcs 11", "pkcs#11", "pkcs #11", 220 "pkcs12", "pkcs 12", "pkcs#12", "pkcs #12", 221 BCFKS_KEYSTORE_TYPE_LC); 222 223 224 225 // The global argument parser used by this tool. 226 @Nullable private volatile ArgumentParser globalParser = null; 227 228 // The argument parser for the selected subcommand. 229 @Nullable private volatile ArgumentParser subCommandParser = null; 230 231 // The input stream to use for standard input. 232 @NotNull private final InputStream in; 233 234 235 236 /** 237 * Invokes this tool with the default standard output and standard error and 238 * the provided set of arguments. 239 * 240 * @param args The command-line arguments provided to this program. 241 */ 242 public static void main(@NotNull final String... args) 243 { 244 final ResultCode resultCode = main(System.in, System.out, System.err, args); 245 if (resultCode != ResultCode.SUCCESS) 246 { 247 System.exit(Math.max(1, Math.min(resultCode.intValue(), 255))); 248 } 249 } 250 251 252 253 /** 254 * Invokes this tool with the provided output and error streams and set of 255 * arguments. 256 * 257 * @param in The input stream to use for standard input. It may be 258 * {@code null} if no input stream should be available. 259 * @param out The output stream to use for standard output. It may be 260 * {@code null} if standard output should be suppressed. 261 * @param err The output stream to use for standard error. It may be 262 * {@code null} if standard error should be suppressed. 263 * @param args The command-line arguments provided to this program. 264 * 265 * @return The result code obtained from tool processing. 266 */ 267 @NotNull() 268 public static ResultCode main(@Nullable final InputStream in, 269 @Nullable final OutputStream out, 270 @Nullable final OutputStream err, 271 @NotNull final String... args) 272 { 273 final ManageCertificates manageCertificates = 274 new ManageCertificates(in, out, err); 275 return manageCertificates.runTool(args); 276 } 277 278 279 280 /** 281 * Creates a new instance of this tool with the provided output and error 282 * streams. Standard input will bot be available. 283 * 284 * @param out The output stream to use for standard output. It may be 285 * {@code null} if standard output should be suppressed. 286 * @param err The output stream to use for standard error. It may be 287 * {@code null} if standard error should be suppressed. 288 */ 289 public ManageCertificates(@Nullable final OutputStream out, 290 @Nullable final OutputStream err) 291 { 292 this(null, out, err); 293 } 294 295 296 297 /** 298 * Creates a new instance of this tool with the provided output and error 299 * streams. 300 * 301 * @param in The input stream to use for standard input. It may be 302 * {@code null} if no input stream should be available. 303 * @param out The output stream to use for standard output. It may be 304 * {@code null} if standard output should be suppressed. 305 * @param err The output stream to use for standard error. It may be 306 * {@code null} if standard error should be suppressed. 307 */ 308 public ManageCertificates(@Nullable final InputStream in, 309 @Nullable final OutputStream out, 310 @Nullable final OutputStream err) 311 { 312 super(out, err); 313 314 if (in == null) 315 { 316 this.in = new ByteArrayInputStream(StaticUtils.NO_BYTES); 317 } 318 else 319 { 320 this.in = in; 321 } 322 } 323 324 325 326 /** 327 * Retrieves the name of this tool. It should be the name of the command used 328 * to invoke this tool. 329 * 330 * @return The name for this tool. 331 */ 332 @Override() 333 @NotNull() 334 public String getToolName() 335 { 336 return "manage-certificates"; 337 } 338 339 340 341 /** 342 * Retrieves a human-readable description for this tool. 343 * 344 * @return A human-readable description for this tool. 345 */ 346 @Override() 347 @NotNull() 348 public String getToolDescription() 349 { 350 return INFO_MANAGE_CERTS_TOOL_DESC.get(); 351 } 352 353 354 355 /** 356 * Retrieves a version string for this tool, if available. 357 * 358 * @return A version string for this tool, or {@code null} if none is 359 * available. 360 */ 361 @Override() 362 @NotNull() 363 public String getToolVersion() 364 { 365 return Version.NUMERIC_VERSION_STRING; 366 } 367 368 369 370 /** 371 * Indicates whether this tool should provide support for an interactive mode, 372 * in which the tool offers a mode in which the arguments can be provided in 373 * a text-driven menu rather than requiring them to be given on the command 374 * line. If interactive mode is supported, it may be invoked using the 375 * "--interactive" argument. Alternately, if interactive mode is supported 376 * and {@link #defaultsToInteractiveMode()} returns {@code true}, then 377 * interactive mode may be invoked by simply launching the tool without any 378 * arguments. 379 * 380 * @return {@code true} if this tool supports interactive mode, or 381 * {@code false} if not. 382 */ 383 @Override() 384 public boolean supportsInteractiveMode() 385 { 386 return true; 387 } 388 389 390 391 /** 392 * Indicates whether this tool defaults to launching in interactive mode if 393 * the tool is invoked without any command-line arguments. This will only be 394 * used if {@link #supportsInteractiveMode()} returns {@code true}. 395 * 396 * @return {@code true} if this tool defaults to using interactive mode if 397 * launched without any command-line arguments, or {@code false} if 398 * not. 399 */ 400 @Override() 401 public boolean defaultsToInteractiveMode() 402 { 403 return true; 404 } 405 406 407 408 /** 409 * Indicates whether this tool supports the use of a properties file for 410 * specifying default values for arguments that aren't specified on the 411 * command line. 412 * 413 * @return {@code true} if this tool supports the use of a properties file 414 * for specifying default values for arguments that aren't specified 415 * on the command line, or {@code false} if not. 416 */ 417 @Override() 418 public boolean supportsPropertiesFile() 419 { 420 return true; 421 } 422 423 424 425 /** 426 * Indicates whether this tool should provide arguments for redirecting output 427 * to a file. If this method returns {@code true}, then the tool will offer 428 * an "--outputFile" argument that will specify the path to a file to which 429 * all standard output and standard error content will be written, and it will 430 * also offer a "--teeToStandardOut" argument that can only be used if the 431 * "--outputFile" argument is present and will cause all output to be written 432 * to both the specified output file and to standard output. 433 * 434 * @return {@code true} if this tool should provide arguments for redirecting 435 * output to a file, or {@code false} if not. 436 */ 437 @Override() 438 protected boolean supportsOutputFile() 439 { 440 return false; 441 } 442 443 444 445 /** 446 * Indicates whether to log messages about the launch and completion of this 447 * tool into the invocation log of Ping Identity server products that may 448 * include it. This method is not needed for tools that are not expected to 449 * be part of the Ping Identity server products suite. Further, this value 450 * may be overridden by settings in the server's 451 * tool-invocation-logging.properties file. 452 * <BR><BR> 453 * This method should generally return {@code true} for tools that may alter 454 * the server configuration, data, or other state information, and 455 * {@code false} for tools that do not make any changes. 456 * 457 * @return {@code true} if Ping Identity server products should include 458 * messages about the launch and completion of this tool in tool 459 * invocation log files by default, or {@code false} if not. 460 */ 461 @Override() 462 protected boolean logToolInvocationByDefault() 463 { 464 return true; 465 } 466 467 468 469 /** 470 * Adds the command-line arguments supported for use with this tool to the 471 * provided argument parser. The tool may need to retain references to the 472 * arguments (and/or the argument parser, if trailing arguments are allowed) 473 * to it in order to obtain their values for use in later processing. 474 * 475 * @param parser The argument parser to which the arguments are to be added. 476 * 477 * @throws ArgumentException If a problem occurs while adding any of the 478 * tool-specific arguments to the provided 479 * argument parser. 480 */ 481 @Override() 482 public void addToolArguments(@NotNull final ArgumentParser parser) 483 throws ArgumentException 484 { 485 globalParser = parser; 486 487 488 // Define the "list-certificates" subcommand and all of its arguments. 489 final ArgumentParser listCertsParser = new ArgumentParser( 490 "list-certificates", INFO_MANAGE_CERTS_SC_LIST_CERTS_DESC.get()); 491 492 final FileArgument listCertsKeystore = new FileArgument(null, "keystore", 493 (JVM_DEFAULT_CACERTS_FILE == null), 1, null, 494 INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_KS_DESC.get(), true, true, true, 495 false); 496 listCertsKeystore.addLongIdentifier("keystore-path", true); 497 listCertsKeystore.addLongIdentifier("keystorePath", true); 498 listCertsKeystore.addLongIdentifier("keystore-file", true); 499 listCertsKeystore.addLongIdentifier("keystoreFile", true); 500 listCertsParser.addArgument(listCertsKeystore); 501 502 if (JVM_DEFAULT_CACERTS_FILE != null) 503 { 504 final BooleanArgument listCertsUseJVMDefault = new BooleanArgument(null, 505 "use-jvm-default-trust-store", 1, 506 INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_JVM_DEFAULT_DESC.get( 507 JVM_DEFAULT_CACERTS_FILE.getAbsolutePath())); 508 listCertsUseJVMDefault.addLongIdentifier("useJVMDefaultTrustStore", true); 509 listCertsUseJVMDefault.addLongIdentifier("jvm-default", true); 510 listCertsUseJVMDefault.addLongIdentifier("jvmDefault", true); 511 listCertsParser.addArgument(listCertsUseJVMDefault); 512 513 listCertsParser.addRequiredArgumentSet(listCertsUseJVMDefault, 514 listCertsKeystore); 515 listCertsParser.addExclusiveArgumentSet(listCertsUseJVMDefault, 516 listCertsKeystore); 517 } 518 519 final StringArgument listCertsKeystorePassword = new StringArgument(null, 520 "keystore-password", false, 1, 521 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 522 INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_KS_PW_DESC.get()); 523 listCertsKeystorePassword.addLongIdentifier("keystorePassword", true); 524 listCertsKeystorePassword.addLongIdentifier("keystore-passphrase", true); 525 listCertsKeystorePassword.addLongIdentifier("keystorePassphrase", true); 526 listCertsKeystorePassword.addLongIdentifier("keystore-pin", true); 527 listCertsKeystorePassword.addLongIdentifier("keystorePIN", true); 528 listCertsKeystorePassword.addLongIdentifier("storepass", true); 529 listCertsKeystorePassword.setSensitive(true); 530 listCertsParser.addArgument(listCertsKeystorePassword); 531 532 final FileArgument listCertsKeystorePasswordFile = new FileArgument(null, 533 "keystore-password-file", false, 1, null, 534 INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_KS_PW_FILE_DESC.get(), true, true, 535 true, false); 536 listCertsKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 537 true); 538 listCertsKeystorePasswordFile.addLongIdentifier("keystore-passphrase-file", 539 true); 540 listCertsKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 541 true); 542 listCertsKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 543 true); 544 listCertsKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 545 listCertsParser.addArgument(listCertsKeystorePasswordFile); 546 547 final BooleanArgument listCertsPromptForKeystorePassword = 548 new BooleanArgument(null, "prompt-for-keystore-password", 549 INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_PROMPT_FOR_KS_PW_DESC.get()); 550 listCertsPromptForKeystorePassword.addLongIdentifier( 551 "promptForKeystorePassword", true); 552 listCertsPromptForKeystorePassword.addLongIdentifier( 553 "prompt-for-keystore-passphrase", true); 554 listCertsPromptForKeystorePassword.addLongIdentifier( 555 "promptForKeystorePassphrase", true); 556 listCertsPromptForKeystorePassword.addLongIdentifier( 557 "prompt-for-keystore-pin", true); 558 listCertsPromptForKeystorePassword.addLongIdentifier( 559 "promptForKeystorePIN", true); 560 listCertsParser.addArgument(listCertsPromptForKeystorePassword); 561 562 final StringArgument listCertsKeystoreType = new StringArgument(null, 563 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 564 INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_KS_TYPE_DESC.get(), 565 ALLOWED_KEYSTORE_TYPE_VALUES); 566 listCertsKeystoreType.addLongIdentifier("key-store-type", true); 567 listCertsKeystoreType.addLongIdentifier("keystoreType", true); 568 listCertsKeystoreType.addLongIdentifier("keystore-format", true); 569 listCertsKeystoreType.addLongIdentifier("key-store-format", true); 570 listCertsKeystoreType.addLongIdentifier("keystoreFormat", true); 571 listCertsKeystoreType.addLongIdentifier("storetype", true); 572 listCertsParser.addArgument(listCertsKeystoreType); 573 574 final StringArgument listCertsAlias = new StringArgument(null, "alias", 575 false, 0, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 576 INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_ALIAS_DESC.get()); 577 listCertsAlias.addLongIdentifier("nickname", true); 578 listCertsParser.addArgument(listCertsAlias); 579 580 final BooleanArgument listCertsDisplayPEM = new BooleanArgument(null, 581 "display-pem-certificate", 1, 582 INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_DISPLAY_PEM_DESC.get()); 583 listCertsDisplayPEM.addLongIdentifier("displayPEMCertificate", true); 584 listCertsDisplayPEM.addLongIdentifier("display-pem", true); 585 listCertsDisplayPEM.addLongIdentifier("displayPEM", true); 586 listCertsDisplayPEM.addLongIdentifier("show-pem-certificate", true); 587 listCertsDisplayPEM.addLongIdentifier("showPEMCertificate", true); 588 listCertsDisplayPEM.addLongIdentifier("show-pem", true); 589 listCertsDisplayPEM.addLongIdentifier("showPEM", true); 590 listCertsDisplayPEM.addLongIdentifier("pem", true); 591 listCertsDisplayPEM.addLongIdentifier("rfc", true); 592 listCertsParser.addArgument(listCertsDisplayPEM); 593 594 final BooleanArgument listCertsVerbose = new BooleanArgument(null, 595 "verbose", 1, INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_VERBOSE_DESC.get()); 596 listCertsParser.addArgument(listCertsVerbose); 597 598 final BooleanArgument listCertsDisplayCommand = new BooleanArgument(null, 599 "display-keytool-command", 1, 600 INFO_MANAGE_CERTS_SC_LIST_CERTS_ARG_DISPLAY_COMMAND_DESC.get()); 601 listCertsDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 602 listCertsDisplayCommand.addLongIdentifier("show-keytool-command", true); 603 listCertsDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 604 listCertsParser.addArgument(listCertsDisplayCommand); 605 606 listCertsParser.addExclusiveArgumentSet(listCertsKeystorePassword, 607 listCertsKeystorePasswordFile, listCertsPromptForKeystorePassword); 608 609 final LinkedHashMap<String[],String> listCertsExamples = 610 new LinkedHashMap<>(StaticUtils.computeMapCapacity(3)); 611 listCertsExamples.put( 612 new String[] 613 { 614 "list-certificates", 615 "--keystore", getPlatformSpecificPath("config", "keystore") 616 }, 617 INFO_MANAGE_CERTS_SC_LIST_CERTS_EXAMPLE_1.get( 618 getPlatformSpecificPath("config", "keystore"))); 619 listCertsExamples.put( 620 new String[] 621 { 622 "list-certificates", 623 "--keystore", getPlatformSpecificPath("config", "keystore.p12"), 624 "--keystore-password-file", 625 getPlatformSpecificPath("config", "keystore.pin"), 626 "--alias", "server-cert", 627 "--verbose", 628 "--display-pem-certificate", 629 "--display-keytool-command" 630 }, 631 INFO_MANAGE_CERTS_SC_LIST_CERTS_EXAMPLE_2.get( 632 getPlatformSpecificPath("config", "keystore.p12"), 633 getPlatformSpecificPath("config", "keystore.pin"))); 634 if (JVM_DEFAULT_CACERTS_FILE != null) 635 { 636 listCertsExamples.put( 637 new String[] 638 { 639 "list-certificates", 640 "--use-jvm-default-trust-store" 641 }, 642 INFO_MANAGE_CERTS_SC_LIST_CERTS_EXAMPLE_3.get()); 643 } 644 645 final SubCommand listCertsSubCommand = new SubCommand("list-certificates", 646 INFO_MANAGE_CERTS_SC_LIST_CERTS_DESC.get(), listCertsParser, 647 listCertsExamples); 648 listCertsSubCommand.addName("listCertificates", true); 649 listCertsSubCommand.addName("list-certs", true); 650 listCertsSubCommand.addName("listCerts", true); 651 listCertsSubCommand.addName("list", true); 652 653 parser.addSubCommand(listCertsSubCommand); 654 655 656 // Define the "export-certificate" subcommand and all of its arguments. 657 final ArgumentParser exportCertParser = new ArgumentParser( 658 "export-certificate", INFO_MANAGE_CERTS_SC_EXPORT_CERT_DESC.get()); 659 660 final FileArgument exportCertKeystore = new FileArgument(null, "keystore", 661 (JVM_DEFAULT_CACERTS_FILE == null), 1, null, 662 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_KS_DESC.get(), true, true, true, 663 false); 664 exportCertKeystore.addLongIdentifier("keystore-path", true); 665 exportCertKeystore.addLongIdentifier("keystorePath", true); 666 exportCertKeystore.addLongIdentifier("keystore-file", true); 667 exportCertKeystore.addLongIdentifier("keystoreFile", true); 668 exportCertParser.addArgument(exportCertKeystore); 669 670 if (JVM_DEFAULT_CACERTS_FILE != null) 671 { 672 final BooleanArgument exportCertUseJVMDefault = new BooleanArgument(null, 673 "use-jvm-default-trust-store", 1, 674 INFO_MANAGE_CERTS_SC_EXPORT_CERTS_ARG_JVM_DEFAULT_DESC.get( 675 JVM_DEFAULT_CACERTS_FILE.getAbsolutePath())); 676 exportCertUseJVMDefault.addLongIdentifier("useJVMDefaultTrustStore", 677 true); 678 exportCertUseJVMDefault.addLongIdentifier("jvm-default", true); 679 exportCertUseJVMDefault.addLongIdentifier("jvmDefault", true); 680 exportCertParser.addArgument(exportCertUseJVMDefault); 681 682 exportCertParser.addRequiredArgumentSet(exportCertUseJVMDefault, 683 exportCertKeystore); 684 exportCertParser.addExclusiveArgumentSet(exportCertUseJVMDefault, 685 exportCertKeystore); 686 } 687 688 final StringArgument exportCertKeystorePassword = new StringArgument(null, 689 "keystore-password", false, 1, 690 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 691 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_KS_PW_DESC.get()); 692 exportCertKeystorePassword.addLongIdentifier("keystorePassword", true); 693 exportCertKeystorePassword.addLongIdentifier("keystore-passphrase", true); 694 exportCertKeystorePassword.addLongIdentifier("keystorePassphrase", true); 695 exportCertKeystorePassword.addLongIdentifier("keystore-pin", true); 696 exportCertKeystorePassword.addLongIdentifier("keystorePIN", true); 697 exportCertKeystorePassword.addLongIdentifier("storepass", true); 698 exportCertKeystorePassword.setSensitive(true); 699 exportCertParser.addArgument(exportCertKeystorePassword); 700 701 final FileArgument exportCertKeystorePasswordFile = new FileArgument(null, 702 "keystore-password-file", false, 1, null, 703 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_KS_PW_FILE_DESC.get(), true, true, 704 true, false); 705 exportCertKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 706 true); 707 exportCertKeystorePasswordFile.addLongIdentifier("keystore-passphrase-file", 708 true); 709 exportCertKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 710 true); 711 exportCertKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 712 true); 713 exportCertKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 714 exportCertParser.addArgument(exportCertKeystorePasswordFile); 715 716 final BooleanArgument exportCertPromptForKeystorePassword = 717 new BooleanArgument(null, "prompt-for-keystore-password", 718 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_PROMPT_FOR_KS_PW_DESC.get()); 719 exportCertPromptForKeystorePassword.addLongIdentifier( 720 "promptForKeystorePassword", true); 721 exportCertPromptForKeystorePassword.addLongIdentifier( 722 "prompt-for-keystore-passphrase", true); 723 exportCertPromptForKeystorePassword.addLongIdentifier( 724 "promptForKeystorePassphrase", true); 725 exportCertPromptForKeystorePassword.addLongIdentifier( 726 "prompt-for-keystore-pin", true); 727 exportCertPromptForKeystorePassword.addLongIdentifier( 728 "promptForKeystorePIN", true); 729 exportCertParser.addArgument(exportCertPromptForKeystorePassword); 730 731 final StringArgument exportCertKeystoreType = new StringArgument(null, 732 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 733 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_KS_TYPE_DESC.get(), 734 ALLOWED_KEYSTORE_TYPE_VALUES); 735 exportCertKeystoreType.addLongIdentifier("key-store-type", true); 736 exportCertKeystoreType.addLongIdentifier("keystoreType", true); 737 exportCertKeystoreType.addLongIdentifier("keystore-format", true); 738 exportCertKeystoreType.addLongIdentifier("key-store-format", true); 739 exportCertKeystoreType.addLongIdentifier("keystoreFormat", true); 740 exportCertKeystoreType.addLongIdentifier("storetype", true); 741 exportCertParser.addArgument(exportCertKeystoreType); 742 743 final StringArgument exportCertAlias = new StringArgument(null, "alias", 744 true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 745 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_ALIAS_DESC.get()); 746 exportCertAlias.addLongIdentifier("nickname", true); 747 exportCertParser.addArgument(exportCertAlias); 748 749 final BooleanArgument exportCertChain = new BooleanArgument(null, 750 "export-certificate-chain", 1, 751 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_CHAIN_DESC.get()); 752 exportCertChain.addLongIdentifier("exportCertificateChain", true); 753 exportCertChain.addLongIdentifier("export-chain", true); 754 exportCertChain.addLongIdentifier("exportChain", true); 755 exportCertChain.addLongIdentifier("certificate-chain", true); 756 exportCertChain.addLongIdentifier("certificateChain", true); 757 exportCertChain.addLongIdentifier("chain", true); 758 exportCertParser.addArgument(exportCertChain); 759 760 final Set<String> exportCertOutputFormatAllowedValues = StaticUtils.setOf( 761 "PEM", "text", "txt", "RFC", "DER", "binary", "bin"); 762 final StringArgument exportCertOutputFormat = new StringArgument(null, 763 "output-format", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_FORMAT.get(), 764 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_FORMAT_DESC.get(), 765 exportCertOutputFormatAllowedValues, "PEM"); 766 exportCertOutputFormat.addLongIdentifier("outputFormat", true); 767 exportCertParser.addArgument(exportCertOutputFormat); 768 769 final FileArgument exportCertOutputFile = new FileArgument(null, 770 "output-file", false, 1, null, 771 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_FILE_DESC.get(), false, true, 772 true, false); 773 exportCertOutputFile.addLongIdentifier("outputFile", true); 774 exportCertOutputFile.addLongIdentifier("export-file", true); 775 exportCertOutputFile.addLongIdentifier("exportFile", true); 776 exportCertOutputFile.addLongIdentifier("certificate-file", true); 777 exportCertOutputFile.addLongIdentifier("certificateFile", true); 778 exportCertOutputFile.addLongIdentifier("file", true); 779 exportCertOutputFile.addLongIdentifier("filename", true); 780 exportCertParser.addArgument(exportCertOutputFile); 781 782 final BooleanArgument exportCertSeparateFile = new BooleanArgument(null, 783 "separate-file-per-certificate", 1, 784 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_SEPARATE_FILE_DESC.get()); 785 exportCertSeparateFile.addLongIdentifier("separateFilePerCertificate", 786 true); 787 exportCertSeparateFile.addLongIdentifier("separate-files", true); 788 exportCertSeparateFile.addLongIdentifier("separateFiles", true); 789 exportCertParser.addArgument(exportCertSeparateFile); 790 791 final BooleanArgument exportCertDisplayCommand = new BooleanArgument(null, 792 "display-keytool-command", 1, 793 INFO_MANAGE_CERTS_SC_EXPORT_CERT_ARG_DISPLAY_COMMAND_DESC.get()); 794 exportCertDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 795 exportCertDisplayCommand.addLongIdentifier("show-keytool-command", true); 796 exportCertDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 797 exportCertParser.addArgument(exportCertDisplayCommand); 798 799 exportCertParser.addExclusiveArgumentSet(exportCertKeystorePassword, 800 exportCertKeystorePasswordFile, exportCertPromptForKeystorePassword); 801 exportCertParser.addDependentArgumentSet(exportCertSeparateFile, 802 exportCertChain); 803 exportCertParser.addDependentArgumentSet(exportCertSeparateFile, 804 exportCertOutputFile); 805 806 final LinkedHashMap<String[],String> exportCertExamples = 807 new LinkedHashMap<>(StaticUtils.computeMapCapacity(2)); 808 exportCertExamples.put( 809 new String[] 810 { 811 "export-certificate", 812 "--keystore", getPlatformSpecificPath("config", "keystore"), 813 "--alias", "server-cert" 814 }, 815 INFO_MANAGE_CERTS_SC_EXPORT_CERT_EXAMPLE_1.get()); 816 exportCertExamples.put( 817 new String[] 818 { 819 "export-certificate", 820 "--keystore", getPlatformSpecificPath("config", "keystore.p12"), 821 "--keystore-password-file", 822 getPlatformSpecificPath("config", "keystore.pin"), 823 "--alias", "server-cert", 824 "--export-certificate-chain", 825 "--output-format", "DER", 826 "--output-file", "certificate-chain.der", 827 "--display-keytool-command" 828 }, 829 INFO_MANAGE_CERTS_SC_EXPORT_CERT_EXAMPLE_2.get()); 830 831 final SubCommand exportCertSubCommand = new SubCommand("export-certificate", 832 INFO_MANAGE_CERTS_SC_EXPORT_CERT_DESC.get(), exportCertParser, 833 exportCertExamples); 834 exportCertSubCommand.addName("exportCertificate", true); 835 exportCertSubCommand.addName("export-cert", true); 836 exportCertSubCommand.addName("exportCert", true); 837 exportCertSubCommand.addName("export", true); 838 839 parser.addSubCommand(exportCertSubCommand); 840 841 842 // Define the "export-private-key" subcommand and all of its arguments. 843 final ArgumentParser exportKeyParser = new ArgumentParser( 844 "export-private-key", INFO_MANAGE_CERTS_SC_EXPORT_KEY_DESC.get()); 845 846 final FileArgument exportKeyKeystore = new FileArgument(null, "keystore", 847 true, 1, null, INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_KS_DESC.get(), 848 true, true, true, false); 849 exportKeyKeystore.addLongIdentifier("keystore-path", true); 850 exportKeyKeystore.addLongIdentifier("keystorePath", true); 851 exportKeyKeystore.addLongIdentifier("keystore-file", true); 852 exportKeyKeystore.addLongIdentifier("keystoreFile", true); 853 exportKeyParser.addArgument(exportKeyKeystore); 854 855 final StringArgument exportKeyKeystorePassword = new StringArgument(null, 856 "keystore-password", false, 1, 857 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 858 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_KS_PW_DESC.get()); 859 exportKeyKeystorePassword.addLongIdentifier("keystorePassword", true); 860 exportKeyKeystorePassword.addLongIdentifier("keystore-passphrase", true); 861 exportKeyKeystorePassword.addLongIdentifier("keystorePassphrase", true); 862 exportKeyKeystorePassword.addLongIdentifier("keystore-pin", true); 863 exportKeyKeystorePassword.addLongIdentifier("keystorePIN", true); 864 exportKeyKeystorePassword.addLongIdentifier("storepass", true); 865 exportKeyKeystorePassword.setSensitive(true); 866 exportKeyParser.addArgument(exportKeyKeystorePassword); 867 868 final FileArgument exportKeyKeystorePasswordFile = new FileArgument(null, 869 "keystore-password-file", false, 1, null, 870 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_KS_PW_FILE_DESC.get(), true, true, 871 true, false); 872 exportKeyKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 873 true); 874 exportKeyKeystorePasswordFile.addLongIdentifier("keystore-passphrase-file", 875 true); 876 exportKeyKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 877 true); 878 exportKeyKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 879 true); 880 exportKeyKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 881 exportKeyParser.addArgument(exportKeyKeystorePasswordFile); 882 883 final BooleanArgument exportKeyPromptForKeystorePassword = 884 new BooleanArgument(null, "prompt-for-keystore-password", 885 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_PROMPT_FOR_KS_PW_DESC.get()); 886 exportKeyPromptForKeystorePassword.addLongIdentifier( 887 "promptForKeystorePassword", true); 888 exportKeyPromptForKeystorePassword.addLongIdentifier( 889 "prompt-for-keystore-passphrase", true); 890 exportKeyPromptForKeystorePassword.addLongIdentifier( 891 "promptForKeystorePassphrase", true); 892 exportKeyPromptForKeystorePassword.addLongIdentifier( 893 "prompt-for-keystore-pin", true); 894 exportKeyPromptForKeystorePassword.addLongIdentifier( 895 "promptForKeystorePIN", true); 896 exportKeyParser.addArgument(exportKeyPromptForKeystorePassword); 897 898 final StringArgument exportKeyPKPassword = new StringArgument(null, 899 "private-key-password", false, 1, 900 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 901 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_PK_PW_DESC.get()); 902 exportKeyPKPassword.addLongIdentifier("privateKeyPassword", true); 903 exportKeyPKPassword.addLongIdentifier("private-key-passphrase", true); 904 exportKeyPKPassword.addLongIdentifier("privateKeyPassphrase", true); 905 exportKeyPKPassword.addLongIdentifier("private-key-pin", true); 906 exportKeyPKPassword.addLongIdentifier("privateKeyPIN", true); 907 exportKeyPKPassword.addLongIdentifier("key-password", true); 908 exportKeyPKPassword.addLongIdentifier("keyPassword", true); 909 exportKeyPKPassword.addLongIdentifier("key-passphrase", true); 910 exportKeyPKPassword.addLongIdentifier("keyPassphrase", true); 911 exportKeyPKPassword.addLongIdentifier("key-pin", true); 912 exportKeyPKPassword.addLongIdentifier("keyPIN", true); 913 exportKeyPKPassword.addLongIdentifier("keypass", true); 914 exportKeyPKPassword.setSensitive(true); 915 exportKeyParser.addArgument(exportKeyPKPassword); 916 917 final FileArgument exportKeyPKPasswordFile = new FileArgument(null, 918 "private-key-password-file", false, 1, null, 919 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_PK_PW_FILE_DESC.get(), true, true, 920 true, false); 921 exportKeyPKPasswordFile.addLongIdentifier("privateKeyPasswordFile", true); 922 exportKeyPKPasswordFile.addLongIdentifier("private-key-passphrase-file", 923 true); 924 exportKeyPKPasswordFile.addLongIdentifier("privateKeyPassphraseFile", 925 true); 926 exportKeyPKPasswordFile.addLongIdentifier("private-key-pin-file", 927 true); 928 exportKeyPKPasswordFile.addLongIdentifier("privateKeyPINFile", true); 929 exportKeyPKPasswordFile.addLongIdentifier("key-password-file", true); 930 exportKeyPKPasswordFile.addLongIdentifier("keyPasswordFile", true); 931 exportKeyPKPasswordFile.addLongIdentifier("key-passphrase-file", 932 true); 933 exportKeyPKPasswordFile.addLongIdentifier("keyPassphraseFile", 934 true); 935 exportKeyPKPasswordFile.addLongIdentifier("key-pin-file", 936 true); 937 exportKeyPKPasswordFile.addLongIdentifier("keyPINFile", true); 938 exportKeyParser.addArgument(exportKeyPKPasswordFile); 939 940 final BooleanArgument exportKeyPromptForPKPassword = 941 new BooleanArgument(null, "prompt-for-private-key-password", 942 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_PROMPT_FOR_PK_PW_DESC.get()); 943 exportKeyPromptForPKPassword.addLongIdentifier( 944 "promptForPrivateKeyPassword", true); 945 exportKeyPromptForPKPassword.addLongIdentifier( 946 "prompt-for-private-key-passphrase", true); 947 exportKeyPromptForPKPassword.addLongIdentifier( 948 "promptForPrivateKeyPassphrase", true); 949 exportKeyPromptForPKPassword.addLongIdentifier("prompt-for-private-key-pin", 950 true); 951 exportKeyPromptForPKPassword.addLongIdentifier("promptForPrivateKeyPIN", 952 true); 953 exportKeyPromptForPKPassword.addLongIdentifier("prompt-for-key-password", 954 true); 955 exportKeyPromptForPKPassword.addLongIdentifier("promptForKeyPassword", 956 true); 957 exportKeyPromptForPKPassword.addLongIdentifier( 958 "prompt-for-key-passphrase", true); 959 exportKeyPromptForPKPassword.addLongIdentifier( 960 "promptForKeyPassphrase", true); 961 exportKeyPromptForPKPassword.addLongIdentifier("prompt-for-key-pin", true); 962 exportKeyPromptForPKPassword.addLongIdentifier("promptForKeyPIN", true); 963 exportKeyParser.addArgument(exportKeyPromptForPKPassword); 964 965 final StringArgument exportKeyKeystoreType = new StringArgument(null, 966 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 967 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_KS_TYPE_DESC.get(), 968 ALLOWED_KEYSTORE_TYPE_VALUES); 969 exportKeyKeystoreType.addLongIdentifier("key-store-type", true); 970 exportKeyKeystoreType.addLongIdentifier("keystoreType", true); 971 exportKeyKeystoreType.addLongIdentifier("keystore-format", true); 972 exportKeyKeystoreType.addLongIdentifier("key-store-format", true); 973 exportKeyKeystoreType.addLongIdentifier("keystoreFormat", true); 974 exportKeyKeystoreType.addLongIdentifier("storetype", true); 975 exportKeyParser.addArgument(exportKeyKeystoreType); 976 977 final StringArgument exportKeyAlias = new StringArgument(null, "alias", 978 true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 979 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_ALIAS_DESC.get()); 980 exportKeyAlias.addLongIdentifier("nickname", true); 981 exportKeyParser.addArgument(exportKeyAlias); 982 983 final Set<String> exportKeyOutputFormatAllowedValues = StaticUtils.setOf( 984 "PEM", "text", "txt", "RFC", "DER", "binary", "bin"); 985 final StringArgument exportKeyOutputFormat = new StringArgument(null, 986 "output-format", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_FORMAT.get(), 987 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_FORMAT_DESC.get(), 988 exportKeyOutputFormatAllowedValues, "PEM"); 989 exportKeyOutputFormat.addLongIdentifier("outputFormat", true); 990 exportKeyParser.addArgument(exportKeyOutputFormat); 991 992 final FileArgument exportKeyOutputFile = new FileArgument(null, 993 "output-file", false, 1, null, 994 INFO_MANAGE_CERTS_SC_EXPORT_KEY_ARG_FILE_DESC.get(), false, true, 995 true, false); 996 exportKeyOutputFile.addLongIdentifier("outputFile", true); 997 exportKeyOutputFile.addLongIdentifier("export-file", true); 998 exportKeyOutputFile.addLongIdentifier("exportFile", true); 999 exportKeyOutputFile.addLongIdentifier("private-key-file", true); 1000 exportKeyOutputFile.addLongIdentifier("privateKeyFile", true); 1001 exportKeyOutputFile.addLongIdentifier("key-file", true); 1002 exportKeyOutputFile.addLongIdentifier("keyFile", true); 1003 exportKeyOutputFile.addLongIdentifier("file", true); 1004 exportKeyOutputFile.addLongIdentifier("filename", true); 1005 exportKeyParser.addArgument(exportKeyOutputFile); 1006 1007 exportKeyParser.addRequiredArgumentSet(exportKeyKeystorePassword, 1008 exportKeyKeystorePasswordFile, exportKeyPromptForKeystorePassword); 1009 exportKeyParser.addExclusiveArgumentSet(exportKeyKeystorePassword, 1010 exportKeyKeystorePasswordFile, exportKeyPromptForKeystorePassword); 1011 exportKeyParser.addExclusiveArgumentSet(exportKeyPKPassword, 1012 exportKeyPKPasswordFile, exportKeyPromptForPKPassword); 1013 1014 final LinkedHashMap<String[],String> exportKeyExamples = 1015 new LinkedHashMap<>(StaticUtils.computeMapCapacity(2)); 1016 exportKeyExamples.put( 1017 new String[] 1018 { 1019 "export-private-key", 1020 "--keystore", getPlatformSpecificPath("config", "keystore"), 1021 "--keystore-password-file", 1022 getPlatformSpecificPath("config", "keystore.pin"), 1023 "--alias", "server-cert" 1024 }, 1025 INFO_MANAGE_CERTS_SC_EXPORT_KEY_EXAMPLE_1.get()); 1026 exportKeyExamples.put( 1027 new String[] 1028 { 1029 "export-private-key", 1030 "--keystore", getPlatformSpecificPath("config", "keystore.p12"), 1031 "--keystore-password-file", 1032 getPlatformSpecificPath("config", "keystore.pin"), 1033 "--private-key-password-file", 1034 getPlatformSpecificPath("config", "server-cert-key.pin"), 1035 "--alias", "server-cert", 1036 "--output-format", "DER", 1037 "--output-file", "server-cert-key.der" 1038 }, 1039 INFO_MANAGE_CERTS_SC_EXPORT_KEY_EXAMPLE_2.get()); 1040 1041 final SubCommand exportKeySubCommand = new SubCommand("export-private-key", 1042 INFO_MANAGE_CERTS_SC_EXPORT_CERT_DESC.get(), exportKeyParser, 1043 exportKeyExamples); 1044 exportKeySubCommand.addName("exportPrivateKey", true); 1045 exportKeySubCommand.addName("export-key", true); 1046 exportKeySubCommand.addName("exportKey", true); 1047 1048 parser.addSubCommand(exportKeySubCommand); 1049 1050 1051 // Define the "import-certificate" subcommand and all of its arguments. 1052 final ArgumentParser importCertParser = new ArgumentParser( 1053 "import-certificate", INFO_MANAGE_CERTS_SC_IMPORT_CERT_DESC.get()); 1054 1055 final FileArgument importCertKeystore = new FileArgument(null, "keystore", 1056 true, 1, null, INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_KS_DESC.get(), 1057 false, true, true, false); 1058 importCertKeystore.addLongIdentifier("keystore-path", true); 1059 importCertKeystore.addLongIdentifier("keystorePath", true); 1060 importCertKeystore.addLongIdentifier("keystore-file", true); 1061 importCertKeystore.addLongIdentifier("keystoreFile", true); 1062 importCertParser.addArgument(importCertKeystore); 1063 1064 final StringArgument importCertKeystorePassword = new StringArgument(null, 1065 "keystore-password", false, 1, 1066 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 1067 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_KS_PW_DESC.get()); 1068 importCertKeystorePassword.addLongIdentifier("keystorePassword", true); 1069 importCertKeystorePassword.addLongIdentifier("keystore-passphrase", true); 1070 importCertKeystorePassword.addLongIdentifier("keystorePassphrase", true); 1071 importCertKeystorePassword.addLongIdentifier("keystore-pin", true); 1072 importCertKeystorePassword.addLongIdentifier("keystorePIN", true); 1073 importCertKeystorePassword.addLongIdentifier("storepass", true); 1074 importCertKeystorePassword.setSensitive(true); 1075 importCertParser.addArgument(importCertKeystorePassword); 1076 1077 final FileArgument importCertKeystorePasswordFile = new FileArgument(null, 1078 "keystore-password-file", false, 1, null, 1079 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_KS_PW_FILE_DESC.get(), true, true, 1080 true, false); 1081 importCertKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 1082 true); 1083 importCertKeystorePasswordFile.addLongIdentifier("keystore-passphrase-file", 1084 true); 1085 importCertKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 1086 true); 1087 importCertKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 1088 true); 1089 importCertKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 1090 importCertParser.addArgument(importCertKeystorePasswordFile); 1091 1092 final BooleanArgument importCertPromptForKeystorePassword = 1093 new BooleanArgument(null, "prompt-for-keystore-password", 1094 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_PROMPT_FOR_KS_PW_DESC.get()); 1095 importCertPromptForKeystorePassword.addLongIdentifier( 1096 "promptForKeystorePassword", true); 1097 importCertPromptForKeystorePassword.addLongIdentifier( 1098 "prompt-for-keystore-passphrase", true); 1099 importCertPromptForKeystorePassword.addLongIdentifier( 1100 "promptForKeystorePassphrase", true); 1101 importCertPromptForKeystorePassword.addLongIdentifier( 1102 "prompt-for-keystore-pin", true); 1103 importCertPromptForKeystorePassword.addLongIdentifier( 1104 "promptForKeystorePIN", true); 1105 importCertParser.addArgument(importCertPromptForKeystorePassword); 1106 1107 final StringArgument importCertKeystoreType = new StringArgument(null, 1108 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 1109 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_KS_TYPE_DESC.get(), 1110 ALLOWED_KEYSTORE_TYPE_VALUES); 1111 importCertKeystoreType.addLongIdentifier("key-store-type", true); 1112 importCertKeystoreType.addLongIdentifier("keystoreType", true); 1113 importCertKeystoreType.addLongIdentifier("keystore-format", true); 1114 importCertKeystoreType.addLongIdentifier("key-store-format", true); 1115 importCertKeystoreType.addLongIdentifier("keystoreFormat", true); 1116 importCertKeystoreType.addLongIdentifier("storetype", true); 1117 importCertParser.addArgument(importCertKeystoreType); 1118 1119 final StringArgument importCertAlias = new StringArgument(null, "alias", 1120 true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 1121 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_ALIAS_DESC.get()); 1122 importCertAlias.addLongIdentifier("nickname", true); 1123 importCertParser.addArgument(importCertAlias); 1124 1125 final FileArgument importCertCertificateFile = new FileArgument(null, 1126 "certificate-file", true, 0, null, 1127 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_CERT_FILE_DESC.get(), true, true, 1128 true, false); 1129 importCertCertificateFile.addLongIdentifier("certificateFile", true); 1130 importCertCertificateFile.addLongIdentifier("certificate-chain-file", true); 1131 importCertCertificateFile.addLongIdentifier("certificateChainFile", true); 1132 importCertCertificateFile.addLongIdentifier("input-file", true); 1133 importCertCertificateFile.addLongIdentifier("inputFile", true); 1134 importCertCertificateFile.addLongIdentifier("import-file", true); 1135 importCertCertificateFile.addLongIdentifier("importFile", true); 1136 importCertCertificateFile.addLongIdentifier("file", true); 1137 importCertCertificateFile.addLongIdentifier("filename", true); 1138 importCertParser.addArgument(importCertCertificateFile); 1139 1140 final FileArgument importCertPKFile = new FileArgument(null, 1141 "private-key-file", false, 1, null, 1142 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_KEY_FILE_DESC.get(), true, true, 1143 true, false); 1144 importCertPKFile.addLongIdentifier("privateKeyFile", true); 1145 importCertPKFile.addLongIdentifier("key-file", true); 1146 importCertPKFile.addLongIdentifier("keyFile", true); 1147 importCertParser.addArgument(importCertPKFile); 1148 1149 final StringArgument importCertPKPassword = new StringArgument(null, 1150 "private-key-password", false, 1, 1151 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 1152 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_PK_PW_DESC.get()); 1153 importCertPKPassword.addLongIdentifier("privateKeyPassword", true); 1154 importCertPKPassword.addLongIdentifier("private-key-passphrase", true); 1155 importCertPKPassword.addLongIdentifier("privateKeyPassphrase", true); 1156 importCertPKPassword.addLongIdentifier("private-key-pin", true); 1157 importCertPKPassword.addLongIdentifier("privateKeyPIN", true); 1158 importCertPKPassword.addLongIdentifier("key-password", true); 1159 importCertPKPassword.addLongIdentifier("keyPassword", true); 1160 importCertPKPassword.addLongIdentifier("key-passphrase", true); 1161 importCertPKPassword.addLongIdentifier("keyPassphrase", true); 1162 importCertPKPassword.addLongIdentifier("key-pin", true); 1163 importCertPKPassword.addLongIdentifier("keyPIN", true); 1164 importCertPKPassword.addLongIdentifier("keypass", true); 1165 importCertPKPassword.setSensitive(true); 1166 importCertParser.addArgument(importCertPKPassword); 1167 1168 final FileArgument importCertPKPasswordFile = new FileArgument(null, 1169 "private-key-password-file", false, 1, null, 1170 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_PK_PW_FILE_DESC.get(), true, true, 1171 true, false); 1172 importCertPKPasswordFile.addLongIdentifier("privateKeyPasswordFile", true); 1173 importCertPKPasswordFile.addLongIdentifier("private-key-passphrase-file", 1174 true); 1175 importCertPKPasswordFile.addLongIdentifier("privateKeyPassphraseFile", 1176 true); 1177 importCertPKPasswordFile.addLongIdentifier("private-key-pin-file", 1178 true); 1179 importCertPKPasswordFile.addLongIdentifier("privateKeyPINFile", true); 1180 importCertPKPasswordFile.addLongIdentifier("key-password-file", true); 1181 importCertPKPasswordFile.addLongIdentifier("keyPasswordFile", true); 1182 importCertPKPasswordFile.addLongIdentifier("key-passphrase-file", 1183 true); 1184 importCertPKPasswordFile.addLongIdentifier("keyPassphraseFile", 1185 true); 1186 importCertPKPasswordFile.addLongIdentifier("key-pin-file", 1187 true); 1188 importCertPKPasswordFile.addLongIdentifier("keyPINFile", true); 1189 importCertParser.addArgument(importCertPKPasswordFile); 1190 1191 final BooleanArgument importCertPromptForPKPassword = 1192 new BooleanArgument(null, "prompt-for-private-key-password", 1193 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_PROMPT_FOR_PK_PW_DESC.get()); 1194 importCertPromptForPKPassword.addLongIdentifier( 1195 "promptForPrivateKeyPassword", true); 1196 importCertPromptForPKPassword.addLongIdentifier( 1197 "prompt-for-private-key-passphrase", true); 1198 importCertPromptForPKPassword.addLongIdentifier( 1199 "promptForPrivateKeyPassphrase", true); 1200 importCertPromptForPKPassword.addLongIdentifier( 1201 "prompt-for-private-key-pin", true); 1202 importCertPromptForPKPassword.addLongIdentifier("promptForPrivateKeyPIN", 1203 true); 1204 importCertPromptForPKPassword.addLongIdentifier("prompt-for-key-password", 1205 true); 1206 importCertPromptForPKPassword.addLongIdentifier("promptForKeyPassword", 1207 true); 1208 importCertPromptForPKPassword.addLongIdentifier( 1209 "prompt-for-key-passphrase", true); 1210 importCertPromptForPKPassword.addLongIdentifier( 1211 "promptForKeyPassphrase", true); 1212 importCertPromptForPKPassword.addLongIdentifier("prompt-for-key-pin", true); 1213 importCertPromptForPKPassword.addLongIdentifier("promptForKeyPIN", true); 1214 importCertParser.addArgument(importCertPromptForPKPassword); 1215 1216 final BooleanArgument importCertNoPrompt = new BooleanArgument(null, 1217 "no-prompt", 1, 1218 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_NO_PROMPT_DESC.get()); 1219 importCertNoPrompt.addLongIdentifier("noPrompt", true); 1220 importCertParser.addArgument(importCertNoPrompt); 1221 1222 final BooleanArgument importCertDisplayCommand = new BooleanArgument(null, 1223 "display-keytool-command", 1, 1224 INFO_MANAGE_CERTS_SC_IMPORT_CERT_ARG_DISPLAY_COMMAND_DESC.get()); 1225 importCertDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 1226 importCertDisplayCommand.addLongIdentifier("show-keytool-command", true); 1227 importCertDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 1228 importCertParser.addArgument(importCertDisplayCommand); 1229 1230 importCertParser.addRequiredArgumentSet(importCertKeystorePassword, 1231 importCertKeystorePasswordFile, importCertPromptForKeystorePassword); 1232 importCertParser.addExclusiveArgumentSet(importCertKeystorePassword, 1233 importCertKeystorePasswordFile, importCertPromptForKeystorePassword); 1234 importCertParser.addExclusiveArgumentSet(importCertPKPassword, 1235 importCertPKPasswordFile, importCertPromptForPKPassword); 1236 1237 final LinkedHashMap<String[],String> importCertExamples = 1238 new LinkedHashMap<>(StaticUtils.computeMapCapacity(2)); 1239 importCertExamples.put( 1240 new String[] 1241 { 1242 "import-certificate", 1243 "--keystore", getPlatformSpecificPath("config", "keystore"), 1244 "--keystore-password-file", 1245 getPlatformSpecificPath("config", "keystore.pin"), 1246 "--alias", "server-cert", 1247 "--certificate-file", "server-cert.crt" 1248 }, 1249 INFO_MANAGE_CERTS_SC_IMPORT_CERT_EXAMPLE_1.get("server-cert.crt")); 1250 importCertExamples.put( 1251 new String[] 1252 { 1253 "import-certificate", 1254 "--keystore", getPlatformSpecificPath("config", "keystore"), 1255 "--keystore-password-file", 1256 getPlatformSpecificPath("config", "keystore.pin"), 1257 "--alias", "server-cert", 1258 "--certificate-file", "server-cert.crt", 1259 "--certificate-file", "server-cert-issuer.crt", 1260 "--private-key-file", "server-cert.key", 1261 "--display-keytool-command" 1262 }, 1263 INFO_MANAGE_CERTS_SC_IMPORT_CERT_EXAMPLE_2.get()); 1264 1265 final SubCommand importCertSubCommand = new SubCommand("import-certificate", 1266 INFO_MANAGE_CERTS_SC_IMPORT_CERT_DESC.get(), importCertParser, 1267 importCertExamples); 1268 importCertSubCommand.addName("importCertificate", true); 1269 importCertSubCommand.addName("import-certificates", true); 1270 importCertSubCommand.addName("importCertificates", true); 1271 importCertSubCommand.addName("import-cert", true); 1272 importCertSubCommand.addName("importCert", true); 1273 importCertSubCommand.addName("import-certs", true); 1274 importCertSubCommand.addName("importCerts", true); 1275 importCertSubCommand.addName("import-certificate-chain", true); 1276 importCertSubCommand.addName("importCertificateChain", true); 1277 importCertSubCommand.addName("import-chain", true); 1278 importCertSubCommand.addName("importChain", true); 1279 importCertSubCommand.addName("import", true); 1280 1281 parser.addSubCommand(importCertSubCommand); 1282 1283 1284 // Define the "delete-certificate" subcommand and all of its arguments. 1285 final ArgumentParser deleteCertParser = new ArgumentParser( 1286 "delete-certificate", INFO_MANAGE_CERTS_SC_DELETE_CERT_DESC.get()); 1287 1288 final FileArgument deleteCertKeystore = new FileArgument(null, "keystore", 1289 true, 1, null, INFO_MANAGE_CERTS_SC_DELETE_CERT_ARG_KS_DESC.get(), 1290 true, true, true, false); 1291 deleteCertKeystore.addLongIdentifier("keystore-path", true); 1292 deleteCertKeystore.addLongIdentifier("keystorePath", true); 1293 deleteCertKeystore.addLongIdentifier("keystore-file", true); 1294 deleteCertKeystore.addLongIdentifier("keystoreFile", true); 1295 deleteCertParser.addArgument(deleteCertKeystore); 1296 1297 final StringArgument deleteCertKeystorePassword = new StringArgument(null, 1298 "keystore-password", false, 1, 1299 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 1300 INFO_MANAGE_CERTS_SC_DELETE_CERT_ARG_KS_PW_DESC.get()); 1301 deleteCertKeystorePassword.addLongIdentifier("keystorePassword", true); 1302 deleteCertKeystorePassword.addLongIdentifier("keystore-passphrase", true); 1303 deleteCertKeystorePassword.addLongIdentifier("keystorePassphrase", true); 1304 deleteCertKeystorePassword.addLongIdentifier("keystore-pin", true); 1305 deleteCertKeystorePassword.addLongIdentifier("keystorePIN", true); 1306 deleteCertKeystorePassword.addLongIdentifier("storepass", true); 1307 deleteCertKeystorePassword.setSensitive(true); 1308 deleteCertParser.addArgument(deleteCertKeystorePassword); 1309 1310 final FileArgument deleteCertKeystorePasswordFile = new FileArgument(null, 1311 "keystore-password-file", false, 1, null, 1312 INFO_MANAGE_CERTS_SC_DELETE_CERT_ARG_KS_PW_FILE_DESC.get(), true, true, 1313 true, false); 1314 deleteCertKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 1315 true); 1316 deleteCertKeystorePasswordFile.addLongIdentifier("keystore-passphrase-file", 1317 true); 1318 deleteCertKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 1319 true); 1320 deleteCertKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 1321 true); 1322 deleteCertKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 1323 deleteCertParser.addArgument(deleteCertKeystorePasswordFile); 1324 1325 final BooleanArgument deleteCertPromptForKeystorePassword = 1326 new BooleanArgument(null, "prompt-for-keystore-password", 1327 INFO_MANAGE_CERTS_SC_DELETE_CERT_ARG_PROMPT_FOR_KS_PW_DESC.get()); 1328 deleteCertPromptForKeystorePassword.addLongIdentifier( 1329 "promptForKeystorePassword", true); 1330 deleteCertPromptForKeystorePassword.addLongIdentifier( 1331 "prompt-for-keystore-passphrase", true); 1332 deleteCertPromptForKeystorePassword.addLongIdentifier( 1333 "promptForKeystorePassphrase", true); 1334 deleteCertPromptForKeystorePassword.addLongIdentifier( 1335 "prompt-for-keystore-pin", true); 1336 deleteCertPromptForKeystorePassword.addLongIdentifier( 1337 "promptForKeystorePIN", true); 1338 deleteCertParser.addArgument(deleteCertPromptForKeystorePassword); 1339 1340 final StringArgument deleteCertKeystoreType = new StringArgument(null, 1341 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 1342 INFO_MANAGE_CERTS_SC_DELETE_CERT_ARG_KS_TYPE_DESC.get(), 1343 ALLOWED_KEYSTORE_TYPE_VALUES); 1344 deleteCertKeystoreType.addLongIdentifier("key-store-type", true); 1345 deleteCertKeystoreType.addLongIdentifier("keystoreType", true); 1346 deleteCertKeystoreType.addLongIdentifier("keystore-format", true); 1347 deleteCertKeystoreType.addLongIdentifier("key-store-format", true); 1348 deleteCertKeystoreType.addLongIdentifier("keystoreFormat", true); 1349 deleteCertKeystoreType.addLongIdentifier("storetype", true); 1350 deleteCertParser.addArgument(deleteCertKeystoreType); 1351 1352 final StringArgument deleteCertAlias = new StringArgument(null, "alias", 1353 true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 1354 INFO_MANAGE_CERTS_SC_DELETE_CERT_ARG_ALIAS_DESC.get()); 1355 deleteCertAlias.addLongIdentifier("nickname", true); 1356 deleteCertParser.addArgument(deleteCertAlias); 1357 1358 final BooleanArgument deleteCertNoPrompt = new BooleanArgument(null, 1359 "no-prompt", 1, 1360 INFO_MANAGE_CERTS_SC_DELETE_CERT_ARG_NO_PROMPT_DESC.get()); 1361 deleteCertNoPrompt.addLongIdentifier("noPrompt", true); 1362 deleteCertParser.addArgument(deleteCertNoPrompt); 1363 1364 final BooleanArgument deleteCertDisplayCommand = new BooleanArgument(null, 1365 "display-keytool-command", 1, 1366 INFO_MANAGE_CERTS_SC_DELETE_CERT_ARG_DISPLAY_COMMAND_DESC.get()); 1367 deleteCertDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 1368 deleteCertDisplayCommand.addLongIdentifier("show-keytool-command", true); 1369 deleteCertDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 1370 deleteCertParser.addArgument(deleteCertDisplayCommand); 1371 1372 deleteCertParser.addExclusiveArgumentSet(deleteCertKeystorePassword, 1373 deleteCertKeystorePasswordFile, deleteCertPromptForKeystorePassword); 1374 deleteCertParser.addRequiredArgumentSet(deleteCertKeystorePassword, 1375 deleteCertKeystorePasswordFile, deleteCertPromptForKeystorePassword); 1376 1377 final LinkedHashMap<String[],String> deleteCertExamples = 1378 new LinkedHashMap<>(StaticUtils.computeMapCapacity(1)); 1379 deleteCertExamples.put( 1380 new String[] 1381 { 1382 "delete-certificate", 1383 "--keystore", getPlatformSpecificPath("config", "keystore"), 1384 "--alias", "server-cert" 1385 }, 1386 INFO_MANAGE_CERTS_SC_DELETE_CERT_EXAMPLE_1.get( 1387 getPlatformSpecificPath("config", "keystore"))); 1388 1389 final SubCommand deleteCertSubCommand = new SubCommand("delete-certificate", 1390 INFO_MANAGE_CERTS_SC_DELETE_CERT_DESC.get(), deleteCertParser, 1391 deleteCertExamples); 1392 deleteCertSubCommand.addName("deleteCertificate", true); 1393 deleteCertSubCommand.addName("remove-certificate", true); 1394 deleteCertSubCommand.addName("removeCertificate", true); 1395 deleteCertSubCommand.addName("delete", true); 1396 deleteCertSubCommand.addName("remove", true); 1397 1398 parser.addSubCommand(deleteCertSubCommand); 1399 1400 1401 // Define the "generate-self-signed-certificate" subcommand and all of its 1402 // arguments. 1403 final ArgumentParser genCertParser = new ArgumentParser( 1404 "generate-self-signed-certificate", 1405 INFO_MANAGE_CERTS_SC_GEN_CERT_DESC.get()); 1406 1407 final FileArgument genCertKeystore = new FileArgument(null, "keystore", 1408 true, 1, null, INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_KS_DESC.get(), false, 1409 true, true, false); 1410 genCertKeystore.addLongIdentifier("keystore-path", true); 1411 genCertKeystore.addLongIdentifier("keystorePath", true); 1412 genCertKeystore.addLongIdentifier("keystore-file", true); 1413 genCertKeystore.addLongIdentifier("keystoreFile", true); 1414 genCertParser.addArgument(genCertKeystore); 1415 1416 final StringArgument genCertKeystorePassword = new StringArgument(null, 1417 "keystore-password", false, 1, 1418 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 1419 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_KS_PW_DESC.get()); 1420 genCertKeystorePassword.addLongIdentifier("keystorePassword", true); 1421 genCertKeystorePassword.addLongIdentifier("keystore-passphrase", true); 1422 genCertKeystorePassword.addLongIdentifier("keystorePassphrase", true); 1423 genCertKeystorePassword.addLongIdentifier("keystore-pin", true); 1424 genCertKeystorePassword.addLongIdentifier("keystorePIN", true); 1425 genCertKeystorePassword.addLongIdentifier("storepass", true); 1426 genCertKeystorePassword.setSensitive(true); 1427 genCertParser.addArgument(genCertKeystorePassword); 1428 1429 final FileArgument genCertKeystorePasswordFile = new FileArgument(null, 1430 "keystore-password-file", false, 1, null, 1431 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_KS_PW_FILE_DESC.get(), true, true, 1432 true, false); 1433 genCertKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 1434 true); 1435 genCertKeystorePasswordFile.addLongIdentifier("keystore-passphrase-file", 1436 true); 1437 genCertKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 1438 true); 1439 genCertKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 1440 true); 1441 genCertKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 1442 genCertParser.addArgument(genCertKeystorePasswordFile); 1443 1444 final BooleanArgument genCertPromptForKeystorePassword = 1445 new BooleanArgument(null, "prompt-for-keystore-password", 1446 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_PROMPT_FOR_KS_PW_DESC.get()); 1447 genCertPromptForKeystorePassword.addLongIdentifier( 1448 "promptForKeystorePassword", true); 1449 genCertPromptForKeystorePassword.addLongIdentifier( 1450 "prompt-for-keystore-passphrase", true); 1451 genCertPromptForKeystorePassword.addLongIdentifier( 1452 "promptForKeystorePassphrase", true); 1453 genCertPromptForKeystorePassword.addLongIdentifier( 1454 "prompt-for-keystore-pin", true); 1455 genCertPromptForKeystorePassword.addLongIdentifier( 1456 "promptForKeystorePIN", true); 1457 genCertParser.addArgument(genCertPromptForKeystorePassword); 1458 1459 final StringArgument genCertPKPassword = new StringArgument(null, 1460 "private-key-password", false, 1, 1461 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 1462 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_PK_PW_DESC.get()); 1463 genCertPKPassword.addLongIdentifier("privateKeyPassword", true); 1464 genCertPKPassword.addLongIdentifier("private-key-passphrase", true); 1465 genCertPKPassword.addLongIdentifier("privateKeyPassphrase", true); 1466 genCertPKPassword.addLongIdentifier("private-key-pin", true); 1467 genCertPKPassword.addLongIdentifier("privateKeyPIN", true); 1468 genCertPKPassword.addLongIdentifier("key-password", true); 1469 genCertPKPassword.addLongIdentifier("keyPassword", true); 1470 genCertPKPassword.addLongIdentifier("key-passphrase", true); 1471 genCertPKPassword.addLongIdentifier("keyPassphrase", true); 1472 genCertPKPassword.addLongIdentifier("key-pin", true); 1473 genCertPKPassword.addLongIdentifier("keyPIN", true); 1474 genCertPKPassword.addLongIdentifier("keypass", true); 1475 genCertPKPassword.setSensitive(true); 1476 genCertParser.addArgument(genCertPKPassword); 1477 1478 final FileArgument genCertPKPasswordFile = new FileArgument(null, 1479 "private-key-password-file", false, 1, null, 1480 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_PK_PW_FILE_DESC.get(), true, true, 1481 true, false); 1482 genCertPKPasswordFile.addLongIdentifier("privateKeyPasswordFile", true); 1483 genCertPKPasswordFile.addLongIdentifier("private-key-passphrase-file", 1484 true); 1485 genCertPKPasswordFile.addLongIdentifier("privateKeyPassphraseFile", 1486 true); 1487 genCertPKPasswordFile.addLongIdentifier("private-key-pin-file", 1488 true); 1489 genCertPKPasswordFile.addLongIdentifier("privateKeyPINFile", true); 1490 genCertPKPasswordFile.addLongIdentifier("key-password-file", true); 1491 genCertPKPasswordFile.addLongIdentifier("keyPasswordFile", true); 1492 genCertPKPasswordFile.addLongIdentifier("key-passphrase-file", 1493 true); 1494 genCertPKPasswordFile.addLongIdentifier("keyPassphraseFile", 1495 true); 1496 genCertPKPasswordFile.addLongIdentifier("key-pin-file", 1497 true); 1498 genCertPKPasswordFile.addLongIdentifier("keyPINFile", true); 1499 genCertParser.addArgument(genCertPKPasswordFile); 1500 1501 final BooleanArgument genCertPromptForPKPassword = 1502 new BooleanArgument(null, "prompt-for-private-key-password", 1503 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_PROMPT_FOR_PK_PW_DESC.get()); 1504 genCertPromptForPKPassword.addLongIdentifier( 1505 "promptForPrivateKeyPassword", true); 1506 genCertPromptForPKPassword.addLongIdentifier( 1507 "prompt-for-private-key-passphrase", true); 1508 genCertPromptForPKPassword.addLongIdentifier( 1509 "promptForPrivateKeyPassphrase", true); 1510 genCertPromptForPKPassword.addLongIdentifier("prompt-for-private-key-pin", 1511 true); 1512 genCertPromptForPKPassword.addLongIdentifier("promptForPrivateKeyPIN", 1513 true); 1514 genCertPromptForPKPassword.addLongIdentifier("prompt-for-key-password", 1515 true); 1516 genCertPromptForPKPassword.addLongIdentifier("promptForKeyPassword", 1517 true); 1518 genCertPromptForPKPassword.addLongIdentifier( 1519 "prompt-for-key-passphrase", true); 1520 genCertPromptForPKPassword.addLongIdentifier( 1521 "promptForKeyPassphrase", true); 1522 genCertPromptForPKPassword.addLongIdentifier("prompt-for-key-pin", true); 1523 genCertPromptForPKPassword.addLongIdentifier("promptForKeyPIN", true); 1524 genCertParser.addArgument(genCertPromptForPKPassword); 1525 1526 final StringArgument genCertKeystoreType = new StringArgument(null, 1527 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 1528 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_KS_TYPE_DESC.get(), 1529 ALLOWED_KEYSTORE_TYPE_VALUES); 1530 genCertKeystoreType.addLongIdentifier("key-store-type", true); 1531 genCertKeystoreType.addLongIdentifier("keystoreType", true); 1532 genCertKeystoreType.addLongIdentifier("keystore-format", true); 1533 genCertKeystoreType.addLongIdentifier("key-store-format", true); 1534 genCertKeystoreType.addLongIdentifier("keystoreFormat", true); 1535 genCertKeystoreType.addLongIdentifier("storetype", true); 1536 genCertParser.addArgument(genCertKeystoreType); 1537 1538 final StringArgument genCertAlias = new StringArgument(null, "alias", 1539 true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 1540 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_ALIAS_DESC.get()); 1541 genCertAlias.addLongIdentifier("nickname", true); 1542 genCertParser.addArgument(genCertAlias); 1543 1544 final BooleanArgument genCertReplace = new BooleanArgument(null, 1545 "replace-existing-certificate", 1, 1546 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_REPLACE_DESC.get()); 1547 genCertReplace.addLongIdentifier("replaceExistingCertificate", true); 1548 genCertReplace.addLongIdentifier("replace-certificate", true); 1549 genCertReplace.addLongIdentifier("replaceCertificate", true); 1550 genCertReplace.addLongIdentifier("replace-existing", true); 1551 genCertReplace.addLongIdentifier("replaceExisting", true); 1552 genCertReplace.addLongIdentifier("replace", true); 1553 genCertReplace.addLongIdentifier("use-existing-key-pair", true); 1554 genCertReplace.addLongIdentifier("use-existing-keypair", true); 1555 genCertReplace.addLongIdentifier("useExistingKeypair", true); 1556 genCertParser.addArgument(genCertReplace); 1557 1558 final DNArgument genCertSubjectDN = new DNArgument(null, "subject-dn", 1559 false, 1, null, 1560 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_SUBJECT_DN_DESC.get()); 1561 genCertSubjectDN.addLongIdentifier("subjectDN", true); 1562 genCertSubjectDN.addLongIdentifier("subject", true); 1563 genCertSubjectDN.addLongIdentifier("dname", true); 1564 genCertParser.addArgument(genCertSubjectDN); 1565 1566 final IntegerArgument genCertDaysValid = new IntegerArgument(null, 1567 "days-valid", false, 1, null, 1568 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_DAYS_VALID_DESC.get(), 1, 1569 Integer.MAX_VALUE); 1570 genCertDaysValid.addLongIdentifier("daysValid", true); 1571 genCertDaysValid.addLongIdentifier("validity", true); 1572 genCertParser.addArgument(genCertDaysValid); 1573 1574 final TimestampArgument genCertNotBefore = new TimestampArgument(null, 1575 "validity-start-time", false, 1, 1576 INFO_MANAGE_CERTS_PLACEHOLDER_TIMESTAMP.get(), 1577 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_VALIDITY_START_TIME_DESC.get( 1578 "20180102123456")); 1579 genCertNotBefore.addLongIdentifier("validityStartTime", true); 1580 genCertNotBefore.addLongIdentifier("not-before", true); 1581 genCertNotBefore.addLongIdentifier("notBefore", true); 1582 genCertParser.addArgument(genCertNotBefore); 1583 1584 final StringArgument genCertKeyAlgorithm = new StringArgument(null, 1585 "key-algorithm", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 1586 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_KEY_ALGORITHM_DESC.get()); 1587 genCertKeyAlgorithm.addLongIdentifier("keyAlgorithm", true); 1588 genCertKeyAlgorithm.addLongIdentifier("key-alg", true); 1589 genCertKeyAlgorithm.addLongIdentifier("keyAlg", true); 1590 genCertParser.addArgument(genCertKeyAlgorithm); 1591 1592 final IntegerArgument genCertKeySizeBits = new IntegerArgument(null, 1593 "key-size-bits", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_BITS.get(), 1594 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_KEY_SIZE_BITS_DESC.get(), 1, 1595 Integer.MAX_VALUE); 1596 genCertKeySizeBits.addLongIdentifier("keySizeBits", true); 1597 genCertKeySizeBits.addLongIdentifier("key-length-bits", true); 1598 genCertKeySizeBits.addLongIdentifier("keyLengthBits", true); 1599 genCertKeySizeBits.addLongIdentifier("key-size", true); 1600 genCertKeySizeBits.addLongIdentifier("keySize", true); 1601 genCertKeySizeBits.addLongIdentifier("key-length", true); 1602 genCertKeySizeBits.addLongIdentifier("keyLength", true); 1603 genCertParser.addArgument(genCertKeySizeBits); 1604 1605 final StringArgument genCertSignatureAlgorithm = new StringArgument(null, 1606 "signature-algorithm", false, 1, 1607 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 1608 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_SIG_ALG_DESC.get()); 1609 genCertSignatureAlgorithm.addLongIdentifier("signatureAlgorithm", true); 1610 genCertSignatureAlgorithm.addLongIdentifier("signature-alg", true); 1611 genCertSignatureAlgorithm.addLongIdentifier("signatureAlg", true); 1612 genCertSignatureAlgorithm.addLongIdentifier("sig-alg", true); 1613 genCertSignatureAlgorithm.addLongIdentifier("sigAlg", true); 1614 genCertParser.addArgument(genCertSignatureAlgorithm); 1615 1616 final BooleanArgument genCertInheritExtensions = new BooleanArgument(null, 1617 "inherit-extensions", 1, 1618 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_INHERIT_EXT_DESC.get()); 1619 genCertInheritExtensions.addLongIdentifier("inheritExtensions", true); 1620 genCertParser.addArgument(genCertInheritExtensions); 1621 1622 final StringArgument genCertSubjectAltDNS = new StringArgument(null, 1623 "subject-alternative-name-dns", false, 0, 1624 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 1625 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_SAN_DNS_DESC.get()); 1626 genCertSubjectAltDNS.addLongIdentifier("subjectAlternativeNameDNS", true); 1627 genCertSubjectAltDNS.addLongIdentifier("subject-alt-name-dns", true); 1628 genCertSubjectAltDNS.addLongIdentifier("subjectAltNameDNS", true); 1629 genCertSubjectAltDNS.addLongIdentifier("subject-alternative-dns", true); 1630 genCertSubjectAltDNS.addLongIdentifier("subjectAlternativeDNS", true); 1631 genCertSubjectAltDNS.addLongIdentifier("subject-alt-dns", true); 1632 genCertSubjectAltDNS.addLongIdentifier("subjectAltDNS", true); 1633 genCertSubjectAltDNS.addLongIdentifier("san-dns", true); 1634 genCertSubjectAltDNS.addLongIdentifier("sanDNS", true); 1635 genCertSubjectAltDNS.addValueValidator( 1636 new IA5StringArgumentValueValidator(false)); 1637 genCertParser.addArgument(genCertSubjectAltDNS); 1638 1639 final StringArgument genCertSubjectAltIP = new StringArgument(null, 1640 "subject-alternative-name-ip-address", false, 0, 1641 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 1642 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_SAN_IP_DESC.get()); 1643 genCertSubjectAltIP.addLongIdentifier("subjectAlternativeNameIPAddress", 1644 true); 1645 genCertSubjectAltIP.addLongIdentifier("subject-alternative-name-ip", true); 1646 genCertSubjectAltIP.addLongIdentifier("subjectAlternativeNameIP", true); 1647 genCertSubjectAltIP.addLongIdentifier("subject-alt-name-ip-address", true); 1648 genCertSubjectAltIP.addLongIdentifier("subjectAltNameIPAddress", true); 1649 genCertSubjectAltIP.addLongIdentifier("subject-alt-name-ip", true); 1650 genCertSubjectAltIP.addLongIdentifier("subjectAltNameIP", true); 1651 genCertSubjectAltIP.addLongIdentifier("subject-alternative-ip-address", 1652 true); 1653 genCertSubjectAltIP.addLongIdentifier("subjectAlternativeIPAddress", true); 1654 genCertSubjectAltIP.addLongIdentifier("subject-alternative-ip", true); 1655 genCertSubjectAltIP.addLongIdentifier("subjectAlternativeIP", true); 1656 genCertSubjectAltIP.addLongIdentifier("subject-alt-ip-address", true); 1657 genCertSubjectAltIP.addLongIdentifier("subjectAltIPAddress", true); 1658 genCertSubjectAltIP.addLongIdentifier("subject-alt-ip", true); 1659 genCertSubjectAltIP.addLongIdentifier("subjectAltIP", true); 1660 genCertSubjectAltIP.addLongIdentifier("san-ip-address", true); 1661 genCertSubjectAltIP.addLongIdentifier("sanIPAddress", true); 1662 genCertSubjectAltIP.addLongIdentifier("san-ip", true); 1663 genCertSubjectAltIP.addLongIdentifier("sanIP", true); 1664 genCertSubjectAltIP.addValueValidator( 1665 new IPAddressArgumentValueValidator(true, true)); 1666 genCertParser.addArgument(genCertSubjectAltIP); 1667 1668 final StringArgument genCertSubjectAltEmail = new StringArgument(null, 1669 "subject-alternative-name-email-address", false, 0, 1670 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 1671 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_SAN_EMAIL_DESC.get()); 1672 genCertSubjectAltEmail.addLongIdentifier( 1673 "subjectAlternativeNameEmailAddress", true); 1674 genCertSubjectAltEmail.addLongIdentifier("subject-alternative-name-email", 1675 true); 1676 genCertSubjectAltEmail.addLongIdentifier("subjectAlternativeNameEmail", 1677 true); 1678 genCertSubjectAltEmail.addLongIdentifier("subject-alt-name-email-address", 1679 true); 1680 genCertSubjectAltEmail.addLongIdentifier("subjectAltNameEmailAddress", 1681 true); 1682 genCertSubjectAltEmail.addLongIdentifier("subject-alt-name-email", true); 1683 genCertSubjectAltEmail.addLongIdentifier("subjectAltNameEmail", true); 1684 genCertSubjectAltEmail.addLongIdentifier( 1685 "subject-alternative-email-address", true); 1686 genCertSubjectAltEmail.addLongIdentifier("subjectAlternativeEmailAddress", 1687 true); 1688 genCertSubjectAltEmail.addLongIdentifier("subject-alternative-email", true); 1689 genCertSubjectAltEmail.addLongIdentifier("subjectAlternativeEmail", true); 1690 genCertSubjectAltEmail.addLongIdentifier("subject-alt-email-address", true); 1691 genCertSubjectAltEmail.addLongIdentifier("subjectAltEmailAddress", true); 1692 genCertSubjectAltEmail.addLongIdentifier("subject-alt-email", true); 1693 genCertSubjectAltEmail.addLongIdentifier("subjectAltEmail", true); 1694 genCertSubjectAltEmail.addLongIdentifier("san-email-address", true); 1695 genCertSubjectAltEmail.addLongIdentifier("sanEmailAddress", true); 1696 genCertSubjectAltEmail.addLongIdentifier("san-email", true); 1697 genCertSubjectAltEmail.addLongIdentifier("sanEmail", true); 1698 genCertSubjectAltEmail.addValueValidator( 1699 new IA5StringArgumentValueValidator(false)); 1700 genCertParser.addArgument(genCertSubjectAltEmail); 1701 1702 final StringArgument genCertSubjectAltURI = new StringArgument(null, 1703 "subject-alternative-name-uri", false, 0, 1704 INFO_MANAGE_CERTS_PLACEHOLDER_URI.get(), 1705 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_SAN_URI_DESC.get()); 1706 genCertSubjectAltURI.addLongIdentifier("subjectAlternativeNameURI", true); 1707 genCertSubjectAltURI.addLongIdentifier("subject-alt-name-uri", true); 1708 genCertSubjectAltURI.addLongIdentifier("subjectAltNameURI", true); 1709 genCertSubjectAltURI.addLongIdentifier("subject-alternative-uri", true); 1710 genCertSubjectAltURI.addLongIdentifier("subjectAlternativeURI", true); 1711 genCertSubjectAltURI.addLongIdentifier("subject-alt-uri", true); 1712 genCertSubjectAltURI.addLongIdentifier("subjectAltURI", true); 1713 genCertSubjectAltURI.addLongIdentifier("san-uri", true); 1714 genCertSubjectAltURI.addLongIdentifier("sanURI", true); 1715 genCertParser.addArgument(genCertSubjectAltURI); 1716 1717 final StringArgument genCertSubjectAltOID = new StringArgument(null, 1718 "subject-alternative-name-oid", false, 0, 1719 INFO_MANAGE_CERTS_PLACEHOLDER_OID.get(), 1720 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_SAN_OID_DESC.get()); 1721 genCertSubjectAltOID.addLongIdentifier("subjectAlternativeNameOID", true); 1722 genCertSubjectAltOID.addLongIdentifier("subject-alt-name-oid", true); 1723 genCertSubjectAltOID.addLongIdentifier("subjectAltNameOID", true); 1724 genCertSubjectAltOID.addLongIdentifier("subject-alternative-oid", true); 1725 genCertSubjectAltOID.addLongIdentifier("subjectAlternativeOID", true); 1726 genCertSubjectAltOID.addLongIdentifier("subject-alt-oid", true); 1727 genCertSubjectAltOID.addLongIdentifier("subjectAltOID", true); 1728 genCertSubjectAltOID.addLongIdentifier("san-oid", true); 1729 genCertSubjectAltOID.addLongIdentifier("sanOID", true); 1730 genCertSubjectAltOID.addValueValidator(new OIDArgumentValueValidator(true)); 1731 genCertParser.addArgument(genCertSubjectAltOID); 1732 1733 final BooleanValueArgument genCertBasicConstraintsIsCA = 1734 new BooleanValueArgument(null, "basic-constraints-is-ca", false, null, 1735 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_BC_IS_CA_DESC.get()); 1736 genCertBasicConstraintsIsCA.addLongIdentifier("basicConstraintsIsCA", true); 1737 genCertBasicConstraintsIsCA.addLongIdentifier("bc-is-ca", true); 1738 genCertBasicConstraintsIsCA.addLongIdentifier("bcIsCA", true); 1739 genCertParser.addArgument(genCertBasicConstraintsIsCA); 1740 1741 final IntegerArgument genCertBasicConstraintsPathLength = 1742 new IntegerArgument(null, "basic-constraints-maximum-path-length", 1743 false, 1, null, 1744 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_BC_PATH_LENGTH_DESC.get(), 0, 1745 Integer.MAX_VALUE); 1746 genCertBasicConstraintsPathLength.addLongIdentifier( 1747 "basicConstraintsMaximumPathLength", true); 1748 genCertBasicConstraintsPathLength.addLongIdentifier( 1749 "basic-constraints-max-path-length", true); 1750 genCertBasicConstraintsPathLength.addLongIdentifier( 1751 "basicConstraintsMaxPathLength", true); 1752 genCertBasicConstraintsPathLength.addLongIdentifier( 1753 "basic-constraints-path-length", true); 1754 genCertBasicConstraintsPathLength.addLongIdentifier( 1755 "basicConstraintsPathLength", true); 1756 genCertBasicConstraintsPathLength.addLongIdentifier( 1757 "bc-maximum-path-length", true); 1758 genCertBasicConstraintsPathLength.addLongIdentifier("bcMaximumPathLength", 1759 true); 1760 genCertBasicConstraintsPathLength.addLongIdentifier("bc-max-path-length", 1761 true); 1762 genCertBasicConstraintsPathLength.addLongIdentifier("bcMaxPathLength", 1763 true); 1764 genCertBasicConstraintsPathLength.addLongIdentifier("bc-path-length", true); 1765 genCertBasicConstraintsPathLength.addLongIdentifier("bcPathLength", true); 1766 genCertParser.addArgument(genCertBasicConstraintsPathLength); 1767 1768 final StringArgument genCertKeyUsage = new StringArgument(null, "key-usage", 1769 false, 0, null, INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_KU_DESC.get()); 1770 genCertKeyUsage.addLongIdentifier("keyUsage", true); 1771 genCertParser.addArgument(genCertKeyUsage); 1772 1773 final StringArgument genCertExtendedKeyUsage = new StringArgument(null, 1774 "extended-key-usage", false, 0, null, 1775 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_EKU_DESC.get()); 1776 genCertExtendedKeyUsage.addLongIdentifier("extendedKeyUsage", true); 1777 genCertParser.addArgument(genCertExtendedKeyUsage); 1778 1779 final StringArgument genCertExtension = new StringArgument(null, 1780 "extension", false, 0, null, 1781 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_EXT_DESC.get()); 1782 genCertExtension.addLongIdentifier("ext", true); 1783 genCertParser.addArgument(genCertExtension); 1784 1785 final FileArgument genCertOutputFile = new FileArgument(null, "output-file", 1786 false, 1, null, 1787 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_OUTPUT_FILE_DESC.get(), false, true, 1788 true, false); 1789 genCertOutputFile.addLongIdentifier("outputFile", true); 1790 genCertOutputFile.addLongIdentifier("filename", true); 1791 genCertOutputFile.addLongIdentifier("file", true); 1792 genCertParser.addArgument(genCertOutputFile); 1793 1794 final Set<String> genCertOutputFormatAllowedValues = StaticUtils.setOf( 1795 "PEM", "text", "txt", "RFC", "DER", "binary", "bin"); 1796 final StringArgument genCertOutputFormat = new StringArgument(null, 1797 "output-format", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_FORMAT.get(), 1798 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_FORMAT_DESC.get(), 1799 genCertOutputFormatAllowedValues, "PEM"); 1800 genCertOutputFormat.addLongIdentifier("outputFormat", true); 1801 genCertParser.addArgument(genCertOutputFormat); 1802 1803 final BooleanArgument genCertDisplayCommand = new BooleanArgument(null, 1804 "display-keytool-command", 1, 1805 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_DISPLAY_COMMAND_DESC.get()); 1806 genCertDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 1807 genCertDisplayCommand.addLongIdentifier("show-keytool-command", true); 1808 genCertDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 1809 genCertParser.addArgument(genCertDisplayCommand); 1810 1811 genCertParser.addRequiredArgumentSet(genCertKeystorePassword, 1812 genCertKeystorePasswordFile, genCertPromptForKeystorePassword); 1813 genCertParser.addExclusiveArgumentSet(genCertKeystorePassword, 1814 genCertKeystorePasswordFile, genCertPromptForKeystorePassword); 1815 genCertParser.addExclusiveArgumentSet(genCertPKPassword, 1816 genCertPKPasswordFile, genCertPromptForPKPassword); 1817 genCertParser.addExclusiveArgumentSet(genCertReplace, genCertKeyAlgorithm); 1818 genCertParser.addExclusiveArgumentSet(genCertReplace, genCertKeySizeBits); 1819 genCertParser.addExclusiveArgumentSet(genCertReplace, 1820 genCertSignatureAlgorithm); 1821 genCertParser.addDependentArgumentSet(genCertBasicConstraintsPathLength, 1822 genCertBasicConstraintsIsCA); 1823 genCertParser.addDependentArgumentSet(genCertOutputFormat, 1824 genCertOutputFile); 1825 1826 final LinkedHashMap<String[],String> genCertExamples = 1827 new LinkedHashMap<>(StaticUtils.computeMapCapacity(4)); 1828 genCertExamples.put( 1829 new String[] 1830 { 1831 "generate-self-signed-certificate", 1832 "--keystore", getPlatformSpecificPath("config", "keystore"), 1833 "--keystore-password-file", 1834 getPlatformSpecificPath("config", "keystore.pin"), 1835 "--alias", "server-cert", 1836 "--subject-dn", "CN=ldap.example.com,O=Example Corp,C=US" 1837 }, 1838 INFO_MANAGE_CERTS_SC_GEN_CERT_EXAMPLE_1.get()); 1839 genCertExamples.put( 1840 new String[] 1841 { 1842 "generate-self-signed-certificate", 1843 "--keystore", getPlatformSpecificPath("config", "keystore"), 1844 "--keystore-password-file", 1845 getPlatformSpecificPath("config", "keystore.pin"), 1846 "--alias", "server-cert", 1847 "--replace-existing-certificate", 1848 "--inherit-extensions" 1849 }, 1850 INFO_MANAGE_CERTS_SC_GEN_CERT_EXAMPLE_2.get()); 1851 genCertExamples.put( 1852 new String[] 1853 { 1854 "generate-self-signed-certificate", 1855 "--keystore", getPlatformSpecificPath("config", "keystore"), 1856 "--keystore-password-file", 1857 getPlatformSpecificPath("config", "keystore.pin"), 1858 "--alias", "server-cert", 1859 "--subject-dn", "CN=ldap.example.com,O=Example Corp,C=US", 1860 "--days-valid", "3650", 1861 "--validity-start-time", "20170101000000", 1862 "--key-algorithm", "RSA", 1863 "--key-size-bits", "4096", 1864 "--signature-algorithm", "SHA256withRSA", 1865 "--subject-alternative-name-dns", "ldap1.example.com", 1866 "--subject-alternative-name-dns", "ldap2.example.com", 1867 "--subject-alternative-name-ip-address", "1.2.3.4", 1868 "--subject-alternative-name-ip-address", "1.2.3.5", 1869 "--extended-key-usage", "server-auth", 1870 "--extended-key-usage", "client-auth", 1871 "--display-keytool-command" 1872 }, 1873 INFO_MANAGE_CERTS_SC_GEN_CERT_EXAMPLE_3.get()); 1874 genCertExamples.put( 1875 new String[] 1876 { 1877 "generate-self-signed-certificate", 1878 "--keystore", getPlatformSpecificPath("config", "keystore"), 1879 "--keystore-password-file", 1880 getPlatformSpecificPath("config", "keystore.pin"), 1881 "--alias", "ca-cert", 1882 "--subject-dn", 1883 "CN=Example Certification Authority,O=Example Corp,C=US", 1884 "--days-valid", "7300", 1885 "--validity-start-time", "20170101000000", 1886 "--key-algorithm", "EC", 1887 "--key-size-bits", "256", 1888 "--signature-algorithm", "SHA256withECDSA", 1889 "--basic-constraints-is-ca", "true", 1890 "--key-usage", "key-cert-sign", 1891 "--key-usage", "crl-sign", 1892 "--display-keytool-command" 1893 }, 1894 INFO_MANAGE_CERTS_SC_GEN_CERT_EXAMPLE_4.get()); 1895 1896 final SubCommand genCertSubCommand = new SubCommand( 1897 "generate-self-signed-certificate", 1898 INFO_MANAGE_CERTS_SC_GEN_CERT_DESC.get(), genCertParser, 1899 genCertExamples); 1900 genCertSubCommand.addName("generateSelfSignedCertificate", true); 1901 genCertSubCommand.addName("generate-certificate", true); 1902 genCertSubCommand.addName("generateCertificate", true); 1903 genCertSubCommand.addName("self-signed-certificate", true); 1904 genCertSubCommand.addName("selfSignedCertificate", true); 1905 genCertSubCommand.addName("selfcert", true); 1906 1907 parser.addSubCommand(genCertSubCommand); 1908 1909 1910 // Define the "generate-certificate-signing-request" subcommand and all of 1911 // its arguments. 1912 final ArgumentParser genCSRParser = new ArgumentParser( 1913 "generate-certificate-signing-request", 1914 INFO_MANAGE_CERTS_SC_GEN_CSR_DESC.get()); 1915 1916 final Set<String> genCSROutputFormatAllowedValues = StaticUtils.setOf( 1917 "PEM", "text", "txt", "RFC", "DER", "binary", "bin"); 1918 final StringArgument genCSROutputFormat = new StringArgument(null, 1919 "output-format", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_FORMAT.get(), 1920 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_FORMAT_DESC.get(), 1921 genCSROutputFormatAllowedValues, "PEM"); 1922 genCSROutputFormat.addLongIdentifier("outputFormat", true); 1923 genCSRParser.addArgument(genCSROutputFormat); 1924 1925 final FileArgument genCSROutputFile = new FileArgument(null, "output-file", 1926 false, 1, null, 1927 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_OUTPUT_FILE_DESC.get(), false, true, 1928 true, false); 1929 genCSROutputFile.addLongIdentifier("outputFile", true); 1930 genCSROutputFile.addLongIdentifier("filename", true); 1931 genCSROutputFile.addLongIdentifier("file", true); 1932 genCSRParser.addArgument(genCSROutputFile); 1933 1934 final FileArgument genCSRKeystore = new FileArgument(null, "keystore", 1935 true, 1, null, INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_KS_DESC.get(), false, 1936 true, true, false); 1937 genCSRKeystore.addLongIdentifier("keystore-path", true); 1938 genCSRKeystore.addLongIdentifier("keystorePath", true); 1939 genCSRKeystore.addLongIdentifier("keystore-file", true); 1940 genCSRKeystore.addLongIdentifier("keystoreFile", true); 1941 genCSRParser.addArgument(genCSRKeystore); 1942 1943 final StringArgument genCSRKeystorePassword = new StringArgument(null, 1944 "keystore-password", false, 1, 1945 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 1946 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_KS_PW_DESC.get()); 1947 genCSRKeystorePassword.addLongIdentifier("keystorePassword", true); 1948 genCSRKeystorePassword.addLongIdentifier("keystore-passphrase", true); 1949 genCSRKeystorePassword.addLongIdentifier("keystorePassphrase", true); 1950 genCSRKeystorePassword.addLongIdentifier("keystore-pin", true); 1951 genCSRKeystorePassword.addLongIdentifier("keystorePIN", true); 1952 genCSRKeystorePassword.addLongIdentifier("storepass", true); 1953 genCSRKeystorePassword.setSensitive(true); 1954 genCSRParser.addArgument(genCSRKeystorePassword); 1955 1956 final FileArgument genCSRKeystorePasswordFile = new FileArgument(null, 1957 "keystore-password-file", false, 1, null, 1958 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_KS_PW_FILE_DESC.get(), true, true, 1959 true, false); 1960 genCSRKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 1961 true); 1962 genCSRKeystorePasswordFile.addLongIdentifier("keystore-passphrase-file", 1963 true); 1964 genCSRKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 1965 true); 1966 genCSRKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 1967 true); 1968 genCSRKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 1969 genCSRParser.addArgument(genCSRKeystorePasswordFile); 1970 1971 final BooleanArgument genCSRPromptForKeystorePassword = 1972 new BooleanArgument(null, "prompt-for-keystore-password", 1973 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_PROMPT_FOR_KS_PW_DESC.get()); 1974 genCSRPromptForKeystorePassword.addLongIdentifier( 1975 "promptForKeystorePassword", true); 1976 genCSRPromptForKeystorePassword.addLongIdentifier( 1977 "prompt-for-keystore-passphrase", true); 1978 genCSRPromptForKeystorePassword.addLongIdentifier( 1979 "promptForKeystorePassphrase", true); 1980 genCSRPromptForKeystorePassword.addLongIdentifier( 1981 "prompt-for-keystore-pin", true); 1982 genCSRPromptForKeystorePassword.addLongIdentifier( 1983 "promptForKeystorePIN", true); 1984 genCSRParser.addArgument(genCSRPromptForKeystorePassword); 1985 1986 final StringArgument genCSRPKPassword = new StringArgument(null, 1987 "private-key-password", false, 1, 1988 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 1989 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_PK_PW_DESC.get()); 1990 genCSRPKPassword.addLongIdentifier("privateKeyPassword", true); 1991 genCSRPKPassword.addLongIdentifier("private-key-passphrase", true); 1992 genCSRPKPassword.addLongIdentifier("privateKeyPassphrase", true); 1993 genCSRPKPassword.addLongIdentifier("private-key-pin", true); 1994 genCSRPKPassword.addLongIdentifier("privateKeyPIN", true); 1995 genCSRPKPassword.addLongIdentifier("key-password", true); 1996 genCSRPKPassword.addLongIdentifier("keyPassword", true); 1997 genCSRPKPassword.addLongIdentifier("key-passphrase", true); 1998 genCSRPKPassword.addLongIdentifier("keyPassphrase", true); 1999 genCSRPKPassword.addLongIdentifier("key-pin", true); 2000 genCSRPKPassword.addLongIdentifier("keyPIN", true); 2001 genCSRPKPassword.addLongIdentifier("keypass", true); 2002 genCSRPKPassword.setSensitive(true); 2003 genCSRParser.addArgument(genCSRPKPassword); 2004 2005 final FileArgument genCSRPKPasswordFile = new FileArgument(null, 2006 "private-key-password-file", false, 1, null, 2007 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_PK_PW_FILE_DESC.get(), true, true, 2008 true, false); 2009 genCSRPKPasswordFile.addLongIdentifier("privateKeyPasswordFile", true); 2010 genCSRPKPasswordFile.addLongIdentifier("private-key-passphrase-file", 2011 true); 2012 genCSRPKPasswordFile.addLongIdentifier("privateKeyPassphraseFile", 2013 true); 2014 genCSRPKPasswordFile.addLongIdentifier("private-key-pin-file", 2015 true); 2016 genCSRPKPasswordFile.addLongIdentifier("privateKeyPINFile", true); 2017 genCSRPKPasswordFile.addLongIdentifier("key-password-file", true); 2018 genCSRPKPasswordFile.addLongIdentifier("keyPasswordFile", true); 2019 genCSRPKPasswordFile.addLongIdentifier("key-passphrase-file", 2020 true); 2021 genCSRPKPasswordFile.addLongIdentifier("keyPassphraseFile", 2022 true); 2023 genCSRPKPasswordFile.addLongIdentifier("key-pin-file", 2024 true); 2025 genCSRPKPasswordFile.addLongIdentifier("keyPINFile", true); 2026 genCSRParser.addArgument(genCSRPKPasswordFile); 2027 2028 final BooleanArgument genCSRPromptForPKPassword = 2029 new BooleanArgument(null, "prompt-for-private-key-password", 2030 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_PROMPT_FOR_PK_PW_DESC.get()); 2031 genCSRPromptForPKPassword.addLongIdentifier( 2032 "promptForPrivateKeyPassword", true); 2033 genCSRPromptForPKPassword.addLongIdentifier( 2034 "prompt-for-private-key-passphrase", true); 2035 genCSRPromptForPKPassword.addLongIdentifier( 2036 "promptForPrivateKeyPassphrase", true); 2037 genCSRPromptForPKPassword.addLongIdentifier("prompt-for-private-key-pin", 2038 true); 2039 genCSRPromptForPKPassword.addLongIdentifier("promptForPrivateKeyPIN", 2040 true); 2041 genCSRPromptForPKPassword.addLongIdentifier("prompt-for-key-password", 2042 true); 2043 genCSRPromptForPKPassword.addLongIdentifier("promptForKeyPassword", 2044 true); 2045 genCSRPromptForPKPassword.addLongIdentifier( 2046 "prompt-for-key-passphrase", true); 2047 genCSRPromptForPKPassword.addLongIdentifier( 2048 "promptForKeyPassphrase", true); 2049 genCSRPromptForPKPassword.addLongIdentifier("prompt-for-key-pin", true); 2050 genCSRPromptForPKPassword.addLongIdentifier("promptForKeyPIN", true); 2051 genCSRParser.addArgument(genCSRPromptForPKPassword); 2052 2053 final StringArgument genCSRKeystoreType = new StringArgument(null, 2054 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 2055 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_KS_TYPE_DESC.get(), 2056 ALLOWED_KEYSTORE_TYPE_VALUES); 2057 genCSRKeystoreType.addLongIdentifier("key-store-type", true); 2058 genCSRKeystoreType.addLongIdentifier("keystoreType", true); 2059 genCSRKeystoreType.addLongIdentifier("keystore-format", true); 2060 genCSRKeystoreType.addLongIdentifier("key-store-format", true); 2061 genCSRKeystoreType.addLongIdentifier("keystoreFormat", true); 2062 genCSRKeystoreType.addLongIdentifier("storetype", true); 2063 genCSRParser.addArgument(genCSRKeystoreType); 2064 2065 final StringArgument genCSRAlias = new StringArgument(null, "alias", 2066 true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 2067 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_ALIAS_DESC.get()); 2068 genCSRAlias.addLongIdentifier("nickname", true); 2069 genCSRParser.addArgument(genCSRAlias); 2070 2071 final BooleanArgument genCSRReplace = new BooleanArgument(null, 2072 "use-existing-key-pair", 1, 2073 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_REPLACE_DESC.get()); 2074 genCSRReplace.addLongIdentifier("use-existing-keypair", true); 2075 genCSRReplace.addLongIdentifier("useExistingKeyPair", true); 2076 genCSRReplace.addLongIdentifier("replace-existing-certificate", true); 2077 genCSRReplace.addLongIdentifier("replaceExistingCertificate", true); 2078 genCSRReplace.addLongIdentifier("replace-certificate", true); 2079 genCSRReplace.addLongIdentifier("replaceCertificate", true); 2080 genCSRReplace.addLongIdentifier("replace-existing", true); 2081 genCSRReplace.addLongIdentifier("replaceExisting", true); 2082 genCSRReplace.addLongIdentifier("replace", true); 2083 genCSRParser.addArgument(genCSRReplace); 2084 2085 final DNArgument genCSRSubjectDN = new DNArgument(null, "subject-dn", 2086 false, 1, null, 2087 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_SUBJECT_DN_DESC.get()); 2088 genCSRSubjectDN.addLongIdentifier("subjectDN", true); 2089 genCSRSubjectDN.addLongIdentifier("subject", true); 2090 genCSRSubjectDN.addLongIdentifier("dname", true); 2091 genCSRParser.addArgument(genCSRSubjectDN); 2092 2093 final StringArgument genCSRKeyAlgorithm = new StringArgument(null, 2094 "key-algorithm", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2095 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_KEY_ALGORITHM_DESC.get()); 2096 genCSRKeyAlgorithm.addLongIdentifier("keyAlgorithm", true); 2097 genCSRKeyAlgorithm.addLongIdentifier("key-alg", true); 2098 genCSRKeyAlgorithm.addLongIdentifier("keyAlg", true); 2099 genCSRParser.addArgument(genCSRKeyAlgorithm); 2100 2101 final IntegerArgument genCSRKeySizeBits = new IntegerArgument(null, 2102 "key-size-bits", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_BITS.get(), 2103 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_KEY_SIZE_BITS_DESC.get(), 1, 2104 Integer.MAX_VALUE); 2105 genCSRKeySizeBits.addLongIdentifier("keySizeBits", true); 2106 genCSRKeySizeBits.addLongIdentifier("key-length-bits", true); 2107 genCSRKeySizeBits.addLongIdentifier("keyLengthBits", true); 2108 genCSRKeySizeBits.addLongIdentifier("key-size", true); 2109 genCSRKeySizeBits.addLongIdentifier("keySize", true); 2110 genCSRKeySizeBits.addLongIdentifier("key-length", true); 2111 genCSRKeySizeBits.addLongIdentifier("keyLength", true); 2112 genCSRParser.addArgument(genCSRKeySizeBits); 2113 2114 final StringArgument genCSRSignatureAlgorithm = new StringArgument(null, 2115 "signature-algorithm", false, 1, 2116 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2117 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_SIG_ALG_DESC.get()); 2118 genCSRSignatureAlgorithm.addLongIdentifier("signatureAlgorithm", true); 2119 genCSRSignatureAlgorithm.addLongIdentifier("signature-alg", true); 2120 genCSRSignatureAlgorithm.addLongIdentifier("signatureAlg", true); 2121 genCSRSignatureAlgorithm.addLongIdentifier("sig-alg", true); 2122 genCSRSignatureAlgorithm.addLongIdentifier("sigAlg", true); 2123 genCSRParser.addArgument(genCSRSignatureAlgorithm); 2124 2125 final BooleanArgument genCSRInheritExtensions = new BooleanArgument(null, 2126 "inherit-extensions", 1, 2127 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_INHERIT_EXT_DESC.get()); 2128 genCSRInheritExtensions.addLongIdentifier("inheritExtensions", true); 2129 genCSRParser.addArgument(genCSRInheritExtensions); 2130 2131 final StringArgument genCSRSubjectAltDNS = new StringArgument(null, 2132 "subject-alternative-name-dns", false, 0, 2133 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2134 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_SAN_DNS_DESC.get()); 2135 genCSRSubjectAltDNS.addLongIdentifier("subjectAlternativeNameDNS", true); 2136 genCSRSubjectAltDNS.addLongIdentifier("subject-alt-name-dns", true); 2137 genCSRSubjectAltDNS.addLongIdentifier("subjectAltNameDNS", true); 2138 genCSRSubjectAltDNS.addLongIdentifier("subject-alternative-dns", true); 2139 genCSRSubjectAltDNS.addLongIdentifier("subjectAlternativeDNS", true); 2140 genCSRSubjectAltDNS.addLongIdentifier("subject-alt-dns", true); 2141 genCSRSubjectAltDNS.addLongIdentifier("subjectAltDNS", true); 2142 genCSRSubjectAltDNS.addLongIdentifier("san-dns", true); 2143 genCSRSubjectAltDNS.addLongIdentifier("sanDNS", true); 2144 genCSRSubjectAltDNS.addValueValidator( 2145 new IA5StringArgumentValueValidator(false)); 2146 genCSRParser.addArgument(genCSRSubjectAltDNS); 2147 2148 final StringArgument genCSRSubjectAltIP = new StringArgument(null, 2149 "subject-alternative-name-ip-address", false, 0, 2150 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2151 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_SAN_IP_DESC.get()); 2152 genCSRSubjectAltIP.addLongIdentifier("subjectAlternativeNameIPAddress", 2153 true); 2154 genCSRSubjectAltIP.addLongIdentifier("subject-alternative-name-ip", true); 2155 genCSRSubjectAltIP.addLongIdentifier("subjectAlternativeNameIP", true); 2156 genCSRSubjectAltIP.addLongIdentifier("subject-alt-name-ip-address", true); 2157 genCSRSubjectAltIP.addLongIdentifier("subjectAltNameIPAddress", true); 2158 genCSRSubjectAltIP.addLongIdentifier("subject-alt-name-ip", true); 2159 genCSRSubjectAltIP.addLongIdentifier("subjectAltNameIP", true); 2160 genCSRSubjectAltIP.addLongIdentifier("subject-alternative-ip-address", 2161 true); 2162 genCSRSubjectAltIP.addLongIdentifier("subjectAlternativeIPAddress", true); 2163 genCSRSubjectAltIP.addLongIdentifier("subject-alternative-ip", true); 2164 genCSRSubjectAltIP.addLongIdentifier("subjectAlternativeIP", true); 2165 genCSRSubjectAltIP.addLongIdentifier("subject-alt-ip-address", true); 2166 genCSRSubjectAltIP.addLongIdentifier("subjectAltIPAddress", true); 2167 genCSRSubjectAltIP.addLongIdentifier("subject-alt-ip", true); 2168 genCSRSubjectAltIP.addLongIdentifier("subjectAltIP", true); 2169 genCSRSubjectAltIP.addLongIdentifier("san-ip-address", true); 2170 genCSRSubjectAltIP.addLongIdentifier("sanIPAddress", true); 2171 genCSRSubjectAltIP.addLongIdentifier("san-ip", true); 2172 genCSRSubjectAltIP.addLongIdentifier("sanIP", true); 2173 genCSRSubjectAltIP.addValueValidator( 2174 new IPAddressArgumentValueValidator(true, true)); 2175 genCSRParser.addArgument(genCSRSubjectAltIP); 2176 2177 final StringArgument genCSRSubjectAltEmail = new StringArgument(null, 2178 "subject-alternative-name-email-address", false, 0, 2179 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2180 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_SAN_EMAIL_DESC.get()); 2181 genCSRSubjectAltEmail.addLongIdentifier( 2182 "subjectAlternativeNameEmailAddress", true); 2183 genCSRSubjectAltEmail.addLongIdentifier("subject-alternative-name-email", 2184 true); 2185 genCSRSubjectAltEmail.addLongIdentifier("subjectAlternativeNameEmail", 2186 true); 2187 genCSRSubjectAltEmail.addLongIdentifier("subject-alt-name-email-address", 2188 true); 2189 genCSRSubjectAltEmail.addLongIdentifier("subjectAltNameEmailAddress", 2190 true); 2191 genCSRSubjectAltEmail.addLongIdentifier("subject-alt-name-email", true); 2192 genCSRSubjectAltEmail.addLongIdentifier("subjectAltNameEmail", true); 2193 genCSRSubjectAltEmail.addLongIdentifier( 2194 "subject-alternative-email-address", true); 2195 genCSRSubjectAltEmail.addLongIdentifier("subjectAlternativeEmailAddress", 2196 true); 2197 genCSRSubjectAltEmail.addLongIdentifier("subject-alternative-email", true); 2198 genCSRSubjectAltEmail.addLongIdentifier("subjectAlternativeEmail", true); 2199 genCSRSubjectAltEmail.addLongIdentifier("subject-alt-email-address", true); 2200 genCSRSubjectAltEmail.addLongIdentifier("subjectAltEmailAddress", true); 2201 genCSRSubjectAltEmail.addLongIdentifier("subject-alt-email", true); 2202 genCSRSubjectAltEmail.addLongIdentifier("subjectAltEmail", true); 2203 genCSRSubjectAltEmail.addLongIdentifier("san-email-address", true); 2204 genCSRSubjectAltEmail.addLongIdentifier("sanEmailAddress", true); 2205 genCSRSubjectAltEmail.addLongIdentifier("san-email", true); 2206 genCSRSubjectAltEmail.addLongIdentifier("sanEmail", true); 2207 genCSRSubjectAltEmail.addValueValidator( 2208 new IA5StringArgumentValueValidator(false)); 2209 genCSRParser.addArgument(genCSRSubjectAltEmail); 2210 2211 final StringArgument genCSRSubjectAltURI = new StringArgument(null, 2212 "subject-alternative-name-uri", false, 0, 2213 INFO_MANAGE_CERTS_PLACEHOLDER_URI.get(), 2214 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_SAN_URI_DESC.get()); 2215 genCSRSubjectAltURI.addLongIdentifier("subjectAlternativeNameURI", true); 2216 genCSRSubjectAltURI.addLongIdentifier("subject-alt-name-uri", true); 2217 genCSRSubjectAltURI.addLongIdentifier("subjectAltNameURI", true); 2218 genCSRSubjectAltURI.addLongIdentifier("subject-alternative-uri", true); 2219 genCSRSubjectAltURI.addLongIdentifier("subjectAlternativeURI", true); 2220 genCSRSubjectAltURI.addLongIdentifier("subject-alt-uri", true); 2221 genCSRSubjectAltURI.addLongIdentifier("subjectAltURI", true); 2222 genCSRSubjectAltURI.addLongIdentifier("san-uri", true); 2223 genCSRSubjectAltURI.addLongIdentifier("sanURI", true); 2224 genCSRParser.addArgument(genCSRSubjectAltURI); 2225 2226 final StringArgument genCSRSubjectAltOID = new StringArgument(null, 2227 "subject-alternative-name-oid", false, 0, 2228 INFO_MANAGE_CERTS_PLACEHOLDER_OID.get(), 2229 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_SAN_OID_DESC.get()); 2230 genCSRSubjectAltOID.addLongIdentifier("subjectAlternativeNameOID", true); 2231 genCSRSubjectAltOID.addLongIdentifier("subject-alt-name-oid", true); 2232 genCSRSubjectAltOID.addLongIdentifier("subjectAltNameOID", true); 2233 genCSRSubjectAltOID.addLongIdentifier("subject-alternative-oid", true); 2234 genCSRSubjectAltOID.addLongIdentifier("subjectAlternativeOID", true); 2235 genCSRSubjectAltOID.addLongIdentifier("subject-alt-oid", true); 2236 genCSRSubjectAltOID.addLongIdentifier("subjectAltOID", true); 2237 genCSRSubjectAltOID.addLongIdentifier("san-oid", true); 2238 genCSRSubjectAltOID.addLongIdentifier("sanOID", true); 2239 genCSRSubjectAltOID.addValueValidator(new OIDArgumentValueValidator(true)); 2240 genCSRParser.addArgument(genCSRSubjectAltOID); 2241 2242 final BooleanValueArgument genCSRBasicConstraintsIsCA = 2243 new BooleanValueArgument(null, "basic-constraints-is-ca", false, null, 2244 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_BC_IS_CA_DESC.get()); 2245 genCSRBasicConstraintsIsCA.addLongIdentifier("basicConstraintsIsCA", true); 2246 genCSRBasicConstraintsIsCA.addLongIdentifier("bc-is-ca", true); 2247 genCSRBasicConstraintsIsCA.addLongIdentifier("bcIsCA", true); 2248 genCSRParser.addArgument(genCSRBasicConstraintsIsCA); 2249 2250 final IntegerArgument genCSRBasicConstraintsPathLength = 2251 new IntegerArgument(null, "basic-constraints-maximum-path-length", 2252 false, 1, null, 2253 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_BC_PATH_LENGTH_DESC.get(), 0, 2254 Integer.MAX_VALUE); 2255 genCSRBasicConstraintsPathLength.addLongIdentifier( 2256 "basicConstraintsMaximumPathLength", true); 2257 genCSRBasicConstraintsPathLength.addLongIdentifier( 2258 "basic-constraints-max-path-length", true); 2259 genCSRBasicConstraintsPathLength.addLongIdentifier( 2260 "basicConstraintsMaxPathLength", true); 2261 genCSRBasicConstraintsPathLength.addLongIdentifier( 2262 "basic-constraints-path-length", true); 2263 genCSRBasicConstraintsPathLength.addLongIdentifier( 2264 "basicConstraintsPathLength", true); 2265 genCSRBasicConstraintsPathLength.addLongIdentifier( 2266 "bc-maximum-path-length", true); 2267 genCSRBasicConstraintsPathLength.addLongIdentifier("bcMaximumPathLength", 2268 true); 2269 genCSRBasicConstraintsPathLength.addLongIdentifier("bc-max-path-length", 2270 true); 2271 genCSRBasicConstraintsPathLength.addLongIdentifier("bcMaxPathLength", 2272 true); 2273 genCSRBasicConstraintsPathLength.addLongIdentifier("bc-path-length", true); 2274 genCSRBasicConstraintsPathLength.addLongIdentifier("bcPathLength", true); 2275 genCSRParser.addArgument(genCSRBasicConstraintsPathLength); 2276 2277 final StringArgument genCSRKeyUsage = new StringArgument(null, "key-usage", 2278 false, 0, null, INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_KU_DESC.get()); 2279 genCSRKeyUsage.addLongIdentifier("keyUsage", true); 2280 genCSRParser.addArgument(genCSRKeyUsage); 2281 2282 final StringArgument genCSRExtendedKeyUsage = new StringArgument(null, 2283 "extended-key-usage", false, 0, null, 2284 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_EKU_DESC.get()); 2285 genCSRExtendedKeyUsage.addLongIdentifier("extendedKeyUsage", true); 2286 genCSRParser.addArgument(genCSRExtendedKeyUsage); 2287 2288 final StringArgument genCSRExtension = new StringArgument(null, 2289 "extension", false, 0, null, 2290 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_EXT_DESC.get()); 2291 genCSRExtension.addLongIdentifier("ext", true); 2292 genCSRParser.addArgument(genCSRExtension); 2293 2294 final BooleanArgument genCSRDisplayCommand = new BooleanArgument(null, 2295 "display-keytool-command", 1, 2296 INFO_MANAGE_CERTS_SC_GEN_CSR_ARG_DISPLAY_COMMAND_DESC.get()); 2297 genCSRDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 2298 genCSRDisplayCommand.addLongIdentifier("show-keytool-command", true); 2299 genCSRDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 2300 genCSRParser.addArgument(genCSRDisplayCommand); 2301 2302 genCSRParser.addRequiredArgumentSet(genCSRKeystorePassword, 2303 genCSRKeystorePasswordFile, genCSRPromptForKeystorePassword); 2304 genCSRParser.addExclusiveArgumentSet(genCSRKeystorePassword, 2305 genCSRKeystorePasswordFile, genCSRPromptForKeystorePassword); 2306 genCSRParser.addExclusiveArgumentSet(genCSRPKPassword, 2307 genCSRPKPasswordFile, genCSRPromptForPKPassword); 2308 genCSRParser.addExclusiveArgumentSet(genCSRReplace, genCSRKeyAlgorithm); 2309 genCSRParser.addExclusiveArgumentSet(genCSRReplace, genCSRKeySizeBits); 2310 genCSRParser.addExclusiveArgumentSet(genCSRReplace, 2311 genCSRSignatureAlgorithm); 2312 genCSRParser.addDependentArgumentSet(genCSRBasicConstraintsPathLength, 2313 genCSRBasicConstraintsIsCA); 2314 2315 final LinkedHashMap<String[],String> genCSRExamples = 2316 new LinkedHashMap<>(StaticUtils.computeMapCapacity(3)); 2317 genCSRExamples.put( 2318 new String[] 2319 { 2320 "generate-certificate-signing-request", 2321 "--keystore", getPlatformSpecificPath("config", "keystore"), 2322 "--keystore-password-file", 2323 getPlatformSpecificPath("config", "keystore.pin"), 2324 "--alias", "server-cert", 2325 "--subject-dn", "CN=ldap.example.com,O=Example Corp,C=US" 2326 }, 2327 INFO_MANAGE_CERTS_SC_GEN_CSR_EXAMPLE_1.get()); 2328 genCSRExamples.put( 2329 new String[] 2330 { 2331 "generate-certificate-signing-request", 2332 "--keystore", getPlatformSpecificPath("config", "keystore"), 2333 "--keystore-password-file", 2334 getPlatformSpecificPath("config", "keystore.pin"), 2335 "--alias", "server-cert", 2336 "--use-existing-key-pair", 2337 "--inherit-extensions", 2338 "--output-file", "server-cert.csr" 2339 }, 2340 INFO_MANAGE_CERTS_SC_GEN_CSR_EXAMPLE_2.get()); 2341 genCSRExamples.put( 2342 new String[] 2343 { 2344 "generate-certificate-signing-request", 2345 "--keystore", getPlatformSpecificPath("config", "keystore"), 2346 "--keystore-password-file", 2347 getPlatformSpecificPath("config", "keystore.pin"), 2348 "--alias", "server-cert", 2349 "--subject-dn", "CN=ldap.example.com,O=Example Corp,C=US", 2350 "--key-algorithm", "EC", 2351 "--key-size-bits", "256", 2352 "--signature-algorithm", "SHA256withECDSA", 2353 "--subject-alternative-name-dns", "ldap1.example.com", 2354 "--subject-alternative-name-dns", "ldap2.example.com", 2355 "--subject-alternative-name-ip-address", "1.2.3.4", 2356 "--subject-alternative-name-ip-address", "1.2.3.5", 2357 "--extended-key-usage", "server-auth", 2358 "--extended-key-usage", "client-auth", 2359 "--output-file", "server-cert.csr", 2360 "--display-keytool-command" 2361 }, 2362 INFO_MANAGE_CERTS_SC_GEN_CSR_EXAMPLE_3.get()); 2363 2364 final SubCommand genCSRSubCommand = new SubCommand( 2365 "generate-certificate-signing-request", 2366 INFO_MANAGE_CERTS_SC_GEN_CSR_DESC.get(), genCSRParser, 2367 genCSRExamples); 2368 genCSRSubCommand.addName("generateCertificateSigningRequest", true); 2369 genCSRSubCommand.addName("generate-certificate-request", true); 2370 genCSRSubCommand.addName("generateCertificateRequest", true); 2371 genCSRSubCommand.addName("generate-csr", true); 2372 genCSRSubCommand.addName("generateCSR", true); 2373 genCSRSubCommand.addName("certificate-signing-request", true); 2374 genCSRSubCommand.addName("certificateSigningRequest", true); 2375 genCSRSubCommand.addName("csr", true); 2376 genCSRSubCommand.addName("certreq", true); 2377 2378 parser.addSubCommand(genCSRSubCommand); 2379 2380 2381 // Define the "sign-certificate-signing-request" subcommand and all of its 2382 // arguments. 2383 final ArgumentParser signCSRParser = new ArgumentParser( 2384 "sign-certificate-signing-request", 2385 INFO_MANAGE_CERTS_SC_SIGN_CSR_DESC.get()); 2386 2387 final FileArgument signCSRInputFile = new FileArgument(null, 2388 "request-input-file", true, 1, null, 2389 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_INPUT_FILE_DESC.get(), true, true, 2390 true, false); 2391 signCSRInputFile.addLongIdentifier("requestInputFile", true); 2392 signCSRInputFile.addLongIdentifier("certificate-signing-request", true); 2393 signCSRInputFile.addLongIdentifier("certificateSigningRequest", true); 2394 signCSRInputFile.addLongIdentifier("input-file", false); 2395 signCSRInputFile.addLongIdentifier("inputFile", true); 2396 signCSRInputFile.addLongIdentifier("csr", true); 2397 signCSRParser.addArgument(signCSRInputFile); 2398 2399 final FileArgument signCSROutputFile = new FileArgument(null, 2400 "certificate-output-file", false, 1, null, 2401 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_OUTPUT_FILE_DESC.get(), false, true, 2402 true, false); 2403 signCSROutputFile.addLongIdentifier("certificateOutputFile", true); 2404 signCSROutputFile.addLongIdentifier("output-file", false); 2405 signCSROutputFile.addLongIdentifier("outputFile", true); 2406 signCSROutputFile.addLongIdentifier("certificate-file", true); 2407 signCSROutputFile.addLongIdentifier("certificateFile", true); 2408 signCSRParser.addArgument(signCSROutputFile); 2409 2410 final Set<String> signCSROutputFormatAllowedValues = StaticUtils.setOf( 2411 "PEM", "text", "txt", "RFC", "DER", "binary", "bin"); 2412 final StringArgument signCSROutputFormat = new StringArgument(null, 2413 "output-format", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_FORMAT.get(), 2414 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_FORMAT_DESC.get(), 2415 signCSROutputFormatAllowedValues, "PEM"); 2416 signCSROutputFormat.addLongIdentifier("outputFormat", true); 2417 signCSRParser.addArgument(signCSROutputFormat); 2418 2419 final FileArgument signCSRKeystore = new FileArgument(null, "keystore", 2420 true, 1, null, INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_KS_DESC.get(), true, 2421 true, true, false); 2422 signCSRKeystore.addLongIdentifier("keystore-path", true); 2423 signCSRKeystore.addLongIdentifier("keystorePath", true); 2424 signCSRKeystore.addLongIdentifier("keystore-file", true); 2425 signCSRKeystore.addLongIdentifier("keystoreFile", true); 2426 signCSRParser.addArgument(signCSRKeystore); 2427 2428 final StringArgument signCSRKeystorePassword = new StringArgument(null, 2429 "keystore-password", false, 1, 2430 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 2431 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_KS_PW_DESC.get()); 2432 signCSRKeystorePassword.addLongIdentifier("keystorePassword", true); 2433 signCSRKeystorePassword.addLongIdentifier("keystore-passphrase", true); 2434 signCSRKeystorePassword.addLongIdentifier("keystorePassphrase", true); 2435 signCSRKeystorePassword.addLongIdentifier("keystore-pin", true); 2436 signCSRKeystorePassword.addLongIdentifier("keystorePIN", true); 2437 signCSRKeystorePassword.addLongIdentifier("storepass", true); 2438 signCSRKeystorePassword.setSensitive(true); 2439 signCSRParser.addArgument(signCSRKeystorePassword); 2440 2441 final FileArgument signCSRKeystorePasswordFile = new FileArgument(null, 2442 "keystore-password-file", false, 1, null, 2443 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_KS_PW_FILE_DESC.get(), true, true, 2444 true, false); 2445 signCSRKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 2446 true); 2447 signCSRKeystorePasswordFile.addLongIdentifier("keystore-passphrase-file", 2448 true); 2449 signCSRKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 2450 true); 2451 signCSRKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 2452 true); 2453 signCSRKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 2454 signCSRParser.addArgument(signCSRKeystorePasswordFile); 2455 2456 final BooleanArgument signCSRPromptForKeystorePassword = 2457 new BooleanArgument(null, "prompt-for-keystore-password", 2458 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_PROMPT_FOR_KS_PW_DESC.get()); 2459 signCSRPromptForKeystorePassword.addLongIdentifier( 2460 "promptForKeystorePassword", true); 2461 signCSRPromptForKeystorePassword.addLongIdentifier( 2462 "prompt-for-keystore-passphrase", true); 2463 signCSRPromptForKeystorePassword.addLongIdentifier( 2464 "promptForKeystorePassphrase", true); 2465 signCSRPromptForKeystorePassword.addLongIdentifier( 2466 "prompt-for-keystore-pin", true); 2467 signCSRPromptForKeystorePassword.addLongIdentifier( 2468 "promptForKeystorePIN", true); 2469 signCSRParser.addArgument(signCSRPromptForKeystorePassword); 2470 2471 final StringArgument signCSRPKPassword = new StringArgument(null, 2472 "private-key-password", false, 1, 2473 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 2474 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_PK_PW_DESC.get()); 2475 signCSRPKPassword.addLongIdentifier("privateKeyPassword", true); 2476 signCSRPKPassword.addLongIdentifier("private-key-passphrase", true); 2477 signCSRPKPassword.addLongIdentifier("privateKeyPassphrase", true); 2478 signCSRPKPassword.addLongIdentifier("private-key-pin", true); 2479 signCSRPKPassword.addLongIdentifier("privateKeyPIN", true); 2480 signCSRPKPassword.addLongIdentifier("key-password", true); 2481 signCSRPKPassword.addLongIdentifier("keyPassword", true); 2482 signCSRPKPassword.addLongIdentifier("key-passphrase", true); 2483 signCSRPKPassword.addLongIdentifier("keyPassphrase", true); 2484 signCSRPKPassword.addLongIdentifier("key-pin", true); 2485 signCSRPKPassword.addLongIdentifier("keyPIN", true); 2486 signCSRPKPassword.addLongIdentifier("keypass", true); 2487 signCSRPKPassword.setSensitive(true); 2488 signCSRParser.addArgument(signCSRPKPassword); 2489 2490 final FileArgument signCSRPKPasswordFile = new FileArgument(null, 2491 "private-key-password-file", false, 1, null, 2492 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_PK_PW_FILE_DESC.get(), true, true, 2493 true, false); 2494 signCSRPKPasswordFile.addLongIdentifier("privateKeyPasswordFile", true); 2495 signCSRPKPasswordFile.addLongIdentifier("private-key-passphrase-file", 2496 true); 2497 signCSRPKPasswordFile.addLongIdentifier("privateKeyPassphraseFile", 2498 true); 2499 signCSRPKPasswordFile.addLongIdentifier("private-key-pin-file", 2500 true); 2501 signCSRPKPasswordFile.addLongIdentifier("privateKeyPINFile", true); 2502 signCSRPKPasswordFile.addLongIdentifier("key-password-file", true); 2503 signCSRPKPasswordFile.addLongIdentifier("keyPasswordFile", true); 2504 signCSRPKPasswordFile.addLongIdentifier("key-passphrase-file", 2505 true); 2506 signCSRPKPasswordFile.addLongIdentifier("keyPassphraseFile", 2507 true); 2508 signCSRPKPasswordFile.addLongIdentifier("key-pin-file", 2509 true); 2510 signCSRPKPasswordFile.addLongIdentifier("keyPINFile", true); 2511 signCSRParser.addArgument(signCSRPKPasswordFile); 2512 2513 final BooleanArgument signCSRPromptForPKPassword = 2514 new BooleanArgument(null, "prompt-for-private-key-password", 2515 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_PROMPT_FOR_PK_PW_DESC.get()); 2516 signCSRPromptForPKPassword.addLongIdentifier( 2517 "promptForPrivateKeyPassword", true); 2518 signCSRPromptForPKPassword.addLongIdentifier( 2519 "prompt-for-private-key-passphrase", true); 2520 signCSRPromptForPKPassword.addLongIdentifier( 2521 "promptForPrivateKeyPassphrase", true); 2522 signCSRPromptForPKPassword.addLongIdentifier("prompt-for-private-key-pin", 2523 true); 2524 signCSRPromptForPKPassword.addLongIdentifier("promptForPrivateKeyPIN", 2525 true); 2526 signCSRPromptForPKPassword.addLongIdentifier("prompt-for-key-password", 2527 true); 2528 signCSRPromptForPKPassword.addLongIdentifier("promptForKeyPassword", 2529 true); 2530 signCSRPromptForPKPassword.addLongIdentifier( 2531 "prompt-for-key-passphrase", true); 2532 signCSRPromptForPKPassword.addLongIdentifier( 2533 "promptForKeyPassphrase", true); 2534 signCSRPromptForPKPassword.addLongIdentifier("prompt-for-key-pin", true); 2535 signCSRPromptForPKPassword.addLongIdentifier("promptForKeyPIN", true); 2536 signCSRParser.addArgument(signCSRPromptForPKPassword); 2537 2538 final StringArgument signCSRKeystoreType = new StringArgument(null, 2539 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 2540 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_KS_TYPE_DESC.get(), 2541 ALLOWED_KEYSTORE_TYPE_VALUES); 2542 signCSRKeystoreType.addLongIdentifier("key-store-type", true); 2543 signCSRKeystoreType.addLongIdentifier("keystoreType", true); 2544 signCSRKeystoreType.addLongIdentifier("keystore-format", true); 2545 signCSRKeystoreType.addLongIdentifier("key-store-format", true); 2546 signCSRKeystoreType.addLongIdentifier("keystoreFormat", true); 2547 signCSRKeystoreType.addLongIdentifier("storetype", true); 2548 signCSRParser.addArgument(signCSRKeystoreType); 2549 2550 final StringArgument signCSRAlias = new StringArgument(null, 2551 "signing-certificate-alias", 2552 true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 2553 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_ALIAS_DESC.get()); 2554 signCSRAlias.addLongIdentifier("signingCertificateAlias", true); 2555 signCSRAlias.addLongIdentifier("signing-certificate-nickname", true); 2556 signCSRAlias.addLongIdentifier("signingCertificateNickname", true); 2557 signCSRAlias.addLongIdentifier("alias", true); 2558 signCSRAlias.addLongIdentifier("nickname", true); 2559 signCSRParser.addArgument(signCSRAlias); 2560 2561 final DNArgument signCSRSubjectDN = new DNArgument(null, "subject-dn", 2562 false, 1, null, 2563 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_SUBJECT_DN_DESC.get()); 2564 signCSRSubjectDN.addLongIdentifier("subjectDN", true); 2565 signCSRSubjectDN.addLongIdentifier("subject", true); 2566 signCSRSubjectDN.addLongIdentifier("dname", true); 2567 signCSRParser.addArgument(signCSRSubjectDN); 2568 2569 final IntegerArgument signCSRDaysValid = new IntegerArgument(null, 2570 "days-valid", false, 1, null, 2571 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_DAYS_VALID_DESC.get(), 1, 2572 Integer.MAX_VALUE); 2573 signCSRDaysValid.addLongIdentifier("daysValid", true); 2574 signCSRDaysValid.addLongIdentifier("validity", true); 2575 signCSRParser.addArgument(signCSRDaysValid); 2576 2577 final TimestampArgument signCSRNotBefore = new TimestampArgument(null, 2578 "validity-start-time", false, 1, 2579 INFO_MANAGE_CERTS_PLACEHOLDER_TIMESTAMP.get(), 2580 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_VALIDITY_START_TIME_DESC.get( 2581 "20180102123456")); 2582 signCSRNotBefore.addLongIdentifier("validityStartTime", true); 2583 signCSRNotBefore.addLongIdentifier("not-before", true); 2584 signCSRNotBefore.addLongIdentifier("notBefore", true); 2585 signCSRParser.addArgument(signCSRNotBefore); 2586 2587 final StringArgument signCSRSignatureAlgorithm = new StringArgument(null, 2588 "signature-algorithm", false, 1, 2589 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2590 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_SIG_ALG_DESC.get()); 2591 signCSRSignatureAlgorithm.addLongIdentifier("signatureAlgorithm", true); 2592 signCSRSignatureAlgorithm.addLongIdentifier("signature-alg", true); 2593 signCSRSignatureAlgorithm.addLongIdentifier("signatureAlg", true); 2594 signCSRSignatureAlgorithm.addLongIdentifier("sig-alg", true); 2595 signCSRSignatureAlgorithm.addLongIdentifier("sigAlg", true); 2596 signCSRParser.addArgument(signCSRSignatureAlgorithm); 2597 2598 final BooleanArgument signCSRIncludeExtensions = new BooleanArgument(null, 2599 "include-requested-extensions", 1, 2600 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_INCLUDE_EXT_DESC.get()); 2601 signCSRIncludeExtensions.addLongIdentifier("includeRequestedExtensions", 2602 true); 2603 signCSRParser.addArgument(signCSRIncludeExtensions); 2604 2605 final StringArgument signCSRSubjectAltDNS = new StringArgument(null, 2606 "subject-alternative-name-dns", false, 0, 2607 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2608 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_SAN_DNS_DESC.get()); 2609 signCSRSubjectAltDNS.addLongIdentifier("subjectAlternativeNameDNS", true); 2610 signCSRSubjectAltDNS.addLongIdentifier("subject-alt-name-dns", true); 2611 signCSRSubjectAltDNS.addLongIdentifier("subjectAltNameDNS", true); 2612 signCSRSubjectAltDNS.addLongIdentifier("subject-alternative-dns", true); 2613 signCSRSubjectAltDNS.addLongIdentifier("subjectAlternativeDNS", true); 2614 signCSRSubjectAltDNS.addLongIdentifier("subject-alt-dns", true); 2615 signCSRSubjectAltDNS.addLongIdentifier("subjectAltDNS", true); 2616 signCSRSubjectAltDNS.addLongIdentifier("san-dns", true); 2617 signCSRSubjectAltDNS.addLongIdentifier("sanDNS", true); 2618 signCSRSubjectAltDNS.addValueValidator( 2619 new IA5StringArgumentValueValidator(false)); 2620 signCSRParser.addArgument(signCSRSubjectAltDNS); 2621 2622 final StringArgument signCSRSubjectAltIP = new StringArgument(null, 2623 "subject-alternative-name-ip-address", false, 0, 2624 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2625 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_SAN_IP_DESC.get()); 2626 signCSRSubjectAltIP.addLongIdentifier("subjectAlternativeNameIPAddress", 2627 true); 2628 signCSRSubjectAltIP.addLongIdentifier("subject-alternative-name-ip", true); 2629 signCSRSubjectAltIP.addLongIdentifier("subjectAlternativeNameIP", true); 2630 signCSRSubjectAltIP.addLongIdentifier("subject-alt-name-ip-address", true); 2631 signCSRSubjectAltIP.addLongIdentifier("subjectAltNameIPAddress", true); 2632 signCSRSubjectAltIP.addLongIdentifier("subject-alt-name-ip", true); 2633 signCSRSubjectAltIP.addLongIdentifier("subjectAltNameIP", true); 2634 signCSRSubjectAltIP.addLongIdentifier("subject-alternative-ip-address", 2635 true); 2636 signCSRSubjectAltIP.addLongIdentifier("subjectAlternativeIPAddress", true); 2637 signCSRSubjectAltIP.addLongIdentifier("subject-alternative-ip", true); 2638 signCSRSubjectAltIP.addLongIdentifier("subjectAlternativeIP", true); 2639 signCSRSubjectAltIP.addLongIdentifier("subject-alt-ip-address", true); 2640 signCSRSubjectAltIP.addLongIdentifier("subjectAltIPAddress", true); 2641 signCSRSubjectAltIP.addLongIdentifier("subject-alt-ip", true); 2642 signCSRSubjectAltIP.addLongIdentifier("subjectAltIP", true); 2643 signCSRSubjectAltIP.addLongIdentifier("san-ip-address", true); 2644 signCSRSubjectAltIP.addLongIdentifier("sanIPAddress", true); 2645 signCSRSubjectAltIP.addLongIdentifier("san-ip", true); 2646 signCSRSubjectAltIP.addLongIdentifier("sanIP", true); 2647 signCSRSubjectAltIP.addValueValidator( 2648 new IPAddressArgumentValueValidator(true, true)); 2649 signCSRParser.addArgument(signCSRSubjectAltIP); 2650 2651 final StringArgument signCSRSubjectAltEmail = new StringArgument(null, 2652 "subject-alternative-name-email-address", false, 0, 2653 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2654 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_SAN_EMAIL_DESC.get()); 2655 signCSRSubjectAltEmail.addLongIdentifier( 2656 "subjectAlternativeNameEmailAddress", true); 2657 signCSRSubjectAltEmail.addLongIdentifier("subject-alternative-name-email", 2658 true); 2659 signCSRSubjectAltEmail.addLongIdentifier("subjectAlternativeNameEmail", 2660 true); 2661 signCSRSubjectAltEmail.addLongIdentifier("subject-alt-name-email-address", 2662 true); 2663 signCSRSubjectAltEmail.addLongIdentifier("subjectAltNameEmailAddress", 2664 true); 2665 signCSRSubjectAltEmail.addLongIdentifier("subject-alt-name-email", true); 2666 signCSRSubjectAltEmail.addLongIdentifier("subjectAltNameEmail", true); 2667 signCSRSubjectAltEmail.addLongIdentifier( 2668 "subject-alternative-email-address", true); 2669 signCSRSubjectAltEmail.addLongIdentifier("subjectAlternativeEmailAddress", 2670 true); 2671 signCSRSubjectAltEmail.addLongIdentifier("subject-alternative-email", true); 2672 signCSRSubjectAltEmail.addLongIdentifier("subjectAlternativeEmail", true); 2673 signCSRSubjectAltEmail.addLongIdentifier("subject-alt-email-address", true); 2674 signCSRSubjectAltEmail.addLongIdentifier("subjectAltEmailAddress", true); 2675 signCSRSubjectAltEmail.addLongIdentifier("subject-alt-email", true); 2676 signCSRSubjectAltEmail.addLongIdentifier("subjectAltEmail", true); 2677 signCSRSubjectAltEmail.addLongIdentifier("san-email-address", true); 2678 signCSRSubjectAltEmail.addLongIdentifier("sanEmailAddress", true); 2679 signCSRSubjectAltEmail.addLongIdentifier("san-email", true); 2680 signCSRSubjectAltEmail.addLongIdentifier("sanEmail", true); 2681 signCSRSubjectAltEmail.addValueValidator( 2682 new IA5StringArgumentValueValidator(false)); 2683 signCSRParser.addArgument(signCSRSubjectAltEmail); 2684 2685 final StringArgument signCSRSubjectAltURI = new StringArgument(null, 2686 "subject-alternative-name-uri", false, 0, 2687 INFO_MANAGE_CERTS_PLACEHOLDER_URI.get(), 2688 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_SAN_URI_DESC.get()); 2689 signCSRSubjectAltURI.addLongIdentifier("subjectAlternativeNameURI", true); 2690 signCSRSubjectAltURI.addLongIdentifier("subject-alt-name-uri", true); 2691 signCSRSubjectAltURI.addLongIdentifier("subjectAltNameURI", true); 2692 signCSRSubjectAltURI.addLongIdentifier("subject-alternative-uri", true); 2693 signCSRSubjectAltURI.addLongIdentifier("subjectAlternativeURI", true); 2694 signCSRSubjectAltURI.addLongIdentifier("subject-alt-uri", true); 2695 signCSRSubjectAltURI.addLongIdentifier("subjectAltURI", true); 2696 signCSRSubjectAltURI.addLongIdentifier("san-uri", true); 2697 signCSRSubjectAltURI.addLongIdentifier("sanURI", true); 2698 signCSRParser.addArgument(signCSRSubjectAltURI); 2699 2700 final StringArgument signCSRSubjectAltOID = new StringArgument(null, 2701 "subject-alternative-name-oid", false, 0, 2702 INFO_MANAGE_CERTS_PLACEHOLDER_OID.get(), 2703 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_SAN_OID_DESC.get()); 2704 signCSRSubjectAltOID.addLongIdentifier("subjectAlternativeNameOID", true); 2705 signCSRSubjectAltOID.addLongIdentifier("subject-alt-name-oid", true); 2706 signCSRSubjectAltOID.addLongIdentifier("subjectAltNameOID", true); 2707 signCSRSubjectAltOID.addLongIdentifier("subject-alternative-oid", true); 2708 signCSRSubjectAltOID.addLongIdentifier("subjectAlternativeOID", true); 2709 signCSRSubjectAltOID.addLongIdentifier("subject-alt-oid", true); 2710 signCSRSubjectAltOID.addLongIdentifier("subjectAltOID", true); 2711 signCSRSubjectAltOID.addLongIdentifier("san-oid", true); 2712 signCSRSubjectAltOID.addLongIdentifier("sanOID", true); 2713 signCSRSubjectAltOID.addValueValidator(new OIDArgumentValueValidator(true)); 2714 signCSRParser.addArgument(signCSRSubjectAltOID); 2715 2716 final StringArgument signCSRIssuerAltDNS = new StringArgument(null, 2717 "issuer-alternative-name-dns", false, 0, 2718 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2719 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_IAN_DNS_DESC.get()); 2720 signCSRIssuerAltDNS.addLongIdentifier("issuerAlternativeNameDNS", true); 2721 signCSRIssuerAltDNS.addLongIdentifier("issuer-alt-name-dns", true); 2722 signCSRIssuerAltDNS.addLongIdentifier("issuerAltNameDNS", true); 2723 signCSRIssuerAltDNS.addLongIdentifier("issuer-alternative-dns", true); 2724 signCSRIssuerAltDNS.addLongIdentifier("issuerAlternativeDNS", true); 2725 signCSRIssuerAltDNS.addLongIdentifier("issuer-alt-dns", true); 2726 signCSRIssuerAltDNS.addLongIdentifier("issuerAltDNS", true); 2727 signCSRIssuerAltDNS.addLongIdentifier("ian-dns", true); 2728 signCSRIssuerAltDNS.addLongIdentifier("ianDNS", true); 2729 signCSRIssuerAltDNS.addValueValidator( 2730 new IA5StringArgumentValueValidator(false)); 2731 signCSRParser.addArgument(signCSRIssuerAltDNS); 2732 2733 final StringArgument signCSRIssuerAltIP = new StringArgument(null, 2734 "issuer-alternative-name-ip-address", false, 0, 2735 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2736 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_IAN_IP_DESC.get()); 2737 signCSRIssuerAltIP.addLongIdentifier("issuerAlternativeNameIPAddress", 2738 true); 2739 signCSRIssuerAltIP.addLongIdentifier("issuer-alternative-name-ip", true); 2740 signCSRIssuerAltIP.addLongIdentifier("issuerAlternativeNameIP", true); 2741 signCSRIssuerAltIP.addLongIdentifier("issuer-alt-name-ip-address", true); 2742 signCSRIssuerAltIP.addLongIdentifier("issuerAltNameIPAddress", true); 2743 signCSRIssuerAltIP.addLongIdentifier("issuer-alt-name-ip", true); 2744 signCSRIssuerAltIP.addLongIdentifier("issuerAltNameIP", true); 2745 signCSRIssuerAltIP.addLongIdentifier("issuer-alternative-ip-address", 2746 true); 2747 signCSRIssuerAltIP.addLongIdentifier("issuerAlternativeIPAddress", true); 2748 signCSRIssuerAltIP.addLongIdentifier("issuer-alternative-ip", true); 2749 signCSRIssuerAltIP.addLongIdentifier("issuerAlternativeIP", true); 2750 signCSRIssuerAltIP.addLongIdentifier("issuer-alt-ip-address", true); 2751 signCSRIssuerAltIP.addLongIdentifier("issuerAltIPAddress", true); 2752 signCSRIssuerAltIP.addLongIdentifier("issuer-alt-ip", true); 2753 signCSRIssuerAltIP.addLongIdentifier("issuerAltIP", true); 2754 signCSRIssuerAltIP.addLongIdentifier("ian-ip-address", true); 2755 signCSRIssuerAltIP.addLongIdentifier("ianIPAddress", true); 2756 signCSRIssuerAltIP.addLongIdentifier("ian-ip", true); 2757 signCSRIssuerAltIP.addLongIdentifier("ianIP", true); 2758 signCSRIssuerAltIP.addValueValidator( 2759 new IPAddressArgumentValueValidator(true, true)); 2760 signCSRParser.addArgument(signCSRIssuerAltIP); 2761 2762 final StringArgument signCSRIssuerAltEmail = new StringArgument(null, 2763 "issuer-alternative-name-email-address", false, 0, 2764 INFO_MANAGE_CERTS_PLACEHOLDER_NAME.get(), 2765 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_IAN_EMAIL_DESC.get()); 2766 signCSRIssuerAltEmail.addLongIdentifier( 2767 "issuerAlternativeNameEmailAddress", true); 2768 signCSRIssuerAltEmail.addLongIdentifier("issuer-alternative-name-email", 2769 true); 2770 signCSRIssuerAltEmail.addLongIdentifier("issuerAlternativeNameEmail", 2771 true); 2772 signCSRIssuerAltEmail.addLongIdentifier("issuer-alt-name-email-address", 2773 true); 2774 signCSRIssuerAltEmail.addLongIdentifier("issuerAltNameEmailAddress", 2775 true); 2776 signCSRIssuerAltEmail.addLongIdentifier("issuer-alt-name-email", true); 2777 signCSRIssuerAltEmail.addLongIdentifier("issuerAltNameEmail", true); 2778 signCSRIssuerAltEmail.addLongIdentifier( 2779 "issuer-alternative-email-address", true); 2780 signCSRIssuerAltEmail.addLongIdentifier("issuerAlternativeEmailAddress", 2781 true); 2782 signCSRIssuerAltEmail.addLongIdentifier("issuer-alternative-email", true); 2783 signCSRIssuerAltEmail.addLongIdentifier("issuerAlternativeEmail", true); 2784 signCSRIssuerAltEmail.addLongIdentifier("issuer-alt-email-address", true); 2785 signCSRIssuerAltEmail.addLongIdentifier("issuerAltEmailAddress", true); 2786 signCSRIssuerAltEmail.addLongIdentifier("issuer-alt-email", true); 2787 signCSRIssuerAltEmail.addLongIdentifier("issuerAltEmail", true); 2788 signCSRIssuerAltEmail.addLongIdentifier("ian-email-address", true); 2789 signCSRIssuerAltEmail.addLongIdentifier("ianEmailAddress", true); 2790 signCSRIssuerAltEmail.addLongIdentifier("ian-email", true); 2791 signCSRIssuerAltEmail.addLongIdentifier("ianEmail", true); 2792 signCSRIssuerAltEmail.addValueValidator( 2793 new IA5StringArgumentValueValidator(false)); 2794 signCSRParser.addArgument(signCSRIssuerAltEmail); 2795 2796 final StringArgument signCSRIssuerAltURI = new StringArgument(null, 2797 "issuer-alternative-name-uri", false, 0, 2798 INFO_MANAGE_CERTS_PLACEHOLDER_URI.get(), 2799 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_IAN_URI_DESC.get()); 2800 signCSRIssuerAltURI.addLongIdentifier("issuerAlternativeNameURI", true); 2801 signCSRIssuerAltURI.addLongIdentifier("issuer-alt-name-uri", true); 2802 signCSRIssuerAltURI.addLongIdentifier("issuerAltNameURI", true); 2803 signCSRIssuerAltURI.addLongIdentifier("issuer-alternative-uri", true); 2804 signCSRIssuerAltURI.addLongIdentifier("issuerAlternativeURI", true); 2805 signCSRIssuerAltURI.addLongIdentifier("issuer-alt-uri", true); 2806 signCSRIssuerAltURI.addLongIdentifier("issuerAltURI", true); 2807 signCSRIssuerAltURI.addLongIdentifier("ian-uri", true); 2808 signCSRIssuerAltURI.addLongIdentifier("ianURI", true); 2809 signCSRParser.addArgument(signCSRIssuerAltURI); 2810 2811 final StringArgument signCSRIssuerAltOID = new StringArgument(null, 2812 "issuer-alternative-name-oid", false, 0, 2813 INFO_MANAGE_CERTS_PLACEHOLDER_OID.get(), 2814 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_IAN_OID_DESC.get()); 2815 signCSRIssuerAltOID.addLongIdentifier("issuerAlternativeNameOID", true); 2816 signCSRIssuerAltOID.addLongIdentifier("issuer-alt-name-oid", true); 2817 signCSRIssuerAltOID.addLongIdentifier("issuerAltNameOID", true); 2818 signCSRIssuerAltOID.addLongIdentifier("issuer-alternative-oid", true); 2819 signCSRIssuerAltOID.addLongIdentifier("issuerAlternativeOID", true); 2820 signCSRIssuerAltOID.addLongIdentifier("issuer-alt-oid", true); 2821 signCSRIssuerAltOID.addLongIdentifier("issuerAltOID", true); 2822 signCSRIssuerAltOID.addLongIdentifier("ian-oid", true); 2823 signCSRIssuerAltOID.addLongIdentifier("ianOID", true); 2824 signCSRIssuerAltOID.addValueValidator(new OIDArgumentValueValidator(true)); 2825 signCSRParser.addArgument(signCSRIssuerAltOID); 2826 2827 final BooleanValueArgument signCSRBasicConstraintsIsCA = 2828 new BooleanValueArgument(null, "basic-constraints-is-ca", false, null, 2829 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_BC_IS_CA_DESC.get()); 2830 signCSRBasicConstraintsIsCA.addLongIdentifier("basicConstraintsIsCA", true); 2831 signCSRBasicConstraintsIsCA.addLongIdentifier("bc-is-ca", true); 2832 signCSRBasicConstraintsIsCA.addLongIdentifier("bcIsCA", true); 2833 signCSRParser.addArgument(signCSRBasicConstraintsIsCA); 2834 2835 final IntegerArgument signCSRBasicConstraintsPathLength = 2836 new IntegerArgument(null, "basic-constraints-maximum-path-length", 2837 false, 1, null, 2838 INFO_MANAGE_CERTS_SC_GEN_CERT_ARG_BC_PATH_LENGTH_DESC.get(), 0, 2839 Integer.MAX_VALUE); 2840 signCSRBasicConstraintsPathLength.addLongIdentifier( 2841 "basicConstraintsMaximumPathLength", true); 2842 signCSRBasicConstraintsPathLength.addLongIdentifier( 2843 "basic-constraints-max-path-length", true); 2844 signCSRBasicConstraintsPathLength.addLongIdentifier( 2845 "basicConstraintsMaxPathLength", true); 2846 signCSRBasicConstraintsPathLength.addLongIdentifier( 2847 "basic-constraints-path-length", true); 2848 signCSRBasicConstraintsPathLength.addLongIdentifier( 2849 "basicConstraintsPathLength", true); 2850 signCSRBasicConstraintsPathLength.addLongIdentifier( 2851 "bc-maximum-path-length", true); 2852 signCSRBasicConstraintsPathLength.addLongIdentifier("bcMaximumPathLength", 2853 true); 2854 signCSRBasicConstraintsPathLength.addLongIdentifier("bc-max-path-length", 2855 true); 2856 signCSRBasicConstraintsPathLength.addLongIdentifier("bcMaxPathLength", 2857 true); 2858 signCSRBasicConstraintsPathLength.addLongIdentifier("bc-path-length", true); 2859 signCSRBasicConstraintsPathLength.addLongIdentifier("bcPathLength", true); 2860 signCSRParser.addArgument(signCSRBasicConstraintsPathLength); 2861 2862 final StringArgument signCSRKeyUsage = new StringArgument(null, "key-usage", 2863 false, 0, null, INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_KU_DESC.get()); 2864 signCSRKeyUsage.addLongIdentifier("keyUsage", true); 2865 signCSRParser.addArgument(signCSRKeyUsage); 2866 2867 final StringArgument signCSRExtendedKeyUsage = new StringArgument(null, 2868 "extended-key-usage", false, 0, null, 2869 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_EKU_DESC.get()); 2870 signCSRExtendedKeyUsage.addLongIdentifier("extendedKeyUsage", true); 2871 signCSRParser.addArgument(signCSRExtendedKeyUsage); 2872 2873 final StringArgument signCSRExtension = new StringArgument(null, 2874 "extension", false, 0, null, 2875 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_EXT_DESC.get()); 2876 signCSRExtension.addLongIdentifier("ext", true); 2877 signCSRParser.addArgument(signCSRExtension); 2878 2879 final BooleanArgument signCSRNoPrompt = new BooleanArgument(null, 2880 "no-prompt", 1, 2881 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_NO_PROMPT_DESC.get()); 2882 signCSRNoPrompt.addLongIdentifier("noPrompt", true); 2883 signCSRParser.addArgument(signCSRNoPrompt); 2884 2885 final BooleanArgument signCSRDisplayCommand = new BooleanArgument(null, 2886 "display-keytool-command", 1, 2887 INFO_MANAGE_CERTS_SC_SIGN_CSR_ARG_DISPLAY_COMMAND_DESC.get()); 2888 signCSRDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 2889 signCSRDisplayCommand.addLongIdentifier("show-keytool-command", true); 2890 signCSRDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 2891 signCSRParser.addArgument(signCSRDisplayCommand); 2892 2893 signCSRParser.addRequiredArgumentSet(signCSRKeystorePassword, 2894 signCSRKeystorePasswordFile, signCSRPromptForKeystorePassword); 2895 signCSRParser.addExclusiveArgumentSet(signCSRKeystorePassword, 2896 signCSRKeystorePasswordFile, signCSRPromptForKeystorePassword); 2897 signCSRParser.addExclusiveArgumentSet(signCSRPKPassword, 2898 signCSRPKPasswordFile, signCSRPromptForPKPassword); 2899 signCSRParser.addDependentArgumentSet(signCSRBasicConstraintsPathLength, 2900 signCSRBasicConstraintsIsCA); 2901 2902 final LinkedHashMap<String[],String> signCSRExamples = 2903 new LinkedHashMap<>(StaticUtils.computeMapCapacity(2)); 2904 signCSRExamples.put( 2905 new String[] 2906 { 2907 "sign-certificate-signing-request", 2908 "--request-input-file", "server-cert.csr", 2909 "--keystore", getPlatformSpecificPath("config", "keystore"), 2910 "--keystore-password-file", 2911 getPlatformSpecificPath("config", "keystore.pin"), 2912 "--signing-certificate-alias", "ca-cert", 2913 "--include-requested-extensions" 2914 }, 2915 INFO_MANAGE_CERTS_SC_SIGN_CSR_EXAMPLE_1.get( 2916 getPlatformSpecificPath("config", "keystore"))); 2917 signCSRExamples.put( 2918 new String[] 2919 { 2920 "sign-certificate-signing-request", 2921 "--request-input-file", "server-cert.csr", 2922 "--certificate-output-file", "server-cert.der", 2923 "--output-format", "DER", 2924 "--keystore", getPlatformSpecificPath("config", "keystore"), 2925 "--keystore-password-file", 2926 getPlatformSpecificPath("config", "keystore.pin"), 2927 "--signing-certificate-alias", "ca-cert", 2928 "--days-valid", "730", 2929 "--validity-start-time", "20170101000000", 2930 "--include-requested-extensions", 2931 "--issuer-alternative-name-email-address", "ca@example.com", 2932 }, 2933 INFO_MANAGE_CERTS_SC_SIGN_CSR_EXAMPLE_2.get( 2934 getPlatformSpecificPath("config", "keystore"))); 2935 2936 final SubCommand signCSRSubCommand = new SubCommand( 2937 "sign-certificate-signing-request", 2938 INFO_MANAGE_CERTS_SC_SIGN_CSR_DESC.get(), signCSRParser, 2939 signCSRExamples); 2940 signCSRSubCommand.addName("signCertificateSigningRequest", true); 2941 signCSRSubCommand.addName("sign-certificate-request", true); 2942 signCSRSubCommand.addName("signCertificateRequest", true); 2943 signCSRSubCommand.addName("sign-certificate", true); 2944 signCSRSubCommand.addName("signCertificate", true); 2945 signCSRSubCommand.addName("sign-csr", true); 2946 signCSRSubCommand.addName("signCSR", true); 2947 signCSRSubCommand.addName("sign", true); 2948 signCSRSubCommand.addName("gencert", true); 2949 2950 parser.addSubCommand(signCSRSubCommand); 2951 2952 2953 // Define the "change-certificate-alias" subcommand and all of its 2954 // arguments. 2955 final ArgumentParser changeAliasParser = new ArgumentParser( 2956 "change-certificate-alias", 2957 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_DESC.get()); 2958 2959 final FileArgument changeAliasKeystore = new FileArgument(null, "keystore", 2960 true, 1, null, INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_KS_DESC.get(), 2961 true, true, true, false); 2962 changeAliasKeystore.addLongIdentifier("keystore-path", true); 2963 changeAliasKeystore.addLongIdentifier("keystorePath", true); 2964 changeAliasKeystore.addLongIdentifier("keystore-file", true); 2965 changeAliasKeystore.addLongIdentifier("keystoreFile", true); 2966 changeAliasParser.addArgument(changeAliasKeystore); 2967 2968 final StringArgument changeAliasKeystorePassword = new StringArgument(null, 2969 "keystore-password", false, 1, 2970 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 2971 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_KS_PW_DESC.get()); 2972 changeAliasKeystorePassword.addLongIdentifier("keystorePassword", true); 2973 changeAliasKeystorePassword.addLongIdentifier("keystore-passphrase", true); 2974 changeAliasKeystorePassword.addLongIdentifier("keystorePassphrase", true); 2975 changeAliasKeystorePassword.addLongIdentifier("keystore-pin", true); 2976 changeAliasKeystorePassword.addLongIdentifier("keystorePIN", true); 2977 changeAliasKeystorePassword.addLongIdentifier("storepass", true); 2978 changeAliasKeystorePassword.setSensitive(true); 2979 changeAliasParser.addArgument(changeAliasKeystorePassword); 2980 2981 final FileArgument changeAliasKeystorePasswordFile = new FileArgument(null, 2982 "keystore-password-file", false, 1, null, 2983 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_KS_PW_FILE_DESC.get(), true, 2984 true, true, false); 2985 changeAliasKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 2986 true); 2987 changeAliasKeystorePasswordFile.addLongIdentifier( 2988 "keystore-passphrase-file", true); 2989 changeAliasKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 2990 true); 2991 changeAliasKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 2992 true); 2993 changeAliasKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 2994 changeAliasParser.addArgument(changeAliasKeystorePasswordFile); 2995 2996 final BooleanArgument changeAliasPromptForKeystorePassword = 2997 new BooleanArgument(null, "prompt-for-keystore-password", 2998 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_PROMPT_FOR_KS_PW_DESC.get()); 2999 changeAliasPromptForKeystorePassword.addLongIdentifier( 3000 "promptForKeystorePassword", true); 3001 changeAliasPromptForKeystorePassword.addLongIdentifier( 3002 "prompt-for-keystore-passphrase", true); 3003 changeAliasPromptForKeystorePassword.addLongIdentifier( 3004 "promptForKeystorePassphrase", true); 3005 changeAliasPromptForKeystorePassword.addLongIdentifier( 3006 "prompt-for-keystore-pin", true); 3007 changeAliasPromptForKeystorePassword.addLongIdentifier( 3008 "promptForKeystorePIN", true); 3009 changeAliasParser.addArgument(changeAliasPromptForKeystorePassword); 3010 3011 final StringArgument changeAliasPKPassword = new StringArgument(null, 3012 "private-key-password", false, 1, 3013 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3014 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_PK_PW_DESC.get()); 3015 changeAliasPKPassword.addLongIdentifier("privateKeyPassword", true); 3016 changeAliasPKPassword.addLongIdentifier("private-key-passphrase", true); 3017 changeAliasPKPassword.addLongIdentifier("privateKeyPassphrase", true); 3018 changeAliasPKPassword.addLongIdentifier("private-key-pin", true); 3019 changeAliasPKPassword.addLongIdentifier("privateKeyPIN", true); 3020 changeAliasPKPassword.addLongIdentifier("key-password", true); 3021 changeAliasPKPassword.addLongIdentifier("keyPassword", true); 3022 changeAliasPKPassword.addLongIdentifier("key-passphrase", true); 3023 changeAliasPKPassword.addLongIdentifier("keyPassphrase", true); 3024 changeAliasPKPassword.addLongIdentifier("key-pin", true); 3025 changeAliasPKPassword.addLongIdentifier("keyPIN", true); 3026 changeAliasPKPassword.addLongIdentifier("keypass", true); 3027 changeAliasPKPassword.setSensitive(true); 3028 changeAliasParser.addArgument(changeAliasPKPassword); 3029 3030 final FileArgument changeAliasPKPasswordFile = new FileArgument(null, 3031 "private-key-password-file", false, 1, null, 3032 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_PK_PW_FILE_DESC.get(), true, 3033 true, true, false); 3034 changeAliasPKPasswordFile.addLongIdentifier("privateKeyPasswordFile", true); 3035 changeAliasPKPasswordFile.addLongIdentifier("private-key-passphrase-file", 3036 true); 3037 changeAliasPKPasswordFile.addLongIdentifier("privateKeyPassphraseFile", 3038 true); 3039 changeAliasPKPasswordFile.addLongIdentifier("private-key-pin-file", 3040 true); 3041 changeAliasPKPasswordFile.addLongIdentifier("privateKeyPINFile", true); 3042 changeAliasPKPasswordFile.addLongIdentifier("key-password-file", true); 3043 changeAliasPKPasswordFile.addLongIdentifier("keyPasswordFile", true); 3044 changeAliasPKPasswordFile.addLongIdentifier("key-passphrase-file", 3045 true); 3046 changeAliasPKPasswordFile.addLongIdentifier("keyPassphraseFile", 3047 true); 3048 changeAliasPKPasswordFile.addLongIdentifier("key-pin-file", 3049 true); 3050 changeAliasPKPasswordFile.addLongIdentifier("keyPINFile", true); 3051 changeAliasParser.addArgument(changeAliasPKPasswordFile); 3052 3053 final BooleanArgument changeAliasPromptForPKPassword = 3054 new BooleanArgument(null, "prompt-for-private-key-password", 3055 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_PROMPT_FOR_PK_PW_DESC.get()); 3056 changeAliasPromptForPKPassword.addLongIdentifier( 3057 "promptForPrivateKeyPassword", true); 3058 changeAliasPromptForPKPassword.addLongIdentifier( 3059 "prompt-for-private-key-passphrase", true); 3060 changeAliasPromptForPKPassword.addLongIdentifier( 3061 "promptForPrivateKeyPassphrase", true); 3062 changeAliasPromptForPKPassword.addLongIdentifier( 3063 "prompt-for-private-key-pin", true); 3064 changeAliasPromptForPKPassword.addLongIdentifier("promptForPrivateKeyPIN", 3065 true); 3066 changeAliasPromptForPKPassword.addLongIdentifier("prompt-for-key-password", 3067 true); 3068 changeAliasPromptForPKPassword.addLongIdentifier("promptForKeyPassword", 3069 true); 3070 changeAliasPromptForPKPassword.addLongIdentifier( 3071 "prompt-for-key-passphrase", true); 3072 changeAliasPromptForPKPassword.addLongIdentifier( 3073 "promptForKeyPassphrase", true); 3074 changeAliasPromptForPKPassword.addLongIdentifier("prompt-for-key-pin", 3075 true); 3076 changeAliasPromptForPKPassword.addLongIdentifier("promptForKeyPIN", true); 3077 changeAliasParser.addArgument(changeAliasPromptForPKPassword); 3078 3079 final StringArgument changeAliasKeystoreType = new StringArgument(null, 3080 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 3081 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_KS_TYPE_DESC.get(), 3082 ALLOWED_KEYSTORE_TYPE_VALUES); 3083 changeAliasKeystoreType.addLongIdentifier("key-store-type", true); 3084 changeAliasKeystoreType.addLongIdentifier("keystoreType", true); 3085 changeAliasKeystoreType.addLongIdentifier("keystore-format", true); 3086 changeAliasKeystoreType.addLongIdentifier("key-store-format", true); 3087 changeAliasKeystoreType.addLongIdentifier("keystoreFormat", true); 3088 changeAliasKeystoreType.addLongIdentifier("storetype", true); 3089 changeAliasParser.addArgument(changeAliasKeystoreType); 3090 3091 final StringArgument changeAliasCurrentAlias = new StringArgument(null, 3092 "current-alias", true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 3093 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_CURRENT_ALIAS_DESC.get()); 3094 changeAliasCurrentAlias.addLongIdentifier("currentAlias", true); 3095 changeAliasCurrentAlias.addLongIdentifier("old-alias", true); 3096 changeAliasCurrentAlias.addLongIdentifier("oldAlias", true); 3097 changeAliasCurrentAlias.addLongIdentifier("source-alias", true); 3098 changeAliasCurrentAlias.addLongIdentifier("sourceAlias", true); 3099 changeAliasCurrentAlias.addLongIdentifier("alias", true); 3100 changeAliasCurrentAlias.addLongIdentifier("current-nickname", true); 3101 changeAliasCurrentAlias.addLongIdentifier("currentNickname", true); 3102 changeAliasCurrentAlias.addLongIdentifier("old-nickname", true); 3103 changeAliasCurrentAlias.addLongIdentifier("oldNickname", true); 3104 changeAliasCurrentAlias.addLongIdentifier("source-nickname", true); 3105 changeAliasCurrentAlias.addLongIdentifier("sourceNickname", true); 3106 changeAliasCurrentAlias.addLongIdentifier("nickname", true); 3107 changeAliasCurrentAlias.addLongIdentifier("from", false); 3108 changeAliasParser.addArgument(changeAliasCurrentAlias); 3109 3110 final StringArgument changeAliasNewAlias = new StringArgument(null, 3111 "new-alias", true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 3112 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_NEW_ALIAS_DESC.get()); 3113 changeAliasNewAlias.addLongIdentifier("newAlias", true); 3114 changeAliasNewAlias.addLongIdentifier("destination-alias", true); 3115 changeAliasNewAlias.addLongIdentifier("destinationAlias", true); 3116 changeAliasNewAlias.addLongIdentifier("new-nickname", true); 3117 changeAliasNewAlias.addLongIdentifier("newNickname", true); 3118 changeAliasNewAlias.addLongIdentifier("destination-nickname", true); 3119 changeAliasNewAlias.addLongIdentifier("destinationNickname", true); 3120 changeAliasNewAlias.addLongIdentifier("to", false); 3121 changeAliasParser.addArgument(changeAliasNewAlias); 3122 3123 final BooleanArgument changeAliasDisplayCommand = new BooleanArgument(null, 3124 "display-keytool-command", 1, 3125 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_ARG_DISPLAY_COMMAND_DESC.get()); 3126 changeAliasDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 3127 changeAliasDisplayCommand.addLongIdentifier("show-keytool-command", true); 3128 changeAliasDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 3129 changeAliasParser.addArgument(changeAliasDisplayCommand); 3130 3131 changeAliasParser.addRequiredArgumentSet(changeAliasKeystorePassword, 3132 changeAliasKeystorePasswordFile, changeAliasPromptForKeystorePassword); 3133 changeAliasParser.addExclusiveArgumentSet(changeAliasKeystorePassword, 3134 changeAliasKeystorePasswordFile, changeAliasPromptForKeystorePassword); 3135 changeAliasParser.addExclusiveArgumentSet(changeAliasPKPassword, 3136 changeAliasPKPasswordFile, changeAliasPromptForPKPassword); 3137 3138 final LinkedHashMap<String[],String> changeAliasExamples = 3139 new LinkedHashMap<>(StaticUtils.computeMapCapacity(1)); 3140 changeAliasExamples.put( 3141 new String[] 3142 { 3143 "change-certificate-alias", 3144 "--keystore", getPlatformSpecificPath("config", "keystore"), 3145 "--keystore-password-file", 3146 getPlatformSpecificPath("config", "keystore.pin"), 3147 "--current-alias", "server-cert", 3148 "--new-alias", "server-certificate", 3149 "--display-keytool-command" 3150 }, 3151 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_EXAMPLE_1.get()); 3152 3153 final SubCommand changeAliasSubCommand = new SubCommand( 3154 "change-certificate-alias", 3155 INFO_MANAGE_CERTS_SC_CHANGE_ALIAS_DESC.get(), changeAliasParser, 3156 changeAliasExamples); 3157 changeAliasSubCommand.addName("changeCertificateAlias", true); 3158 changeAliasSubCommand.addName("change-alias", true); 3159 changeAliasSubCommand.addName("changeAlias", true); 3160 changeAliasSubCommand.addName("rename-certificate", true); 3161 changeAliasSubCommand.addName("renameCertificate", true); 3162 changeAliasSubCommand.addName("rename", true); 3163 3164 parser.addSubCommand(changeAliasSubCommand); 3165 3166 3167 // Define the "change-keystore-password" subcommand and all of its 3168 // arguments. 3169 final ArgumentParser changeKSPWParser = new ArgumentParser( 3170 "change-keystore-password", 3171 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_DESC.get()); 3172 3173 final FileArgument changeKSPWKeystore = new FileArgument(null, "keystore", 3174 true, 1, null, INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_ARG_KS_DESC.get(), 3175 true, true, true, false); 3176 changeKSPWKeystore.addLongIdentifier("keystore-path", true); 3177 changeKSPWKeystore.addLongIdentifier("keystorePath", true); 3178 changeKSPWKeystore.addLongIdentifier("keystore-file", true); 3179 changeKSPWKeystore.addLongIdentifier("keystoreFile", true); 3180 changeKSPWParser.addArgument(changeKSPWKeystore); 3181 3182 final StringArgument changeKSPWCurrentPassword = new StringArgument(null, 3183 "current-keystore-password", false, 1, 3184 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3185 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_ARG_CURRENT_PW_DESC.get()); 3186 changeKSPWCurrentPassword.addLongIdentifier("currentKeystorePassword", 3187 true); 3188 changeKSPWCurrentPassword.addLongIdentifier("current-keystore-passphrase", 3189 true); 3190 changeKSPWCurrentPassword.addLongIdentifier("currentKeystorePassphrase", 3191 true); 3192 changeKSPWCurrentPassword.addLongIdentifier("current-keystore-pin", true); 3193 changeKSPWCurrentPassword.addLongIdentifier("currentKeystorePIN", true); 3194 changeKSPWCurrentPassword.addLongIdentifier("storepass", true); 3195 changeKSPWCurrentPassword.setSensitive(true); 3196 changeKSPWParser.addArgument(changeKSPWCurrentPassword); 3197 3198 final FileArgument changeKSPWCurrentPasswordFile = new FileArgument(null, 3199 "current-keystore-password-file", false, 1, null, 3200 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_ARG_CURRENT_PW_FILE_DESC.get(), true, 3201 true, true, false); 3202 changeKSPWCurrentPasswordFile.addLongIdentifier( 3203 "currentKeystorePasswordFile", true); 3204 changeKSPWCurrentPasswordFile.addLongIdentifier( 3205 "current-keystore-passphrase-file", true); 3206 changeKSPWCurrentPasswordFile.addLongIdentifier( 3207 "currentKeystorePassphraseFile", true); 3208 changeKSPWCurrentPasswordFile.addLongIdentifier("current-keystore-pin-file", 3209 true); 3210 changeKSPWCurrentPasswordFile.addLongIdentifier("currentKeystorePINFile", 3211 true); 3212 changeKSPWParser.addArgument(changeKSPWCurrentPasswordFile); 3213 3214 final BooleanArgument changeKSPWPromptForCurrentPassword = 3215 new BooleanArgument(null, "prompt-for-current-keystore-password", 3216 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_ARG_PROMPT_FOR_CURRENT_PW_DESC.get()); 3217 changeKSPWPromptForCurrentPassword.addLongIdentifier( 3218 "promptForCurrentKeystorePassword", true); 3219 changeKSPWPromptForCurrentPassword.addLongIdentifier( 3220 "prompt-for-current-keystore-passphrase", true); 3221 changeKSPWPromptForCurrentPassword.addLongIdentifier( 3222 "promptForCurrentKeystorePassphrase", true); 3223 changeKSPWPromptForCurrentPassword.addLongIdentifier( 3224 "prompt-for-current-keystore-pin", true); 3225 changeKSPWPromptForCurrentPassword.addLongIdentifier( 3226 "promptForCurrentKeystorePIN", true); 3227 changeKSPWParser.addArgument(changeKSPWPromptForCurrentPassword); 3228 3229 final StringArgument changeKSPWNewPassword = new StringArgument(null, 3230 "new-keystore-password", false, 1, 3231 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3232 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_ARG_NEW_PW_DESC.get()); 3233 changeKSPWNewPassword.addLongIdentifier("newKeystorePassword", 3234 true); 3235 changeKSPWNewPassword.addLongIdentifier("new-keystore-passphrase", 3236 true); 3237 changeKSPWNewPassword.addLongIdentifier("newKeystorePassphrase", 3238 true); 3239 changeKSPWNewPassword.addLongIdentifier("new-keystore-pin", true); 3240 changeKSPWNewPassword.addLongIdentifier("newKeystorePIN", true); 3241 changeKSPWNewPassword.addLongIdentifier("new", true); 3242 changeKSPWNewPassword.setSensitive(true); 3243 changeKSPWParser.addArgument(changeKSPWNewPassword); 3244 3245 final FileArgument changeKSPWNewPasswordFile = new FileArgument(null, 3246 "new-keystore-password-file", false, 1, null, 3247 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_ARG_NEW_PW_FILE_DESC.get(), true, 3248 true, true, false); 3249 changeKSPWNewPasswordFile.addLongIdentifier("newKeystorePasswordFile", 3250 true); 3251 changeKSPWNewPasswordFile.addLongIdentifier("new-keystore-passphrase-file", 3252 true); 3253 changeKSPWNewPasswordFile.addLongIdentifier("newKeystorePassphraseFile", 3254 true); 3255 changeKSPWNewPasswordFile.addLongIdentifier("new-keystore-pin-file", true); 3256 changeKSPWNewPasswordFile.addLongIdentifier("newKeystorePINFile", true); 3257 changeKSPWParser.addArgument(changeKSPWNewPasswordFile); 3258 3259 final BooleanArgument changeKSPWPromptForNewPassword = 3260 new BooleanArgument(null, "prompt-for-new-keystore-password", 3261 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_ARG_PROMPT_FOR_NEW_PW_DESC.get()); 3262 changeKSPWPromptForNewPassword.addLongIdentifier( 3263 "promptForNewKeystorePassword", true); 3264 changeKSPWPromptForNewPassword.addLongIdentifier( 3265 "prompt-for-new-keystore-passphrase", true); 3266 changeKSPWPromptForNewPassword.addLongIdentifier( 3267 "promptForNewKeystorePassphrase", true); 3268 changeKSPWPromptForNewPassword.addLongIdentifier( 3269 "prompt-for-new-keystore-pin", true); 3270 changeKSPWPromptForNewPassword.addLongIdentifier( 3271 "promptForNewKeystorePIN", true); 3272 changeKSPWParser.addArgument(changeKSPWPromptForNewPassword); 3273 3274 final BooleanArgument changeKSPWDisplayCommand = new BooleanArgument(null, 3275 "display-keytool-command", 1, 3276 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_ARG_DISPLAY_COMMAND_DESC.get()); 3277 changeKSPWDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 3278 changeKSPWDisplayCommand.addLongIdentifier("show-keytool-command", true); 3279 changeKSPWDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 3280 changeKSPWParser.addArgument(changeKSPWDisplayCommand); 3281 3282 changeKSPWParser.addRequiredArgumentSet(changeKSPWCurrentPassword, 3283 changeKSPWCurrentPasswordFile, changeKSPWPromptForCurrentPassword); 3284 changeKSPWParser.addExclusiveArgumentSet(changeKSPWCurrentPassword, 3285 changeKSPWCurrentPasswordFile, changeKSPWPromptForCurrentPassword); 3286 changeKSPWParser.addRequiredArgumentSet(changeKSPWNewPassword, 3287 changeKSPWNewPasswordFile, changeKSPWPromptForNewPassword); 3288 changeKSPWParser.addExclusiveArgumentSet(changeKSPWNewPassword, 3289 changeKSPWNewPasswordFile, changeKSPWPromptForNewPassword); 3290 3291 final LinkedHashMap<String[],String> changeKSPWExamples = 3292 new LinkedHashMap<>(StaticUtils.computeMapCapacity(1)); 3293 changeKSPWExamples.put( 3294 new String[] 3295 { 3296 "change-keystore-password", 3297 "--keystore", getPlatformSpecificPath("config", "keystore"), 3298 "--current-keystore-password-file", 3299 getPlatformSpecificPath("config", "current.pin"), 3300 "--new-keystore-password-file", 3301 getPlatformSpecificPath("config", "new.pin"), 3302 "--display-keytool-command" 3303 }, 3304 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_EXAMPLE_1.get( 3305 getPlatformSpecificPath("config", "keystore"), 3306 getPlatformSpecificPath("config", "current.pin"), 3307 getPlatformSpecificPath("config", "new.pin"))); 3308 3309 final SubCommand changeKSPWSubCommand = new SubCommand( 3310 "change-keystore-password", 3311 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_DESC.get(), changeKSPWParser, 3312 changeKSPWExamples); 3313 changeKSPWSubCommand.addName("changeKeystorePassword", true); 3314 changeKSPWSubCommand.addName("change-keystore-passphrase", true); 3315 changeKSPWSubCommand.addName("changeKeystorePassphrase", true); 3316 changeKSPWSubCommand.addName("change-keystore-pin", true); 3317 changeKSPWSubCommand.addName("changeKeystorePIN", true); 3318 changeKSPWSubCommand.addName("storepasswd", true); 3319 3320 parser.addSubCommand(changeKSPWSubCommand); 3321 3322 3323 // Define the "change-private-key-password" subcommand and all of its 3324 // arguments. 3325 final ArgumentParser changePKPWParser = new ArgumentParser( 3326 "change-private-key-password", 3327 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_DESC.get()); 3328 3329 final FileArgument changePKPWKeystore = new FileArgument(null, "keystore", 3330 true, 1, null, INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_KS_DESC.get(), 3331 true, true, true, false); 3332 changePKPWKeystore.addLongIdentifier("keystore-path", true); 3333 changePKPWKeystore.addLongIdentifier("keystorePath", true); 3334 changePKPWKeystore.addLongIdentifier("keystore-file", true); 3335 changePKPWKeystore.addLongIdentifier("keystoreFile", true); 3336 changePKPWParser.addArgument(changePKPWKeystore); 3337 3338 final StringArgument changePKPWKeystorePassword = new StringArgument(null, 3339 "keystore-password", false, 1, 3340 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3341 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_KS_PW_DESC.get()); 3342 changePKPWKeystorePassword.addLongIdentifier("keystorePassword", true); 3343 changePKPWKeystorePassword.addLongIdentifier("keystore-passphrase", true); 3344 changePKPWKeystorePassword.addLongIdentifier("keystorePassphrase", true); 3345 changePKPWKeystorePassword.addLongIdentifier("keystore-pin", true); 3346 changePKPWKeystorePassword.addLongIdentifier("keystorePIN", true); 3347 changePKPWKeystorePassword.addLongIdentifier("storepass", true); 3348 changePKPWKeystorePassword.setSensitive(true); 3349 changePKPWParser.addArgument(changePKPWKeystorePassword); 3350 3351 final FileArgument changePKPWKeystorePasswordFile = new FileArgument(null, 3352 "keystore-password-file", false, 1, null, 3353 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_KS_PW_FILE_DESC.get(), true, 3354 true, true, false); 3355 changePKPWKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 3356 true); 3357 changePKPWKeystorePasswordFile.addLongIdentifier( 3358 "keystore-passphrase-file", true); 3359 changePKPWKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 3360 true); 3361 changePKPWKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 3362 true); 3363 changePKPWKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 3364 changePKPWParser.addArgument(changePKPWKeystorePasswordFile); 3365 3366 final BooleanArgument changePKPWPromptForKeystorePassword = 3367 new BooleanArgument(null, "prompt-for-keystore-password", 3368 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_PROMPT_FOR_KS_PW_DESC.get()); 3369 changePKPWPromptForKeystorePassword.addLongIdentifier( 3370 "promptForKeystorePassword", true); 3371 changePKPWPromptForKeystorePassword.addLongIdentifier( 3372 "prompt-for-keystore-passphrase", true); 3373 changePKPWPromptForKeystorePassword.addLongIdentifier( 3374 "promptForKeystorePassphrase", true); 3375 changePKPWPromptForKeystorePassword.addLongIdentifier( 3376 "prompt-for-keystore-pin", true); 3377 changePKPWPromptForKeystorePassword.addLongIdentifier( 3378 "promptForKeystorePIN", true); 3379 changePKPWParser.addArgument(changePKPWPromptForKeystorePassword); 3380 3381 final StringArgument changePKPWKeystoreType = new StringArgument(null, 3382 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 3383 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_KS_TYPE_DESC.get(), 3384 ALLOWED_KEYSTORE_TYPE_VALUES); 3385 changePKPWKeystoreType.addLongIdentifier("key-store-type", true); 3386 changePKPWKeystoreType.addLongIdentifier("keystoreType", true); 3387 changePKPWKeystoreType.addLongIdentifier("keystore-format", true); 3388 changePKPWKeystoreType.addLongIdentifier("key-store-format", true); 3389 changePKPWKeystoreType.addLongIdentifier("keystoreFormat", true); 3390 changePKPWKeystoreType.addLongIdentifier("storetype", true); 3391 changePKPWParser.addArgument(changePKPWKeystoreType); 3392 3393 final StringArgument changePKPWAlias = new StringArgument(null, "alias", 3394 true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 3395 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_ALIAS_DESC.get()); 3396 changePKPWAlias.addLongIdentifier("nickname", true); 3397 changePKPWParser.addArgument(changePKPWAlias); 3398 3399 final StringArgument changePKPWCurrentPassword = new StringArgument(null, 3400 "current-private-key-password", false, 1, 3401 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3402 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_CURRENT_PW_DESC.get()); 3403 changePKPWCurrentPassword.addLongIdentifier("currentPrivateKeyPassword", 3404 true); 3405 changePKPWCurrentPassword.addLongIdentifier( 3406 "current-private-key-passphrase", true); 3407 changePKPWCurrentPassword.addLongIdentifier("currentPrivateKeyPassphrase", 3408 true); 3409 changePKPWCurrentPassword.addLongIdentifier("current-private-key-pin", 3410 true); 3411 changePKPWCurrentPassword.addLongIdentifier("currentPrivateKeyPIN", true); 3412 changePKPWCurrentPassword.addLongIdentifier("keypass", true); 3413 changePKPWCurrentPassword.setSensitive(true); 3414 changePKPWParser.addArgument(changePKPWCurrentPassword); 3415 3416 final FileArgument changePKPWCurrentPasswordFile = new FileArgument(null, 3417 "current-private-key-password-file", false, 1, null, 3418 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_CURRENT_PW_FILE_DESC.get(), true, 3419 true, true, false); 3420 changePKPWCurrentPasswordFile.addLongIdentifier( 3421 "currentPrivateKeyPasswordFile", true); 3422 changePKPWCurrentPasswordFile.addLongIdentifier( 3423 "current-private-key-passphrase-file", true); 3424 changePKPWCurrentPasswordFile.addLongIdentifier( 3425 "currentPrivateKeyPassphraseFile", true); 3426 changePKPWCurrentPasswordFile.addLongIdentifier( 3427 "current-private-key-pin-file", true); 3428 changePKPWCurrentPasswordFile.addLongIdentifier("currentPrivateKeyPINFile", 3429 true); 3430 changePKPWParser.addArgument(changePKPWCurrentPasswordFile); 3431 3432 final BooleanArgument changePKPWPromptForCurrentPassword = 3433 new BooleanArgument(null, "prompt-for-current-private-key-password", 3434 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_PROMPT_FOR_CURRENT_PW_DESC.get()); 3435 changePKPWPromptForCurrentPassword.addLongIdentifier( 3436 "promptForCurrentPrivateKeyPassword", true); 3437 changePKPWPromptForCurrentPassword.addLongIdentifier( 3438 "prompt-for-current-private-key-passphrase", true); 3439 changePKPWPromptForCurrentPassword.addLongIdentifier( 3440 "promptForCurrentPrivateKeyPassphrase", true); 3441 changePKPWPromptForCurrentPassword.addLongIdentifier( 3442 "prompt-for-current-private-key-pin", true); 3443 changePKPWPromptForCurrentPassword.addLongIdentifier( 3444 "promptForCurrentPrivateKeyPIN", true); 3445 changePKPWParser.addArgument(changePKPWPromptForCurrentPassword); 3446 3447 final StringArgument changePKPWNewPassword = new StringArgument(null, 3448 "new-private-key-password", false, 1, 3449 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3450 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_NEW_PW_DESC.get()); 3451 changePKPWNewPassword.addLongIdentifier("newPrivateKeyPassword", 3452 true); 3453 changePKPWNewPassword.addLongIdentifier("new-private-key-passphrase", true); 3454 changePKPWNewPassword.addLongIdentifier("newPrivateKeyPassphrase", true); 3455 changePKPWNewPassword.addLongIdentifier("new-private-key-pin", true); 3456 changePKPWNewPassword.addLongIdentifier("newPrivateKeyPIN", true); 3457 changePKPWNewPassword.addLongIdentifier("new", true); 3458 changePKPWNewPassword.setSensitive(true); 3459 changePKPWParser.addArgument(changePKPWNewPassword); 3460 3461 final FileArgument changePKPWNewPasswordFile = new FileArgument(null, 3462 "new-private-key-password-file", false, 1, null, 3463 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_NEW_PW_FILE_DESC.get(), true, 3464 true, true, false); 3465 changePKPWNewPasswordFile.addLongIdentifier("newPrivateKeyPasswordFile", 3466 true); 3467 changePKPWNewPasswordFile.addLongIdentifier( 3468 "new-private-key-passphrase-file", true); 3469 changePKPWNewPasswordFile.addLongIdentifier("newPrivateKeyPassphraseFile", 3470 true); 3471 changePKPWNewPasswordFile.addLongIdentifier("new-private-key-pin-file", 3472 true); 3473 changePKPWNewPasswordFile.addLongIdentifier("newPrivateKeyPINFile", true); 3474 changePKPWParser.addArgument(changePKPWNewPasswordFile); 3475 3476 final BooleanArgument changePKPWPromptForNewPassword = 3477 new BooleanArgument(null, "prompt-for-new-private-key-password", 3478 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_PROMPT_FOR_NEW_PW_DESC.get()); 3479 changePKPWPromptForNewPassword.addLongIdentifier( 3480 "promptForNewPrivateKeyPassword", true); 3481 changePKPWPromptForNewPassword.addLongIdentifier( 3482 "prompt-for-new-private-key-passphrase", true); 3483 changePKPWPromptForNewPassword.addLongIdentifier( 3484 "promptForNewPrivateKeyPassphrase", true); 3485 changePKPWPromptForNewPassword.addLongIdentifier( 3486 "prompt-for-new-private-key-pin", true); 3487 changePKPWPromptForNewPassword.addLongIdentifier( 3488 "promptForNewPrivateKeyPIN", true); 3489 changePKPWParser.addArgument(changePKPWPromptForNewPassword); 3490 3491 final BooleanArgument changePKPWDisplayCommand = new BooleanArgument(null, 3492 "display-keytool-command", 1, 3493 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_ARG_DISPLAY_COMMAND_DESC.get()); 3494 changePKPWDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 3495 changePKPWDisplayCommand.addLongIdentifier("show-keytool-command", true); 3496 changePKPWDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 3497 changePKPWParser.addArgument(changePKPWDisplayCommand); 3498 3499 changePKPWParser.addRequiredArgumentSet(changePKPWKeystorePassword, 3500 changePKPWKeystorePasswordFile, changePKPWPromptForKeystorePassword); 3501 changePKPWParser.addExclusiveArgumentSet(changePKPWKeystorePassword, 3502 changePKPWKeystorePasswordFile, changePKPWPromptForKeystorePassword); 3503 changePKPWParser.addRequiredArgumentSet(changePKPWCurrentPassword, 3504 changePKPWCurrentPasswordFile, changePKPWPromptForCurrentPassword); 3505 changePKPWParser.addExclusiveArgumentSet(changePKPWCurrentPassword, 3506 changePKPWCurrentPasswordFile, changePKPWPromptForCurrentPassword); 3507 changePKPWParser.addRequiredArgumentSet(changePKPWNewPassword, 3508 changePKPWNewPasswordFile, changePKPWPromptForNewPassword); 3509 changePKPWParser.addExclusiveArgumentSet(changePKPWNewPassword, 3510 changePKPWNewPasswordFile, changePKPWPromptForNewPassword); 3511 3512 final LinkedHashMap<String[],String> changePKPWExamples = 3513 new LinkedHashMap<>(StaticUtils.computeMapCapacity(1)); 3514 changePKPWExamples.put( 3515 new String[] 3516 { 3517 "change-private-key-password", 3518 "--keystore", getPlatformSpecificPath("config", "keystore"), 3519 "--keystore-password-file", 3520 getPlatformSpecificPath("config", "keystore.pin"), 3521 "--alias", "server-cert", 3522 "--current-private-key-password-file", 3523 getPlatformSpecificPath("config", "current.pin"), 3524 "--new-private-key-password-file", 3525 getPlatformSpecificPath("config", "new.pin"), 3526 "--display-keytool-command" 3527 }, 3528 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_EXAMPLE_1.get( 3529 getPlatformSpecificPath("config", "keystore"), 3530 getPlatformSpecificPath("config", "current.pin"), 3531 getPlatformSpecificPath("config", "new.pin"))); 3532 3533 final SubCommand changePKPWSubCommand = new SubCommand( 3534 "change-private-key-password", 3535 INFO_MANAGE_CERTS_SC_CHANGE_PK_PW_DESC.get(), changePKPWParser, 3536 changePKPWExamples); 3537 changePKPWSubCommand.addName("changePrivateKeyPassword", true); 3538 changePKPWSubCommand.addName("change-private-key-passphrase", true); 3539 changePKPWSubCommand.addName("changePrivateKeyPassphrase", true); 3540 changePKPWSubCommand.addName("change-private-key-pin", true); 3541 changePKPWSubCommand.addName("changePrivateKeyPIN", true); 3542 changePKPWSubCommand.addName("change-key-password", true); 3543 changePKPWSubCommand.addName("changeKeyPassword", true); 3544 changePKPWSubCommand.addName("change-key-passphrase", true); 3545 changePKPWSubCommand.addName("changeKeyPassphrase", true); 3546 changePKPWSubCommand.addName("change-key-pin", true); 3547 changePKPWSubCommand.addName("changeKeyPIN", true); 3548 changePKPWSubCommand.addName("keypasswd", true); 3549 3550 parser.addSubCommand(changePKPWSubCommand); 3551 3552 3553 // Define the "copy-keystore" subcommand and all of its arguments. 3554 final ArgumentParser copyKSParser = new ArgumentParser("copy-keystore", 3555 INFO_MANAGE_CERTS_SC_COPY_KS_DESC.get()); 3556 3557 final FileArgument copyKSSourceKeystore = new FileArgument(null, 3558 "source-keystore", true, 1, null, 3559 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_SRC_KS_DESC.get(), true, true, true, 3560 false); 3561 copyKSSourceKeystore.addLongIdentifier("sourceKeystore", true); 3562 copyKSSourceKeystore.addLongIdentifier("source-keystore-path", true); 3563 copyKSSourceKeystore.addLongIdentifier("sourceKeystorePath", true); 3564 copyKSSourceKeystore.addLongIdentifier("source-keystore-file", true); 3565 copyKSSourceKeystore.addLongIdentifier("sourceKeystoreFile", true); 3566 copyKSParser.addArgument(copyKSSourceKeystore); 3567 3568 final StringArgument copyKSSourceKeystorePassword = new StringArgument(null, 3569 "source-keystore-password", false, 1, 3570 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3571 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_SRC_KS_PW_DESC.get()); 3572 copyKSSourceKeystorePassword.addLongIdentifier("sourceKeystorePassword", 3573 true); 3574 copyKSSourceKeystorePassword.addLongIdentifier("source-keystore-passphrase", 3575 true); 3576 copyKSSourceKeystorePassword.addLongIdentifier("sourceKeystorePassphrase", 3577 true); 3578 copyKSSourceKeystorePassword.addLongIdentifier("source-keystore-pin", true); 3579 copyKSSourceKeystorePassword.addLongIdentifier("sourceKeystorePIN", true); 3580 copyKSParser.addArgument(copyKSSourceKeystorePassword); 3581 3582 final FileArgument copyKSSourceKeystorePasswordFile = new FileArgument(null, 3583 "source-keystore-password-file", false, 1, null, 3584 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_SRC_KS_PW_FILE_DESC.get(), true, true, 3585 true, false); 3586 copyKSSourceKeystorePasswordFile.addLongIdentifier( 3587 "sourceKeystorePasswordFile", true); 3588 copyKSSourceKeystorePasswordFile.addLongIdentifier( 3589 "source-keystore-passphrase-file", true); 3590 copyKSSourceKeystorePasswordFile.addLongIdentifier( 3591 "sourceKeystorePassphraseFile", true); 3592 copyKSSourceKeystorePasswordFile.addLongIdentifier( 3593 "source-keystore-pin-file", true); 3594 copyKSSourceKeystorePasswordFile.addLongIdentifier( 3595 "sourceKeystorePINFile", true); 3596 copyKSParser.addArgument(copyKSSourceKeystorePasswordFile); 3597 3598 final BooleanArgument copyKSPromptForSourceKeystorePassword = 3599 new BooleanArgument(null, "prompt-for-source-keystore-password", 1, 3600 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_PROMPT_FOR_SRC_KS_PW.get()); 3601 copyKSPromptForSourceKeystorePassword.addLongIdentifier( 3602 "promptForSourceKeystorePassword", true); 3603 copyKSPromptForSourceKeystorePassword.addLongIdentifier( 3604 "prompt-for-source-keystore-passphrase", true); 3605 copyKSPromptForSourceKeystorePassword.addLongIdentifier( 3606 "promptForSourceKeystorePassphrase", true); 3607 copyKSPromptForSourceKeystorePassword.addLongIdentifier( 3608 "prompt-for-source-keystore-pin", true); 3609 copyKSPromptForSourceKeystorePassword.addLongIdentifier( 3610 "promptForSourceKeystorePIN", true); 3611 copyKSParser.addArgument(copyKSPromptForSourceKeystorePassword); 3612 3613 final StringArgument copyKSSourcePKPassword = new StringArgument(null, 3614 "source-private-key-password", false, 1, 3615 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3616 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_SRC_PK_PW_DESC.get()); 3617 copyKSSourcePKPassword.addLongIdentifier("sourcePrivateKeyPassword", true); 3618 copyKSSourcePKPassword.addLongIdentifier("source-private-key-passphrase", 3619 true); 3620 copyKSSourcePKPassword.addLongIdentifier("sourcePrivateKeyPassphrase", 3621 true); 3622 copyKSSourcePKPassword.addLongIdentifier("source-private-key-pin", true); 3623 copyKSSourcePKPassword.addLongIdentifier("sourcePrivateKeyPIN", true); 3624 copyKSParser.addArgument(copyKSSourcePKPassword); 3625 3626 final FileArgument copyKSSourcePKPasswordFile = new FileArgument(null, 3627 "source-private-key-password-file", false, 1, null, 3628 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_SRC_PK_PW_FILE_DESC.get(), true, true, 3629 true, false); 3630 copyKSSourcePKPasswordFile.addLongIdentifier( 3631 "sourcePrivateKeyPasswordFile", true); 3632 copyKSSourcePKPasswordFile.addLongIdentifier( 3633 "source-private-key-passphrase-file", true); 3634 copyKSSourcePKPasswordFile.addLongIdentifier( 3635 "sourcePrivateKeyPassphraseFile", true); 3636 copyKSSourcePKPasswordFile.addLongIdentifier( 3637 "source-private-key-pin-file", true); 3638 copyKSSourcePKPasswordFile.addLongIdentifier( 3639 "sourcePrivateKeyPINFile", true); 3640 copyKSParser.addArgument(copyKSSourcePKPasswordFile); 3641 3642 final BooleanArgument copyKSPromptForSourcePKPassword = 3643 new BooleanArgument(null, "prompt-for-source-private-key-password", 1, 3644 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_PROMPT_FOR_SRC_PK_PW.get()); 3645 copyKSPromptForSourcePKPassword.addLongIdentifier( 3646 "promptForSourcePrivateKeyPassword", true); 3647 copyKSPromptForSourcePKPassword.addLongIdentifier( 3648 "prompt-for-source-private-key-passphrase", true); 3649 copyKSPromptForSourcePKPassword.addLongIdentifier( 3650 "promptForSourcePrivateKeyPassphrase", true); 3651 copyKSPromptForSourcePKPassword.addLongIdentifier( 3652 "prompt-for-source-private-key-pin", true); 3653 copyKSPromptForSourcePKPassword.addLongIdentifier( 3654 "promptForSourcePrivateKeyPIN", true); 3655 copyKSParser.addArgument(copyKSPromptForSourcePKPassword); 3656 3657 final StringArgument copyKSSourceKeystoreType = new StringArgument(null, 3658 "source-keystore-type", false, 1, 3659 INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 3660 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_SRC_KS_TYPE.get(), 3661 ALLOWED_KEYSTORE_TYPE_VALUES); 3662 copyKSSourceKeystoreType.addLongIdentifier("source-key-store-type", true); 3663 copyKSSourceKeystoreType.addLongIdentifier("sourceKeystoreType", true); 3664 copyKSSourceKeystoreType.addLongIdentifier("source-keystore-format", true); 3665 copyKSSourceKeystoreType.addLongIdentifier("source-key-store-format", true); 3666 copyKSSourceKeystoreType.addLongIdentifier("sourceKeystoreFormat", true); 3667 copyKSParser.addArgument(copyKSSourceKeystoreType); 3668 3669 final FileArgument copyKSDestKeystore = new FileArgument(null, 3670 "destination-keystore", true, 1, null, 3671 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_DST_KS_DESC.get(), false, true, true, 3672 false); 3673 copyKSDestKeystore.addLongIdentifier("destinationKeystore", true); 3674 copyKSDestKeystore.addLongIdentifier("destination-keystore-path", true); 3675 copyKSDestKeystore.addLongIdentifier("destinationKeystorePath", true); 3676 copyKSDestKeystore.addLongIdentifier("destination-keystore-file", true); 3677 copyKSDestKeystore.addLongIdentifier("destinationKeystoreFile", true); 3678 copyKSDestKeystore.addLongIdentifier("target-keystore", true); 3679 copyKSDestKeystore.addLongIdentifier("targetKeystore", true); 3680 copyKSDestKeystore.addLongIdentifier("target-keystore-path", true); 3681 copyKSDestKeystore.addLongIdentifier("targetKeystorePath", true); 3682 copyKSDestKeystore.addLongIdentifier("target-keystore-file", true); 3683 copyKSDestKeystore.addLongIdentifier("targetKeystoreFile", true); 3684 copyKSParser.addArgument(copyKSDestKeystore); 3685 3686 final StringArgument copyKSDestKeystorePassword = new StringArgument(null, 3687 "destination-keystore-password", false, 1, 3688 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3689 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_DST_KS_PW_DESC.get()); 3690 copyKSDestKeystorePassword.addLongIdentifier("destinationKeystorePassword", 3691 true); 3692 copyKSDestKeystorePassword.addLongIdentifier( 3693 "destination-keystore-passphrase", true); 3694 copyKSDestKeystorePassword.addLongIdentifier( 3695 "destinationKeystorePassphrase", true); 3696 copyKSDestKeystorePassword.addLongIdentifier("destination-keystore-pin", 3697 true); 3698 copyKSDestKeystorePassword.addLongIdentifier("destinationKeystorePIN", 3699 true); 3700 copyKSDestKeystorePassword.addLongIdentifier("target-keystore-password", 3701 true); 3702 copyKSDestKeystorePassword.addLongIdentifier("targetKeystorePassword", 3703 true); 3704 copyKSDestKeystorePassword.addLongIdentifier("target-keystore-passphrase", 3705 true); 3706 copyKSDestKeystorePassword.addLongIdentifier("targetKeystorePassphrase", 3707 true); 3708 copyKSDestKeystorePassword.addLongIdentifier("target-keystore-pin", true); 3709 copyKSDestKeystorePassword.addLongIdentifier("targetKeystorePIN", true); 3710 copyKSParser.addArgument(copyKSDestKeystorePassword); 3711 3712 final FileArgument copyKSDestKeystorePasswordFile = new FileArgument(null, 3713 "destination-keystore-password-file", false, 1, null, 3714 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_DST_KS_PW_FILE_DESC.get(), true, true, 3715 true, false); 3716 copyKSDestKeystorePasswordFile.addLongIdentifier( 3717 "destinationKeystorePasswordFile", true); 3718 copyKSDestKeystorePasswordFile.addLongIdentifier( 3719 "destination-keystore-passphrase-file", true); 3720 copyKSDestKeystorePasswordFile.addLongIdentifier( 3721 "destinationKeystorePassphraseFile", true); 3722 copyKSDestKeystorePasswordFile.addLongIdentifier( 3723 "destination-keystore-pin-file", true); 3724 copyKSDestKeystorePasswordFile.addLongIdentifier( 3725 "destinationKeystorePINFile", true); 3726 copyKSDestKeystorePasswordFile.addLongIdentifier( 3727 "target-keystore-password-file", true); 3728 copyKSDestKeystorePasswordFile.addLongIdentifier( 3729 "targetKeystorePasswordFile", true); 3730 copyKSDestKeystorePasswordFile.addLongIdentifier( 3731 "target-keystore-passphrase-file", true); 3732 copyKSDestKeystorePasswordFile.addLongIdentifier( 3733 "targetKeystorePassphraseFile", true); 3734 copyKSDestKeystorePasswordFile.addLongIdentifier("target-keystore-pin-file", 3735 true); 3736 copyKSDestKeystorePasswordFile.addLongIdentifier("targetKeystorePINFile", 3737 true); 3738 copyKSParser.addArgument(copyKSDestKeystorePasswordFile); 3739 3740 final BooleanArgument copyKSPromptForDestKeystorePassword = 3741 new BooleanArgument(null, "prompt-for-destination-keystore-password", 3742 1, INFO_MANAGE_CERTS_SC_COPY_KS_ARG_PROMPT_FOR_DST_KS_PW.get()); 3743 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3744 "promptForDestinationKeystorePassword", true); 3745 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3746 "prompt-for-Destination-keystore-passphrase", true); 3747 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3748 "promptForDestinationKeystorePassphrase", true); 3749 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3750 "prompt-for-Destination-keystore-pin", true); 3751 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3752 "promptForDestinationKeystorePIN", true); 3753 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3754 "prompt-for-target-keystore-password", true); 3755 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3756 "promptForTargetKeystorePassword", true); 3757 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3758 "prompt-for-Target-keystore-passphrase", true); 3759 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3760 "promptForTargetKeystorePassphrase", true); 3761 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3762 "prompt-for-Target-keystore-pin", true); 3763 copyKSPromptForDestKeystorePassword.addLongIdentifier( 3764 "promptForTargetKeystorePIN", true); 3765 copyKSParser.addArgument(copyKSPromptForDestKeystorePassword); 3766 3767 final StringArgument copyKSDestPKPassword = new StringArgument(null, 3768 "destination-private-key-password", false, 1, 3769 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 3770 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_DST_PK_PW_DESC.get()); 3771 copyKSDestPKPassword.addLongIdentifier("destinationPrivateKeyPassword", 3772 true); 3773 copyKSDestPKPassword.addLongIdentifier("destination-private-key-passphrase", 3774 true); 3775 copyKSDestPKPassword.addLongIdentifier("destinationPrivateKeyPassphrase", 3776 true); 3777 copyKSDestPKPassword.addLongIdentifier("destination-private-key-pin", true); 3778 copyKSDestPKPassword.addLongIdentifier("destinationPrivateKeyPIN", true); 3779 copyKSDestPKPassword.addLongIdentifier("target-private-key-password", 3780 true); 3781 copyKSDestPKPassword.addLongIdentifier("targetPrivateKeyPassword", 3782 true); 3783 copyKSDestPKPassword.addLongIdentifier("target-private-key-passphrase", 3784 true); 3785 copyKSDestPKPassword.addLongIdentifier("targetPrivateKeyPassphrase", 3786 true); 3787 copyKSDestPKPassword.addLongIdentifier("target-private-key-pin", true); 3788 copyKSDestPKPassword.addLongIdentifier("targetPrivateKeyPIN", true); 3789 copyKSParser.addArgument(copyKSDestPKPassword); 3790 3791 final FileArgument copyKSDestPKPasswordFile = new FileArgument(null, 3792 "destination-private-key-password-file", false, 1, null, 3793 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_DST_PK_PW_FILE_DESC.get(), true, true, 3794 true, false); 3795 copyKSDestPKPasswordFile.addLongIdentifier( 3796 "destinationPrivateKeyPasswordFile", true); 3797 copyKSDestPKPasswordFile.addLongIdentifier( 3798 "destination-private-key-passphrase-file", true); 3799 copyKSDestPKPasswordFile.addLongIdentifier( 3800 "destinationPrivateKeyPassphraseFile", true); 3801 copyKSDestPKPasswordFile.addLongIdentifier( 3802 "destination-private-key-pin-file", true); 3803 copyKSDestPKPasswordFile.addLongIdentifier( 3804 "destinationPrivateKeyPINFile", true); 3805 copyKSDestPKPasswordFile.addLongIdentifier( 3806 "target-private-key-password-file", true); 3807 copyKSDestPKPasswordFile.addLongIdentifier( 3808 "targetPrivateKeyPasswordFile", true); 3809 copyKSDestPKPasswordFile.addLongIdentifier( 3810 "target-private-key-passphrase-file", true); 3811 copyKSDestPKPasswordFile.addLongIdentifier( 3812 "targetPrivateKeyPassphraseFile", true); 3813 copyKSDestPKPasswordFile.addLongIdentifier( 3814 "target-private-key-pin-file", true); 3815 copyKSDestPKPasswordFile.addLongIdentifier( 3816 "targetPrivateKeyPINFile", true); 3817 copyKSParser.addArgument(copyKSDestPKPasswordFile); 3818 3819 final BooleanArgument copyKSPromptForDestPKPassword = 3820 new BooleanArgument(null, 3821 "prompt-for-destination-private-key-password", 1, 3822 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_PROMPT_FOR_DST_PK_PW.get()); 3823 copyKSPromptForDestPKPassword.addLongIdentifier( 3824 "promptForDestinationPrivateKeyPassword", true); 3825 copyKSPromptForDestPKPassword.addLongIdentifier( 3826 "prompt-for-Destination-private-key-passphrase", true); 3827 copyKSPromptForDestPKPassword.addLongIdentifier( 3828 "promptForDestinationPrivateKeyPassphrase", true); 3829 copyKSPromptForDestPKPassword.addLongIdentifier( 3830 "prompt-for-Destination-private-key-pin", true); 3831 copyKSPromptForDestPKPassword.addLongIdentifier( 3832 "promptForDestinationPrivateKeyPIN", true); 3833 copyKSPromptForDestPKPassword.addLongIdentifier( 3834 "prompt-for-target-private-key-password", true); 3835 copyKSPromptForDestPKPassword.addLongIdentifier( 3836 "promptForTargetPrivateKeyPassword", true); 3837 copyKSPromptForDestPKPassword.addLongIdentifier( 3838 "prompt-for-Target-private-key-passphrase", true); 3839 copyKSPromptForDestPKPassword.addLongIdentifier( 3840 "promptForTargetPrivateKeyPassphrase", true); 3841 copyKSPromptForDestPKPassword.addLongIdentifier( 3842 "prompt-for-Target-private-key-pin", true); 3843 copyKSPromptForDestPKPassword.addLongIdentifier( 3844 "promptForTargetPrivateKeyPIN", true); 3845 copyKSParser.addArgument(copyKSPromptForDestPKPassword); 3846 3847 final StringArgument copyKSDestKeystoreType = new StringArgument(null, 3848 "destination-keystore-type", false, 1, 3849 INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 3850 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_DST_KS_TYPE.get(), 3851 ALLOWED_KEYSTORE_TYPE_VALUES); 3852 copyKSDestKeystoreType.addLongIdentifier("destination-key-store-type", 3853 true); 3854 copyKSDestKeystoreType.addLongIdentifier("destinationKeystoreType", true); 3855 copyKSDestKeystoreType.addLongIdentifier("destination-keystore-format", 3856 true); 3857 copyKSDestKeystoreType.addLongIdentifier("destination-key-store-format", 3858 true); 3859 copyKSDestKeystoreType.addLongIdentifier("destinationKeystoreFormat", true); 3860 copyKSDestKeystoreType.addLongIdentifier("target-key-store-type", true); 3861 copyKSDestKeystoreType.addLongIdentifier("targetKeystoreType", true); 3862 copyKSDestKeystoreType.addLongIdentifier("target-keystore-format", true); 3863 copyKSDestKeystoreType.addLongIdentifier("target-key-store-format", true); 3864 copyKSDestKeystoreType.addLongIdentifier("targetKeystoreFormat", true); 3865 copyKSParser.addArgument(copyKSDestKeystoreType); 3866 3867 final StringArgument copyKSAlias = new StringArgument(null, "alias", false, 3868 0, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 3869 INFO_MANAGE_CERTS_SC_COPY_KS_ARG_ALIAS.get()); 3870 copyKSAlias.addLongIdentifier("nickname", true); 3871 copyKSParser.addArgument(copyKSAlias); 3872 3873 copyKSParser.addRequiredArgumentSet(copyKSSourceKeystorePassword, 3874 copyKSSourceKeystorePasswordFile, 3875 copyKSPromptForSourceKeystorePassword); 3876 copyKSParser.addExclusiveArgumentSet(copyKSSourceKeystorePassword, 3877 copyKSSourceKeystorePasswordFile, 3878 copyKSPromptForSourceKeystorePassword); 3879 copyKSParser.addExclusiveArgumentSet(copyKSSourcePKPassword, 3880 copyKSSourcePKPasswordFile, copyKSPromptForDestPKPassword); 3881 copyKSParser.addExclusiveArgumentSet(copyKSDestKeystorePassword, 3882 copyKSDestKeystorePasswordFile, copyKSPromptForDestKeystorePassword); 3883 copyKSParser.addExclusiveArgumentSet(copyKSDestPKPassword, 3884 copyKSDestPKPasswordFile, copyKSPromptForDestPKPassword); 3885 3886 final LinkedHashMap<String[],String> copyKeyStoreExamples = 3887 new LinkedHashMap<>(StaticUtils.computeMapCapacity(1)); 3888 copyKeyStoreExamples.put( 3889 new String[] 3890 { 3891 "copy-keystore", 3892 "--source-keystore", 3893 getPlatformSpecificPath("config", "keystore.jks"), 3894 "--source-keystore-password-file", 3895 getPlatformSpecificPath("config", "keystore.pin"), 3896 "--source-keystore-type", "JKS", 3897 "--destination-keystore", 3898 getPlatformSpecificPath("config", "keystore.p12"), 3899 "--destination-keystore-password-file", 3900 getPlatformSpecificPath("config", "keystore.pin"), 3901 "--destination-keystore-type", "PKCS12" 3902 }, 3903 INFO_MANAGE_CERTS_SC_COPY_KS_EXAMPLE_1.get("keystore.jks", 3904 "keystore.p12")); 3905 3906 final SubCommand copyKeyStoreSubCommand = new SubCommand("copy-keystore", 3907 INFO_MANAGE_CERTS_SC_COPY_KS_DESC.get(), copyKSParser, 3908 copyKeyStoreExamples); 3909 copyKeyStoreSubCommand.addName("copy-key-store", true); 3910 copyKeyStoreSubCommand.addName("copyKeyStore", true); 3911 copyKeyStoreSubCommand.addName("import-keystore", true); 3912 copyKeyStoreSubCommand.addName("import-key-store", true); 3913 copyKeyStoreSubCommand.addName("importKeyStore", true); 3914 copyKeyStoreSubCommand.addName("convert-keystore", true); 3915 copyKeyStoreSubCommand.addName("convert-key-store", true); 3916 copyKeyStoreSubCommand.addName("convertKeyStore", true); 3917 3918 parser.addSubCommand(copyKeyStoreSubCommand); 3919 3920 // Define the "retrieve-server-certificate" subcommand and all of its 3921 // arguments. 3922 final ArgumentParser retrieveCertParser = new ArgumentParser( 3923 "retrieve-server-certificate", 3924 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_DESC.get()); 3925 3926 final StringArgument retrieveCertHostname = new StringArgument('h', 3927 "hostname", true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_HOST.get(), 3928 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_ARG_HOSTNAME_DESC.get()); 3929 retrieveCertHostname.addLongIdentifier("server-address", true); 3930 retrieveCertHostname.addLongIdentifier("serverAddress", true); 3931 retrieveCertHostname.addLongIdentifier("address", true); 3932 retrieveCertParser.addArgument(retrieveCertHostname); 3933 3934 final IntegerArgument retrieveCertPort = new IntegerArgument('p', 3935 "port", true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_PORT.get(), 3936 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_ARG_PORT_DESC.get(), 1, 65_535); 3937 retrieveCertPort.addLongIdentifier("server-port", true); 3938 retrieveCertPort.addLongIdentifier("serverPort", true); 3939 retrieveCertParser.addArgument(retrieveCertPort); 3940 3941 final BooleanArgument retrieveCertUseStartTLS = new BooleanArgument('q', 3942 "use-ldap-start-tls", 1, 3943 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_ARG_USE_START_TLS_DESC.get()); 3944 retrieveCertUseStartTLS.addLongIdentifier("use-ldap-starttls", true); 3945 retrieveCertUseStartTLS.addLongIdentifier("useLDAPStartTLS", true); 3946 retrieveCertUseStartTLS.addLongIdentifier("use-start-tls", true); 3947 retrieveCertUseStartTLS.addLongIdentifier("use-starttls", true); 3948 retrieveCertUseStartTLS.addLongIdentifier("useStartTLS", true); 3949 retrieveCertParser.addArgument(retrieveCertUseStartTLS); 3950 3951 final FileArgument retrieveCertOutputFile = new FileArgument(null, 3952 "output-file", false, 1, null, 3953 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_ARG_FILE_DESC.get(), false, true, 3954 true, false); 3955 retrieveCertOutputFile.addLongIdentifier("outputFile", true); 3956 retrieveCertOutputFile.addLongIdentifier("export-file", true); 3957 retrieveCertOutputFile.addLongIdentifier("exportFile", true); 3958 retrieveCertOutputFile.addLongIdentifier("certificate-file", true); 3959 retrieveCertOutputFile.addLongIdentifier("certificateFile", true); 3960 retrieveCertOutputFile.addLongIdentifier("file", true); 3961 retrieveCertOutputFile.addLongIdentifier("filename", true); 3962 retrieveCertParser.addArgument(retrieveCertOutputFile); 3963 3964 final Set<String> retrieveCertOutputFormatAllowedValues = StaticUtils.setOf( 3965 "PEM", "text", "txt", "RFC", "DER", "binary", "bin"); 3966 final StringArgument retrieveCertOutputFormat = new StringArgument(null, 3967 "output-format", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_FORMAT.get(), 3968 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_ARG_FORMAT_DESC.get(), 3969 retrieveCertOutputFormatAllowedValues, "PEM"); 3970 retrieveCertOutputFormat.addLongIdentifier("outputFormat", true); 3971 retrieveCertParser.addArgument(retrieveCertOutputFormat); 3972 3973 final BooleanArgument retrieveCertOnlyPeer = new BooleanArgument(null, 3974 "only-peer-certificate", 1, 3975 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_ARG_ONLY_PEER_DESC.get()); 3976 retrieveCertOnlyPeer.addLongIdentifier("onlyPeerCertificate", true); 3977 retrieveCertOnlyPeer.addLongIdentifier("only-peer", true); 3978 retrieveCertOnlyPeer.addLongIdentifier("onlyPeer", true); 3979 retrieveCertOnlyPeer.addLongIdentifier("peer-certificate-only", true); 3980 retrieveCertOnlyPeer.addLongIdentifier("peerCertificateOnly", true); 3981 retrieveCertOnlyPeer.addLongIdentifier("peer-only", true); 3982 retrieveCertOnlyPeer.addLongIdentifier("peerOnly", true); 3983 retrieveCertParser.addArgument(retrieveCertOnlyPeer); 3984 3985 final BooleanArgument retrieveCertEnableSSLDebugging = new BooleanArgument( 3986 null, "enableSSLDebugging", 1, 3987 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_ARG_ENABLE_SSL_DEBUGGING_DESC. 3988 get()); 3989 retrieveCertEnableSSLDebugging.addLongIdentifier("enableTLSDebugging", 3990 true); 3991 retrieveCertEnableSSLDebugging.addLongIdentifier("enableStartTLSDebugging", 3992 true); 3993 retrieveCertEnableSSLDebugging.addLongIdentifier("enable-ssl-debugging", 3994 true); 3995 retrieveCertEnableSSLDebugging.addLongIdentifier("enable-tls-debugging", 3996 true); 3997 retrieveCertEnableSSLDebugging.addLongIdentifier( 3998 "enable-starttls-debugging", true); 3999 retrieveCertEnableSSLDebugging.addLongIdentifier( 4000 "enable-start-tls-debugging", true); 4001 retrieveCertParser.addArgument(retrieveCertEnableSSLDebugging); 4002 addEnableSSLDebuggingArgument(retrieveCertEnableSSLDebugging); 4003 4004 final BooleanArgument retrieveCertVerbose = new BooleanArgument(null, 4005 "verbose", 1, 4006 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_ARG_VERBOSE_DESC.get()); 4007 retrieveCertParser.addArgument(retrieveCertVerbose); 4008 4009 retrieveCertParser.addDependentArgumentSet(retrieveCertOutputFormat, 4010 retrieveCertOutputFile); 4011 4012 final LinkedHashMap<String[],String> retrieveCertExamples = 4013 new LinkedHashMap<>(StaticUtils.computeMapCapacity(2)); 4014 retrieveCertExamples.put( 4015 new String[] 4016 { 4017 "retrieve-server-certificate", 4018 "--hostname", "ds.example.com", 4019 "--port", "636" 4020 }, 4021 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_EXAMPLE_1.get( 4022 getPlatformSpecificPath("config", "truststore"))); 4023 retrieveCertExamples.put( 4024 new String[] 4025 { 4026 "retrieve-server-certificate", 4027 "--hostname", "ds.example.com", 4028 "--port", "389", 4029 "--use-ldap-start-tls", 4030 "--only-peer-certificate", 4031 "--output-file", "ds-cert.pem", 4032 "--output-format", "PEM", 4033 "--verbose" 4034 }, 4035 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_EXAMPLE_2.get( 4036 getPlatformSpecificPath("config", "truststore"))); 4037 4038 final SubCommand retrieveCertSubCommand = new SubCommand( 4039 "retrieve-server-certificate", 4040 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_DESC.get(), retrieveCertParser, 4041 retrieveCertExamples); 4042 retrieveCertSubCommand.addName("retrieveServerCertificate", true); 4043 retrieveCertSubCommand.addName("retrieve-certificate", true); 4044 retrieveCertSubCommand.addName("retrieveCertificate", true); 4045 retrieveCertSubCommand.addName("get-server-certificate", true); 4046 retrieveCertSubCommand.addName("getServerCertificate", true); 4047 retrieveCertSubCommand.addName("get-certificate", true); 4048 retrieveCertSubCommand.addName("getCertificate", true); 4049 retrieveCertSubCommand.addName("display-server-certificate", true); 4050 retrieveCertSubCommand.addName("displayServerCertificate", true); 4051 4052 parser.addSubCommand(retrieveCertSubCommand); 4053 4054 4055 // Define the "trust-server-certificate" subcommand and all of its 4056 // arguments. 4057 final ArgumentParser trustServerParser = new ArgumentParser( 4058 "trust-server-certificate", 4059 INFO_MANAGE_CERTS_SC_TRUST_SERVER_DESC.get()); 4060 4061 final StringArgument trustServerHostname = new StringArgument('h', 4062 "hostname", true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_HOST.get(), 4063 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_HOSTNAME_DESC.get()); 4064 trustServerHostname.addLongIdentifier("server-address", true); 4065 trustServerHostname.addLongIdentifier("serverAddress", true); 4066 trustServerHostname.addLongIdentifier("address", true); 4067 trustServerParser.addArgument(trustServerHostname); 4068 4069 final IntegerArgument trustServerPort = new IntegerArgument('p', 4070 "port", true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_PORT.get(), 4071 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_PORT_DESC.get(), 1, 65_535); 4072 trustServerPort.addLongIdentifier("server-port", true); 4073 trustServerPort.addLongIdentifier("serverPort", true); 4074 trustServerParser.addArgument(trustServerPort); 4075 4076 final BooleanArgument trustServerUseStartTLS = new BooleanArgument('q', 4077 "use-ldap-start-tls", 1, 4078 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_USE_START_TLS_DESC.get()); 4079 trustServerUseStartTLS.addLongIdentifier("use-ldap-starttls", true); 4080 trustServerUseStartTLS.addLongIdentifier("useLDAPStartTLS", true); 4081 trustServerUseStartTLS.addLongIdentifier("use-start-tls", true); 4082 trustServerUseStartTLS.addLongIdentifier("use-starttls", true); 4083 trustServerUseStartTLS.addLongIdentifier("useStartTLS", true); 4084 trustServerParser.addArgument(trustServerUseStartTLS); 4085 4086 final FileArgument trustServerKeystore = new FileArgument(null, "keystore", 4087 true, 1, null, INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_KS_DESC.get(), 4088 false, true, true, false); 4089 trustServerKeystore.addLongIdentifier("keystore-path", true); 4090 trustServerKeystore.addLongIdentifier("keystorePath", true); 4091 trustServerKeystore.addLongIdentifier("keystore-file", true); 4092 trustServerKeystore.addLongIdentifier("keystoreFile", true); 4093 trustServerParser.addArgument(trustServerKeystore); 4094 4095 final StringArgument trustServerKeystorePassword = new StringArgument(null, 4096 "keystore-password", false, 1, 4097 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 4098 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_KS_PW_DESC.get()); 4099 trustServerKeystorePassword.addLongIdentifier("keystorePassword", true); 4100 trustServerKeystorePassword.addLongIdentifier("keystore-passphrase", true); 4101 trustServerKeystorePassword.addLongIdentifier("keystorePassphrase", true); 4102 trustServerKeystorePassword.addLongIdentifier("keystore-pin", true); 4103 trustServerKeystorePassword.addLongIdentifier("keystorePIN", true); 4104 trustServerKeystorePassword.addLongIdentifier("storepass", true); 4105 trustServerKeystorePassword.setSensitive(true); 4106 trustServerParser.addArgument(trustServerKeystorePassword); 4107 4108 final FileArgument trustServerKeystorePasswordFile = new FileArgument(null, 4109 "keystore-password-file", false, 1, null, 4110 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_KS_PW_FILE_DESC.get(), true, 4111 true, true, false); 4112 trustServerKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 4113 true); 4114 trustServerKeystorePasswordFile.addLongIdentifier( 4115 "keystore-passphrase-file", true); 4116 trustServerKeystorePasswordFile.addLongIdentifier("keystorePassphraseFile", 4117 true); 4118 trustServerKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 4119 true); 4120 trustServerKeystorePasswordFile.addLongIdentifier("keystorePINFile", true); 4121 trustServerParser.addArgument(trustServerKeystorePasswordFile); 4122 4123 final BooleanArgument trustServerPromptForKeystorePassword = 4124 new BooleanArgument(null, "prompt-for-keystore-password", 4125 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_PROMPT_FOR_KS_PW_DESC.get()); 4126 trustServerPromptForKeystorePassword.addLongIdentifier( 4127 "promptForKeystorePassword", true); 4128 trustServerPromptForKeystorePassword.addLongIdentifier( 4129 "prompt-for-keystore-passphrase", true); 4130 trustServerPromptForKeystorePassword.addLongIdentifier( 4131 "promptForKeystorePassphrase", true); 4132 trustServerPromptForKeystorePassword.addLongIdentifier( 4133 "prompt-for-keystore-pin", true); 4134 trustServerPromptForKeystorePassword.addLongIdentifier( 4135 "promptForKeystorePIN", true); 4136 trustServerParser.addArgument(trustServerPromptForKeystorePassword); 4137 4138 final StringArgument trustServerKeystoreType = new StringArgument(null, 4139 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 4140 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_KS_TYPE_DESC.get(), 4141 ALLOWED_KEYSTORE_TYPE_VALUES); 4142 trustServerKeystoreType.addLongIdentifier("key-store-type", true); 4143 trustServerKeystoreType.addLongIdentifier("keystoreType", true); 4144 trustServerKeystoreType.addLongIdentifier("keystore-format", true); 4145 trustServerKeystoreType.addLongIdentifier("key-store-format", true); 4146 trustServerKeystoreType.addLongIdentifier("keystoreFormat", true); 4147 trustServerKeystoreType.addLongIdentifier("storetype", true); 4148 trustServerParser.addArgument(trustServerKeystoreType); 4149 4150 final StringArgument trustServerAlias = new StringArgument(null, 4151 "alias", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 4152 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_ALIAS_DESC.get()); 4153 trustServerAlias.addLongIdentifier("nickname", true); 4154 trustServerParser.addArgument(trustServerAlias); 4155 4156 final BooleanArgument trustServerIssuersOnly = new BooleanArgument(null, 4157 "issuers-only", 1, 4158 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_ISSUERS_ONLY_DESC.get()); 4159 trustServerIssuersOnly.addLongIdentifier("issuersOnly", true); 4160 trustServerIssuersOnly.addLongIdentifier("issuer-certificates-only", true); 4161 trustServerIssuersOnly.addLongIdentifier("issuerCertificatesOnly", true); 4162 trustServerIssuersOnly.addLongIdentifier("only-issuers", true); 4163 trustServerIssuersOnly.addLongIdentifier("onlyIssuers", true); 4164 trustServerIssuersOnly.addLongIdentifier("only-issuer-certificates", true); 4165 trustServerIssuersOnly.addLongIdentifier("onlyIssuerCertificates", true); 4166 trustServerParser.addArgument(trustServerIssuersOnly); 4167 4168 final BooleanArgument trustServerEnableSSLDebugging = new BooleanArgument( 4169 null, "enableSSLDebugging", 1, 4170 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_ENABLE_SSL_DEBUGGING_DESC.get()); 4171 trustServerEnableSSLDebugging.addLongIdentifier("enableTLSDebugging", true); 4172 trustServerEnableSSLDebugging.addLongIdentifier("enableStartTLSDebugging", 4173 true); 4174 trustServerEnableSSLDebugging.addLongIdentifier("enable-ssl-debugging", 4175 true); 4176 trustServerEnableSSLDebugging.addLongIdentifier("enable-tls-debugging", 4177 true); 4178 trustServerEnableSSLDebugging.addLongIdentifier("enable-starttls-debugging", 4179 true); 4180 trustServerEnableSSLDebugging.addLongIdentifier( 4181 "enable-start-tls-debugging", true); 4182 trustServerParser.addArgument(trustServerEnableSSLDebugging); 4183 addEnableSSLDebuggingArgument(trustServerEnableSSLDebugging); 4184 4185 final BooleanArgument trustServerVerbose = new BooleanArgument(null, 4186 "verbose", 1, 4187 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_VERBOSE_DESC.get()); 4188 trustServerParser.addArgument(trustServerVerbose); 4189 4190 final BooleanArgument trustServerNoPrompt = new BooleanArgument(null, 4191 "no-prompt", 1, 4192 INFO_MANAGE_CERTS_SC_TRUST_SERVER_ARG_NO_PROMPT_DESC.get()); 4193 trustServerNoPrompt.addLongIdentifier("noPrompt", true); 4194 trustServerParser.addArgument(trustServerNoPrompt); 4195 4196 trustServerParser.addRequiredArgumentSet(trustServerKeystorePassword, 4197 trustServerKeystorePasswordFile, trustServerPromptForKeystorePassword); 4198 trustServerParser.addExclusiveArgumentSet(trustServerKeystorePassword, 4199 trustServerKeystorePasswordFile, trustServerPromptForKeystorePassword); 4200 4201 final LinkedHashMap<String[],String> trustServerExamples = 4202 new LinkedHashMap<>(StaticUtils.computeMapCapacity(2)); 4203 trustServerExamples.put( 4204 new String[] 4205 { 4206 "trust-server-certificate", 4207 "--hostname", "ds.example.com", 4208 "--port", "636", 4209 "--keystore", getPlatformSpecificPath("config", "truststore"), 4210 "--keystore-password-file", 4211 getPlatformSpecificPath("config", "truststore.pin"), 4212 "--verbose" 4213 }, 4214 INFO_MANAGE_CERTS_SC_TRUST_SERVER_EXAMPLE_1.get( 4215 getPlatformSpecificPath("config", "truststore"))); 4216 trustServerExamples.put( 4217 new String[] 4218 { 4219 "trust-server-certificate", 4220 "--hostname", "ds.example.com", 4221 "--port", "389", 4222 "--use-ldap-start-tls", 4223 "--keystore", getPlatformSpecificPath("config", "truststore"), 4224 "--keystore-password-file", 4225 getPlatformSpecificPath("config", "truststore.pin"), 4226 "--issuers-only", 4227 "--alias", "ds-start-tls-cert", 4228 "--no-prompt" 4229 }, 4230 INFO_MANAGE_CERTS_SC_TRUST_SERVER_EXAMPLE_2.get( 4231 getPlatformSpecificPath("config", "truststore"))); 4232 4233 final SubCommand trustServerSubCommand = new SubCommand( 4234 "trust-server-certificate", 4235 INFO_MANAGE_CERTS_SC_TRUST_SERVER_DESC.get(), trustServerParser, 4236 trustServerExamples); 4237 trustServerSubCommand.addName("trustServerCertificate", true); 4238 trustServerSubCommand.addName("trust-server", true); 4239 trustServerSubCommand.addName("trustServer", true); 4240 4241 parser.addSubCommand(trustServerSubCommand); 4242 4243 4244 // Define the "check-certificate-usability" subcommand and all of its 4245 // arguments. 4246 final ArgumentParser checkUsabilityParser = new ArgumentParser( 4247 "check-certificate-usability", 4248 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_DESC.get()); 4249 4250 final FileArgument checkUsabilityKeystore = new FileArgument(null, 4251 "keystore", true, 1, null, 4252 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_ARG_KS_DESC.get(), 4253 true, true, true, false); 4254 checkUsabilityKeystore.addLongIdentifier("keystore-path", true); 4255 checkUsabilityKeystore.addLongIdentifier("keystorePath", true); 4256 checkUsabilityKeystore.addLongIdentifier("keystore-file", true); 4257 checkUsabilityKeystore.addLongIdentifier("keystoreFile", true); 4258 checkUsabilityParser.addArgument(checkUsabilityKeystore); 4259 4260 final StringArgument checkUsabilityKeystorePassword = new StringArgument( 4261 null, "keystore-password", false, 1, 4262 INFO_MANAGE_CERTS_PLACEHOLDER_PASSWORD.get(), 4263 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_ARG_KS_PW_DESC.get()); 4264 checkUsabilityKeystorePassword.addLongIdentifier("keystorePassword", true); 4265 checkUsabilityKeystorePassword.addLongIdentifier("keystore-passphrase", 4266 true); 4267 checkUsabilityKeystorePassword.addLongIdentifier("keystorePassphrase", 4268 true); 4269 checkUsabilityKeystorePassword.addLongIdentifier("keystore-pin", true); 4270 checkUsabilityKeystorePassword.addLongIdentifier("keystorePIN", true); 4271 checkUsabilityKeystorePassword.addLongIdentifier("storepass", true); 4272 checkUsabilityKeystorePassword.setSensitive(true); 4273 checkUsabilityParser.addArgument(checkUsabilityKeystorePassword); 4274 4275 final FileArgument checkUsabilityKeystorePasswordFile = new FileArgument( 4276 null, "keystore-password-file", false, 1, null, 4277 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_ARG_KS_PW_FILE_DESC.get(), true, 4278 true, true, false); 4279 checkUsabilityKeystorePasswordFile.addLongIdentifier("keystorePasswordFile", 4280 true); 4281 checkUsabilityKeystorePasswordFile.addLongIdentifier( 4282 "keystore-passphrase-file", true); 4283 checkUsabilityKeystorePasswordFile.addLongIdentifier( 4284 "keystorePassphraseFile", true); 4285 checkUsabilityKeystorePasswordFile.addLongIdentifier("keystore-pin-file", 4286 true); 4287 checkUsabilityKeystorePasswordFile.addLongIdentifier("keystorePINFile", 4288 true); 4289 checkUsabilityParser.addArgument(checkUsabilityKeystorePasswordFile); 4290 4291 final BooleanArgument checkUsabilityPromptForKeystorePassword = 4292 new BooleanArgument(null, "prompt-for-keystore-password", 4293 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_ARG_PROMPT_FOR_KS_PW_DESC.get()); 4294 checkUsabilityPromptForKeystorePassword.addLongIdentifier( 4295 "promptForKeystorePassword", true); 4296 checkUsabilityPromptForKeystorePassword.addLongIdentifier( 4297 "prompt-for-keystore-passphrase", true); 4298 checkUsabilityPromptForKeystorePassword.addLongIdentifier( 4299 "promptForKeystorePassphrase", true); 4300 checkUsabilityPromptForKeystorePassword.addLongIdentifier( 4301 "prompt-for-keystore-pin", true); 4302 checkUsabilityPromptForKeystorePassword.addLongIdentifier( 4303 "promptForKeystorePIN", true); 4304 checkUsabilityParser.addArgument(checkUsabilityPromptForKeystorePassword); 4305 4306 final StringArgument checkUsabilityKeystoreType = new StringArgument(null, 4307 "keystore-type", false, 1, INFO_MANAGE_CERTS_PLACEHOLDER_TYPE.get(), 4308 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_ARG_KS_TYPE_DESC.get(), 4309 ALLOWED_KEYSTORE_TYPE_VALUES); 4310 checkUsabilityKeystoreType.addLongIdentifier("key-store-type", true); 4311 checkUsabilityKeystoreType.addLongIdentifier("keystoreType", true); 4312 checkUsabilityKeystoreType.addLongIdentifier("keystore-format", true); 4313 checkUsabilityKeystoreType.addLongIdentifier("key-store-format", true); 4314 checkUsabilityKeystoreType.addLongIdentifier("keystoreFormat", true); 4315 checkUsabilityKeystoreType.addLongIdentifier("storetype", true); 4316 checkUsabilityParser.addArgument(checkUsabilityKeystoreType); 4317 4318 final StringArgument checkUsabilityAlias = new StringArgument(null, "alias", 4319 true, 1, INFO_MANAGE_CERTS_PLACEHOLDER_ALIAS.get(), 4320 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_ARG_ALIAS_DESC.get()); 4321 checkUsabilityAlias.addLongIdentifier("nickname", true); 4322 checkUsabilityParser.addArgument(checkUsabilityAlias); 4323 4324 final BooleanArgument checkUsabilityIgnoreSHA1Signature = 4325 new BooleanArgument(null, 4326 "allow-sha-1-signature-for-issuer-certificates", 1, 4327 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_IGNORE_SHA1_WARNING_DESC. 4328 get()); 4329 checkUsabilityIgnoreSHA1Signature.addLongIdentifier( 4330 "allow-sha1-signature-for-issuer-certificates", true); 4331 checkUsabilityIgnoreSHA1Signature.addLongIdentifier( 4332 "allowSHA1SignatureForIssuerCertificates", true); 4333 checkUsabilityParser.addArgument(checkUsabilityIgnoreSHA1Signature); 4334 4335 checkUsabilityParser.addRequiredArgumentSet(checkUsabilityKeystorePassword, 4336 checkUsabilityKeystorePasswordFile, 4337 checkUsabilityPromptForKeystorePassword); 4338 checkUsabilityParser.addExclusiveArgumentSet(checkUsabilityKeystorePassword, 4339 checkUsabilityKeystorePasswordFile, 4340 checkUsabilityPromptForKeystorePassword); 4341 4342 final LinkedHashMap<String[],String> checkUsabilityExamples = 4343 new LinkedHashMap<>(StaticUtils.computeMapCapacity(2)); 4344 checkUsabilityExamples.put( 4345 new String[] 4346 { 4347 "check-certificate-usability", 4348 "--keystore", getPlatformSpecificPath("config", "keystore"), 4349 "--keystore-password-file", 4350 getPlatformSpecificPath("config", "keystore.pin"), 4351 "--alias", "server-cert" 4352 }, 4353 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_EXAMPLE_1.get( 4354 getPlatformSpecificPath("config", "keystore"))); 4355 4356 final SubCommand checkUsabilitySubCommand = new SubCommand( 4357 "check-certificate-usability", 4358 INFO_MANAGE_CERTS_SC_CHECK_USABILITY_DESC.get(), checkUsabilityParser, 4359 checkUsabilityExamples); 4360 checkUsabilitySubCommand.addName("checkCertificateUsability", true); 4361 checkUsabilitySubCommand.addName("check-usability", true); 4362 checkUsabilitySubCommand.addName("checkUsability", true); 4363 4364 parser.addSubCommand(checkUsabilitySubCommand); 4365 4366 4367 // Define the "display-certificate-file" subcommand and all of its 4368 // arguments. 4369 final ArgumentParser displayCertParser = new ArgumentParser( 4370 "display-certificate-file", 4371 INFO_MANAGE_CERTS_SC_DISPLAY_CERT_DESC.get()); 4372 4373 final FileArgument displayCertFile = new FileArgument(null, 4374 "certificate-file", true, 1, null, 4375 INFO_MANAGE_CERTS_SC_DISPLAY_CERT_ARG_FILE_DESC.get(), true, true, 4376 true, false); 4377 displayCertFile.addLongIdentifier("certificateFile", true); 4378 displayCertFile.addLongIdentifier("input-file", true); 4379 displayCertFile.addLongIdentifier("inputFile", true); 4380 displayCertFile.addLongIdentifier("file", true); 4381 displayCertFile.addLongIdentifier("filename", true); 4382 displayCertParser.addArgument(displayCertFile); 4383 4384 final BooleanArgument displayCertVerbose = new BooleanArgument(null, 4385 "verbose", 1, 4386 INFO_MANAGE_CERTS_SC_DISPLAY_CERT_ARG_VERBOSE_DESC.get()); 4387 displayCertParser.addArgument(displayCertVerbose); 4388 4389 final BooleanArgument displayCertDisplayCommand = new BooleanArgument(null, 4390 "display-keytool-command", 1, 4391 INFO_MANAGE_CERTS_SC_DISPLAY_CERT_ARG_DISPLAY_COMMAND_DESC.get()); 4392 displayCertDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 4393 displayCertDisplayCommand.addLongIdentifier("show-keytool-command", true); 4394 displayCertDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 4395 displayCertParser.addArgument(displayCertDisplayCommand); 4396 4397 final LinkedHashMap<String[],String> displayCertExamples = 4398 new LinkedHashMap<>(StaticUtils.computeMapCapacity(2)); 4399 displayCertExamples.put( 4400 new String[] 4401 { 4402 "display-certificate-file", 4403 "--certificate-file", "certificate.pem", 4404 }, 4405 INFO_MANAGE_CERTS_SC_DISPLAY_CERT_EXAMPLE_1.get("certificate.pem")); 4406 displayCertExamples.put( 4407 new String[] 4408 { 4409 "display-certificate-file", 4410 "--certificate-file", "certificate.pem", 4411 "--verbose", 4412 "--display-keytool-command" 4413 }, 4414 INFO_MANAGE_CERTS_SC_DISPLAY_CERT_EXAMPLE_2.get("certificate.pem")); 4415 4416 final SubCommand displayCertSubCommand = new SubCommand( 4417 "display-certificate-file", 4418 INFO_MANAGE_CERTS_SC_DISPLAY_CERT_DESC.get(), displayCertParser, 4419 displayCertExamples); 4420 displayCertSubCommand.addName("displayCertificateFile", true); 4421 displayCertSubCommand.addName("display-certificate", true); 4422 displayCertSubCommand.addName("displayCertificate", true); 4423 displayCertSubCommand.addName("display-certificates", true); 4424 displayCertSubCommand.addName("displayCertificates", true); 4425 displayCertSubCommand.addName("show-certificate", true); 4426 displayCertSubCommand.addName("showCertificate", true); 4427 displayCertSubCommand.addName("show-certificate-file", true); 4428 displayCertSubCommand.addName("showCertificateFile", true); 4429 displayCertSubCommand.addName("show-certificates", true); 4430 displayCertSubCommand.addName("showCertificates", true); 4431 displayCertSubCommand.addName("print-certificate-file", true); 4432 displayCertSubCommand.addName("printCertificateFile", true); 4433 displayCertSubCommand.addName("print-certificate", true); 4434 displayCertSubCommand.addName("printCertificate", true); 4435 displayCertSubCommand.addName("print-certificates", true); 4436 displayCertSubCommand.addName("printCertificates", true); 4437 displayCertSubCommand.addName("printcert", true); 4438 4439 parser.addSubCommand(displayCertSubCommand); 4440 4441 4442 // Define the "display-certificate-signing-request-file" subcommand and all 4443 // of its arguments. 4444 final ArgumentParser displayCSRParser = new ArgumentParser( 4445 "display-certificate-signing-request-file", 4446 INFO_MANAGE_CERTS_SC_DISPLAY_CSR_DESC.get()); 4447 4448 final FileArgument displayCSRFile = new FileArgument(null, 4449 "certificate-signing-request-file", true, 1, null, 4450 INFO_MANAGE_CERTS_SC_DISPLAY_CSR_ARG_FILE_DESC.get(), true, true, 4451 true, false); 4452 displayCSRFile.addLongIdentifier("certificateSigningRequestFile", true); 4453 displayCSRFile.addLongIdentifier("request-file", true); 4454 displayCSRFile.addLongIdentifier("requestFile", true); 4455 displayCSRFile.addLongIdentifier("input-file", true); 4456 displayCSRFile.addLongIdentifier("inputFile", true); 4457 displayCSRFile.addLongIdentifier("file", true); 4458 displayCSRFile.addLongIdentifier("filename", true); 4459 displayCSRParser.addArgument(displayCSRFile); 4460 4461 final BooleanArgument displayCSRVerbose = new BooleanArgument(null, 4462 "verbose", 1, 4463 INFO_MANAGE_CERTS_SC_DISPLAY_CSR_ARG_VERBOSE_DESC.get()); 4464 displayCSRParser.addArgument(displayCSRVerbose); 4465 4466 final BooleanArgument displayCSRDisplayCommand = new BooleanArgument(null, 4467 "display-keytool-command", 1, 4468 INFO_MANAGE_CERTS_SC_DISPLAY_CSR_ARG_DISPLAY_COMMAND_DESC.get()); 4469 displayCSRDisplayCommand.addLongIdentifier("displayKeytoolCommand", true); 4470 displayCSRDisplayCommand.addLongIdentifier("show-keytool-command", true); 4471 displayCSRDisplayCommand.addLongIdentifier("showKeytoolCommand", true); 4472 displayCSRParser.addArgument(displayCSRDisplayCommand); 4473 4474 final LinkedHashMap<String[],String> displayCSRExamples = 4475 new LinkedHashMap<>(StaticUtils.computeMapCapacity(1)); 4476 displayCSRExamples.put( 4477 new String[] 4478 { 4479 "display-certificate-signing-request-file", 4480 "--certificate-signing-request-file", "server-cert.csr", 4481 "--display-keytool-command" 4482 }, 4483 INFO_MANAGE_CERTS_SC_DISPLAY_CSR_EXAMPLE_1.get("server-cert.csr")); 4484 4485 final SubCommand displayCSRSubCommand = new SubCommand( 4486 "display-certificate-signing-request-file", 4487 INFO_MANAGE_CERTS_SC_DISPLAY_CSR_DESC.get(), displayCSRParser, 4488 displayCSRExamples); 4489 displayCSRSubCommand.addName("displayCertificateSigningRequestFile", true); 4490 displayCSRSubCommand.addName("display-certificate-signing-request", true); 4491 displayCSRSubCommand.addName("displayCertificateSigningRequest", true); 4492 displayCSRSubCommand.addName("display-certificate-request-file", true); 4493 displayCSRSubCommand.addName("displayCertificateRequestFile", true); 4494 displayCSRSubCommand.addName("display-certificate-request", true); 4495 displayCSRSubCommand.addName("displayCertificateRequest", true); 4496 displayCSRSubCommand.addName("display-csr-file", true); 4497 displayCSRSubCommand.addName("displayCSRFile", true); 4498 displayCSRSubCommand.addName("display-csr", true); 4499 displayCSRSubCommand.addName("displayCSR", true); 4500 displayCSRSubCommand.addName("show-certificate-signing-request-file", true); 4501 displayCSRSubCommand.addName("showCertificateSigningRequestFile", true); 4502 displayCSRSubCommand.addName("show-certificate-signing-request", true); 4503 displayCSRSubCommand.addName("showCertificateSigningRequest", true); 4504 displayCSRSubCommand.addName("show-certificate-request-file", true); 4505 displayCSRSubCommand.addName("showCertificateRequestFile", true); 4506 displayCSRSubCommand.addName("show-certificate-request", true); 4507 displayCSRSubCommand.addName("showCertificateRequest", true); 4508 displayCSRSubCommand.addName("show-csr-file", true); 4509 displayCSRSubCommand.addName("showCSRFile", true); 4510 displayCSRSubCommand.addName("show-csr", true); 4511 displayCSRSubCommand.addName("showCSR", true); 4512 displayCSRSubCommand.addName("print-certificate-signing-request-file", 4513 true); 4514 displayCSRSubCommand.addName("printCertificateSigningRequestFile", true); 4515 displayCSRSubCommand.addName("print-certificate-signing-request", true); 4516 displayCSRSubCommand.addName("printCertificateSigningRequest", true); 4517 displayCSRSubCommand.addName("print-certificate-request-file", true); 4518 displayCSRSubCommand.addName("printCertificateRequestFile", true); 4519 displayCSRSubCommand.addName("print-certificate-request", true); 4520 displayCSRSubCommand.addName("printCertificateRequest", true); 4521 displayCSRSubCommand.addName("print-csr-file", true); 4522 displayCSRSubCommand.addName("printCSRFile", true); 4523 displayCSRSubCommand.addName("print-csr", true); 4524 displayCSRSubCommand.addName("printCSR", true); 4525 displayCSRSubCommand.addName("printcertreq", true); 4526 4527 parser.addSubCommand(displayCSRSubCommand); 4528 } 4529 4530 4531 4532 /** 4533 * Constructs a platform-specific relative path from the provided elements. 4534 * 4535 * @param pathElements The elements of the path to construct. It must not 4536 * be {@code null} or empty. 4537 * 4538 * @return The constructed path. 4539 */ 4540 @NotNull() 4541 private static String getPlatformSpecificPath( 4542 @NotNull final String... pathElements) 4543 { 4544 final StringBuilder buffer = new StringBuilder(); 4545 for (int i=0; i < pathElements.length; i++) 4546 { 4547 if (i > 0) 4548 { 4549 buffer.append(File.separatorChar); 4550 } 4551 4552 buffer.append(pathElements[i]); 4553 } 4554 4555 return buffer.toString(); 4556 } 4557 4558 4559 4560 /** 4561 * Performs the core set of processing for this tool. 4562 * 4563 * @return A result code that indicates whether the processing completed 4564 * successfully. 4565 */ 4566 @Override() 4567 @NotNull() 4568 public ResultCode doToolProcessing() 4569 { 4570 final SubCommand selectedSubCommand = globalParser.getSelectedSubCommand(); 4571 if (selectedSubCommand == null) 4572 { 4573 // This should never happen. 4574 wrapErr(0, WRAP_COLUMN, ERR_MANAGE_CERTS_NO_SUBCOMMAND.get()); 4575 return ResultCode.PARAM_ERROR; 4576 } 4577 4578 subCommandParser = selectedSubCommand.getArgumentParser(); 4579 4580 if (selectedSubCommand.hasName("list-certificates")) 4581 { 4582 return doListCertificates(); 4583 } 4584 else if (selectedSubCommand.hasName("export-certificate")) 4585 { 4586 return doExportCertificate(); 4587 } 4588 else if (selectedSubCommand.hasName("export-private-key")) 4589 { 4590 return doExportPrivateKey(); 4591 } 4592 else if (selectedSubCommand.hasName("import-certificate")) 4593 { 4594 return doImportCertificate(); 4595 } 4596 else if (selectedSubCommand.hasName("delete-certificate")) 4597 { 4598 return doDeleteCertificate(); 4599 } 4600 else if (selectedSubCommand.hasName("generate-self-signed-certificate")) 4601 { 4602 return doGenerateOrSignCertificateOrCSR(); 4603 } 4604 else if (selectedSubCommand.hasName("generate-certificate-signing-request")) 4605 { 4606 return doGenerateOrSignCertificateOrCSR(); 4607 } 4608 else if (selectedSubCommand.hasName("sign-certificate-signing-request")) 4609 { 4610 return doGenerateOrSignCertificateOrCSR(); 4611 } 4612 else if (selectedSubCommand.hasName("change-certificate-alias")) 4613 { 4614 return doChangeCertificateAlias(); 4615 } 4616 else if (selectedSubCommand.hasName("change-keystore-password")) 4617 { 4618 return doChangeKeystorePassword(); 4619 } 4620 else if (selectedSubCommand.hasName("change-private-key-password")) 4621 { 4622 return doChangePrivateKeyPassword(); 4623 } 4624 else if (selectedSubCommand.hasName("copy-keystore")) 4625 { 4626 return doCopyKeystore(); 4627 } 4628 else if (selectedSubCommand.hasName("retrieve-server-certificate")) 4629 { 4630 return doRetrieveServerCertificate(); 4631 } 4632 else if (selectedSubCommand.hasName("trust-server-certificate")) 4633 { 4634 return doTrustServerCertificate(); 4635 } 4636 else if (selectedSubCommand.hasName("check-certificate-usability")) 4637 { 4638 return doCheckCertificateUsability(); 4639 } 4640 else if (selectedSubCommand.hasName("display-certificate-file")) 4641 { 4642 return doDisplayCertificateFile(); 4643 } 4644 else if (selectedSubCommand.hasName( 4645 "display-certificate-signing-request-file")) 4646 { 4647 return doDisplayCertificateSigningRequestFile(); 4648 } 4649 else 4650 { 4651 // This should never happen. 4652 wrapErr(0, WRAP_COLUMN, 4653 ERR_MANAGE_CERTS_UNKNOWN_SUBCOMMAND.get( 4654 selectedSubCommand.getPrimaryName())); 4655 return ResultCode.PARAM_ERROR; 4656 } 4657 } 4658 4659 4660 4661 /** 4662 * Performs the necessary processing for the list-certificates subcommand. 4663 * 4664 * @return A result code that indicates whether the processing completed 4665 * successfully. 4666 */ 4667 @NotNull() 4668 private ResultCode doListCertificates() 4669 { 4670 // Get the values of a number of configured arguments. 4671 final BooleanArgument displayPEMArgument = 4672 subCommandParser.getBooleanArgument("display-pem-certificate"); 4673 final boolean displayPEM = 4674 ((displayPEMArgument != null) && displayPEMArgument.isPresent()); 4675 4676 final BooleanArgument verboseArgument = 4677 subCommandParser.getBooleanArgument("verbose"); 4678 final boolean verbose = 4679 ((verboseArgument != null) && verboseArgument.isPresent()); 4680 4681 final Map<String,String> missingAliases; 4682 final Set<String> aliases; 4683 final StringArgument aliasArgument = 4684 subCommandParser.getStringArgument("alias"); 4685 if ((aliasArgument == null) || (! aliasArgument.isPresent())) 4686 { 4687 aliases = Collections.emptySet(); 4688 missingAliases = Collections.emptyMap(); 4689 } 4690 else 4691 { 4692 final List<String> values = aliasArgument.getValues(); 4693 aliases = new LinkedHashSet<>(StaticUtils.computeMapCapacity( 4694 values.size())); 4695 missingAliases = 4696 new LinkedHashMap<>(StaticUtils.computeMapCapacity(values.size())); 4697 for (final String alias : values) 4698 { 4699 final String lowerAlias = StaticUtils.toLowerCase(alias); 4700 aliases.add(StaticUtils.toLowerCase(lowerAlias)); 4701 missingAliases.put(lowerAlias, alias); 4702 } 4703 } 4704 4705 final String keystoreType; 4706 final File keystorePath = getKeystorePath(); 4707 try 4708 { 4709 keystoreType = inferKeystoreType(keystorePath); 4710 } 4711 catch (final LDAPException le) 4712 { 4713 Debug.debugException(le); 4714 wrapErr(0, WRAP_COLUMN, le.getMessage()); 4715 return le.getResultCode(); 4716 } 4717 4718 final char[] keystorePassword; 4719 try 4720 { 4721 keystorePassword = getKeystorePassword(keystorePath); 4722 } 4723 catch (final LDAPException le) 4724 { 4725 Debug.debugException(le); 4726 wrapErr(0, WRAP_COLUMN, le.getMessage()); 4727 return le.getResultCode(); 4728 } 4729 4730 final BooleanArgument displayKeytoolCommandArgument = 4731 subCommandParser.getBooleanArgument("display-keytool-command"); 4732 if ((displayKeytoolCommandArgument != null) && 4733 displayKeytoolCommandArgument.isPresent()) 4734 { 4735 final ArrayList<String> keytoolArgs = new ArrayList<>(10); 4736 keytoolArgs.add("-list"); 4737 4738 keytoolArgs.add("-keystore"); 4739 keytoolArgs.add(keystorePath.getAbsolutePath()); 4740 keytoolArgs.add("-storetype"); 4741 keytoolArgs.add(keystoreType); 4742 4743 if (keystorePassword != null) 4744 { 4745 keytoolArgs.add("-storepass"); 4746 keytoolArgs.add("*****REDACTED*****"); 4747 } 4748 4749 for (final String alias : missingAliases.values()) 4750 { 4751 keytoolArgs.add("-alias"); 4752 keytoolArgs.add(alias); 4753 } 4754 4755 if (displayPEM) 4756 { 4757 keytoolArgs.add("-rfc"); 4758 } 4759 4760 if (verbose) 4761 { 4762 keytoolArgs.add("-v"); 4763 } 4764 4765 displayKeytoolCommand(keytoolArgs); 4766 } 4767 4768 4769 // Get the keystore. 4770 final KeyStore keystore; 4771 try 4772 { 4773 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 4774 } 4775 catch (final LDAPException le) 4776 { 4777 Debug.debugException(le); 4778 wrapErr(0, WRAP_COLUMN, le.getMessage()); 4779 return le.getResultCode(); 4780 } 4781 4782 4783 // Display a message with the keystore type. 4784 wrapOut(0, WRAP_COLUMN, 4785 INFO_MANAGE_CERTS_LIST_KEYSTORE_TYPE.get(keystoreType)); 4786 4787 4788 // Iterate through the keystore and display the appropriate certificates. 4789 final Enumeration<String> aliasEnumeration; 4790 try 4791 { 4792 aliasEnumeration = keystore.aliases(); 4793 } 4794 catch (final Exception e) 4795 { 4796 Debug.debugException(e); 4797 err(); 4798 wrapErr(0, WRAP_COLUMN, 4799 ERR_MANAGE_CERTS_LIST_CERTS_CANNOT_GET_ALIASES.get( 4800 keystorePath.getAbsolutePath())); 4801 e.printStackTrace(getErr()); 4802 return ResultCode.LOCAL_ERROR; 4803 } 4804 4805 int listedCount = 0; 4806 ResultCode resultCode = ResultCode.SUCCESS; 4807 while (aliasEnumeration.hasMoreElements()) 4808 { 4809 final String alias = aliasEnumeration.nextElement(); 4810 final String lowerAlias = StaticUtils.toLowerCase(alias); 4811 if ((!aliases.isEmpty()) && (missingAliases.remove(lowerAlias) == null)) 4812 { 4813 // We don't care about this alias. 4814 continue; 4815 } 4816 4817 final X509Certificate[] certificateChain; 4818 try 4819 { 4820 // NOTE: Keystore entries that have private keys may have a certificate 4821 // chain associated with them (the end certificate plus all of the 4822 // issuer certificates). In that case all of those certificates in the 4823 // chain will be stored under the same alias, and the only way we can 4824 // access them is to call the getCertificateChain method. However, if 4825 // the keystore only has a certificate for the alias but no private key, 4826 // then the entry will not have a chain, and the call to 4827 // getCertificateChain will return null for that alias. We want to be 4828 // able to handle both of these cases, so we will first try 4829 // getCertificateChain to see if we can get a complete chain, but if 4830 // that returns null, then use getCertificate to see if we can get a 4831 // single certificate. That call to getCertificate can also return null 4832 // because the entry with this alias might be some other type of entry, 4833 // like a secret key entry. 4834 Certificate[] chain = keystore.getCertificateChain(alias); 4835 if ((chain == null) || (chain.length == 0)) 4836 { 4837 final Certificate cert = keystore.getCertificate(alias); 4838 if (cert == null) 4839 { 4840 continue; 4841 } 4842 else 4843 { 4844 chain = new Certificate[] { cert }; 4845 } 4846 } 4847 4848 certificateChain = new X509Certificate[chain.length]; 4849 for (int i = 0; i < chain.length; i++) 4850 { 4851 certificateChain[i] = new X509Certificate(chain[i].getEncoded()); 4852 } 4853 } 4854 catch (final Exception e) 4855 { 4856 Debug.debugException(e); 4857 err(); 4858 wrapErr(0, WRAP_COLUMN, 4859 ERR_MANAGE_CERTS_LIST_CERTS_ERROR_GETTING_CERT.get(alias, 4860 StaticUtils.getExceptionMessage(e))); 4861 resultCode = ResultCode.LOCAL_ERROR; 4862 continue; 4863 } 4864 4865 listedCount++; 4866 for (int i = 0; i < certificateChain.length; i++) 4867 { 4868 out(); 4869 if (certificateChain.length == 1) 4870 { 4871 out(INFO_MANAGE_CERTS_LIST_CERTS_LABEL_ALIAS_WITHOUT_CHAIN.get( 4872 alias)); 4873 } 4874 else 4875 { 4876 out(INFO_MANAGE_CERTS_LIST_CERTS_LABEL_ALIAS_WITH_CHAIN.get(alias, 4877 (i + 1), certificateChain.length)); 4878 } 4879 4880 printCertificate(certificateChain[i], "", verbose); 4881 4882 if (i == 0) 4883 { 4884 if (hasKeyAlias(keystore, alias)) 4885 { 4886 out(INFO_MANAGE_CERTS_LIST_CERTS_LABEL_HAS_PK_YES.get()); 4887 } 4888 else 4889 { 4890 out(INFO_MANAGE_CERTS_LIST_CERTS_LABEL_HAS_PK_NO.get()); 4891 } 4892 } 4893 4894 CertException signatureVerificationException = null; 4895 if (certificateChain[i].isSelfSigned()) 4896 { 4897 try 4898 { 4899 certificateChain[i].verifySignature(null); 4900 } 4901 catch (final CertException ce) 4902 { 4903 Debug.debugException(ce); 4904 signatureVerificationException = ce; 4905 } 4906 } 4907 else 4908 { 4909 X509Certificate issuerCertificate = null; 4910 try 4911 { 4912 final AtomicReference<KeyStore> jvmDefaultTrustStoreRef = 4913 new AtomicReference<>(); 4914 final AtomicReference<DN> missingIssuerRef = 4915 new AtomicReference<>(); 4916 issuerCertificate = getIssuerCertificate(certificateChain[i], 4917 keystore, jvmDefaultTrustStoreRef, missingIssuerRef); 4918 } 4919 catch (final Exception e) 4920 { 4921 Debug.debugException(e); 4922 } 4923 4924 if (issuerCertificate == null) 4925 { 4926 signatureVerificationException = new CertException( 4927 ERR_MANAGE_CERTS_LIST_CERTS_VERIFY_SIGNATURE_NO_ISSUER.get( 4928 certificateChain[i].getIssuerDN())); 4929 } 4930 else 4931 { 4932 try 4933 { 4934 certificateChain[i].verifySignature(issuerCertificate); 4935 } 4936 catch (final CertException ce) 4937 { 4938 Debug.debugException(ce); 4939 signatureVerificationException = ce; 4940 } 4941 } 4942 } 4943 4944 if (signatureVerificationException == null) 4945 { 4946 wrapOut(0, WRAP_COLUMN, 4947 INFO_MANAGE_CERTS_LIST_CERTS_SIGNATURE_VALID.get()); 4948 } 4949 else 4950 { 4951 wrapErr(0, WRAP_COLUMN, 4952 signatureVerificationException.getMessage()); 4953 } 4954 4955 if (displayPEM) 4956 { 4957 out(INFO_MANAGE_CERTS_LIST_CERTS_LABEL_PEM.get()); 4958 writePEMCertificate(getOut(), 4959 certificateChain[i].getX509CertificateBytes()); 4960 } 4961 } 4962 } 4963 4964 if (! missingAliases.isEmpty()) 4965 { 4966 err(); 4967 for (final String missingAlias : missingAliases.values()) 4968 { 4969 wrapErr(0, WRAP_COLUMN, 4970 WARN_MANAGE_CERTS_LIST_CERTS_ALIAS_NOT_IN_KS.get(missingAlias, 4971 keystorePath.getAbsolutePath())); 4972 resultCode = ResultCode.PARAM_ERROR; 4973 } 4974 } 4975 else if (listedCount == 0) 4976 { 4977 out(); 4978 if (keystorePassword == null) 4979 { 4980 wrapOut(0, WRAP_COLUMN, 4981 INFO_MANAGE_CERTS_LIST_CERTS_NO_CERTS_OR_KEYS_WITHOUT_PW.get()); 4982 } 4983 else 4984 { 4985 wrapOut(0, WRAP_COLUMN, 4986 INFO_MANAGE_CERTS_LIST_CERTS_NO_CERTS_OR_KEYS_WITH_PW.get()); 4987 } 4988 } 4989 4990 return resultCode; 4991 } 4992 4993 4994 4995 /** 4996 * Performs the necessary processing for the export-certificate subcommand. 4997 * 4998 * @return A result code that indicates whether the processing completed 4999 * successfully. 5000 */ 5001 @NotNull() 5002 private ResultCode doExportCertificate() 5003 { 5004 // Get the values of a number of configured arguments. 5005 final StringArgument aliasArgument = 5006 subCommandParser.getStringArgument("alias"); 5007 final String alias = aliasArgument.getValue(); 5008 5009 final BooleanArgument exportChainArgument = 5010 subCommandParser.getBooleanArgument("export-certificate-chain"); 5011 final boolean exportChain = 5012 ((exportChainArgument != null) && exportChainArgument.isPresent()); 5013 5014 final BooleanArgument separateFilePerCertificateArgument = 5015 subCommandParser.getBooleanArgument("separate-file-per-certificate"); 5016 final boolean separateFilePerCertificate = 5017 ((separateFilePerCertificateArgument != null) && 5018 separateFilePerCertificateArgument.isPresent()); 5019 5020 boolean exportPEM = true; 5021 final StringArgument outputFormatArgument = 5022 subCommandParser.getStringArgument("output-format"); 5023 if ((outputFormatArgument != null) && outputFormatArgument.isPresent()) 5024 { 5025 final String format = outputFormatArgument.getValue().toLowerCase(); 5026 if (format.equals("der") || format.equals("binary") || 5027 format.equals("bin")) 5028 { 5029 exportPEM = false; 5030 } 5031 } 5032 5033 File outputFile = null; 5034 final FileArgument outputFileArgument = 5035 subCommandParser.getFileArgument("output-file"); 5036 if ((outputFileArgument != null) && outputFileArgument.isPresent()) 5037 { 5038 outputFile = outputFileArgument.getValue(); 5039 } 5040 5041 if ((outputFile == null) && (! exportPEM)) 5042 { 5043 wrapErr(0, WRAP_COLUMN, 5044 ERR_MANAGE_CERTS_EXPORT_CERT_NO_FILE_WITH_DER.get()); 5045 return ResultCode.PARAM_ERROR; 5046 } 5047 5048 final String keystoreType; 5049 final File keystorePath = getKeystorePath(); 5050 try 5051 { 5052 keystoreType = inferKeystoreType(keystorePath); 5053 } 5054 catch (final LDAPException le) 5055 { 5056 Debug.debugException(le); 5057 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5058 return le.getResultCode(); 5059 } 5060 5061 final char[] keystorePassword; 5062 try 5063 { 5064 keystorePassword = getKeystorePassword(keystorePath); 5065 } 5066 catch (final LDAPException le) 5067 { 5068 Debug.debugException(le); 5069 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5070 return le.getResultCode(); 5071 } 5072 5073 final BooleanArgument displayKeytoolCommandArgument = 5074 subCommandParser.getBooleanArgument("display-keytool-command"); 5075 if ((displayKeytoolCommandArgument != null) && 5076 displayKeytoolCommandArgument.isPresent()) 5077 { 5078 final ArrayList<String> keytoolArgs = new ArrayList<>(10); 5079 keytoolArgs.add("-list"); 5080 5081 keytoolArgs.add("-keystore"); 5082 keytoolArgs.add(keystorePath.getAbsolutePath()); 5083 keytoolArgs.add("-storetype"); 5084 keytoolArgs.add(keystoreType); 5085 5086 if (keystorePassword != null) 5087 { 5088 keytoolArgs.add("-storepass"); 5089 keytoolArgs.add("*****REDACTED*****"); 5090 } 5091 5092 keytoolArgs.add("-alias"); 5093 keytoolArgs.add(alias); 5094 5095 if (exportPEM) 5096 { 5097 keytoolArgs.add("-rfc"); 5098 } 5099 5100 if (outputFile != null) 5101 { 5102 keytoolArgs.add("-file"); 5103 keytoolArgs.add(outputFile.getAbsolutePath()); 5104 } 5105 5106 displayKeytoolCommand(keytoolArgs); 5107 } 5108 5109 5110 // Get the keystore. 5111 final KeyStore keystore; 5112 try 5113 { 5114 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 5115 } 5116 catch (final LDAPException le) 5117 { 5118 Debug.debugException(le); 5119 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5120 return le.getResultCode(); 5121 } 5122 5123 5124 // Get the certificates to export. If the --export-certificate-chain 5125 // argument was provided, this can be multiple certificates. Otherwise, it 5126 // there will only be one. 5127 DN missingIssuerDN = null; 5128 final X509Certificate[] certificatesToExport; 5129 if (exportChain) 5130 { 5131 try 5132 { 5133 final AtomicReference<DN> missingIssuerRef = new AtomicReference<>(); 5134 certificatesToExport = 5135 getCertificateChain(alias, keystore, missingIssuerRef); 5136 missingIssuerDN = missingIssuerRef.get(); 5137 } 5138 catch (final LDAPException le) 5139 { 5140 Debug.debugException(le); 5141 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5142 return le.getResultCode(); 5143 } 5144 } 5145 else 5146 { 5147 try 5148 { 5149 final Certificate cert = keystore.getCertificate(alias); 5150 if (cert == null) 5151 { 5152 certificatesToExport = new X509Certificate[0]; 5153 } 5154 else 5155 { 5156 certificatesToExport = new X509Certificate[] 5157 { 5158 new X509Certificate(cert.getEncoded()) 5159 }; 5160 } 5161 } 5162 catch (final Exception e) 5163 { 5164 Debug.debugException(e); 5165 wrapErr(0, WRAP_COLUMN, 5166 ERR_MANAGE_CERTS_EXPORT_CERT_ERROR_GETTING_CERT.get(alias, 5167 keystorePath.getAbsolutePath())); 5168 e.printStackTrace(getErr()); 5169 return ResultCode.LOCAL_ERROR; 5170 } 5171 } 5172 5173 if (certificatesToExport.length == 0) 5174 { 5175 wrapErr(0, WRAP_COLUMN, 5176 ERR_MANAGE_CERTS_EXPORT_CERT_NO_CERT_WITH_ALIAS.get(alias, 5177 keystorePath.getAbsolutePath())); 5178 return ResultCode.PARAM_ERROR; 5179 } 5180 5181 5182 // Get a PrintStream to use for the output. 5183 int fileCounter = 1; 5184 String filename = null; 5185 PrintStream printStream; 5186 if (outputFile == null) 5187 { 5188 printStream = getOut(); 5189 } 5190 else 5191 { 5192 try 5193 { 5194 if ((certificatesToExport.length > 1) && separateFilePerCertificate) 5195 { 5196 filename = outputFile.getAbsolutePath() + '.' + fileCounter; 5197 } 5198 else 5199 { 5200 filename = outputFile.getAbsolutePath(); 5201 } 5202 printStream = new PrintStream(filename); 5203 } 5204 catch (final Exception e) 5205 { 5206 Debug.debugException(e); 5207 wrapErr(0, WRAP_COLUMN, 5208 ERR_MANAGE_CERTS_EXPORT_CERT_ERROR_OPENING_OUTPUT.get( 5209 outputFile.getAbsolutePath())); 5210 e.printStackTrace(getErr()); 5211 return ResultCode.LOCAL_ERROR; 5212 } 5213 } 5214 5215 try 5216 { 5217 for (final X509Certificate certificate : certificatesToExport) 5218 { 5219 try 5220 { 5221 if (separateFilePerCertificate && (certificatesToExport.length > 1)) 5222 { 5223 if (fileCounter > 1) 5224 { 5225 printStream.close(); 5226 filename = outputFile.getAbsolutePath() + '.' + fileCounter; 5227 printStream = new PrintStream(filename); 5228 } 5229 5230 fileCounter++; 5231 } 5232 5233 if (exportPEM) 5234 { 5235 writePEMCertificate(printStream, 5236 certificate.getX509CertificateBytes()); 5237 } 5238 else 5239 { 5240 printStream.write(certificate.getX509CertificateBytes()); 5241 } 5242 } 5243 catch (final Exception e) 5244 { 5245 Debug.debugException(e); 5246 wrapErr(0, WRAP_COLUMN, 5247 ERR_MANAGE_CERTS_EXPORT_CERT_ERROR_WRITING_CERT.get(alias, 5248 certificate.getSubjectDN())); 5249 e.printStackTrace(getErr()); 5250 return ResultCode.LOCAL_ERROR; 5251 } 5252 5253 if (outputFile != null) 5254 { 5255 out(); 5256 wrapOut(0, WRAP_COLUMN, 5257 INFO_MANAGE_CERTS_EXPORT_CERT_EXPORT_SUCCESSFUL.get(filename)); 5258 printCertificate(certificate, "", false); 5259 } 5260 } 5261 } 5262 finally 5263 { 5264 printStream.flush(); 5265 if (outputFile != null) 5266 { 5267 printStream.close(); 5268 } 5269 } 5270 5271 if (missingIssuerDN != null) 5272 { 5273 err(); 5274 wrapErr(0, WRAP_COLUMN, 5275 WARN_MANAGE_CERTS_EXPORT_CERT_MISSING_CERT_IN_CHAIN.get( 5276 missingIssuerDN, keystorePath.getAbsolutePath())); 5277 return ResultCode.NO_SUCH_OBJECT; 5278 } 5279 5280 return ResultCode.SUCCESS; 5281 } 5282 5283 5284 5285 /** 5286 * Performs the necessary processing for the export-private-key subcommand. 5287 * 5288 * @return A result code that indicates whether the processing completed 5289 * successfully. 5290 */ 5291 @NotNull() 5292 private ResultCode doExportPrivateKey() 5293 { 5294 // Get the values of a number of configured arguments. 5295 final StringArgument aliasArgument = 5296 subCommandParser.getStringArgument("alias"); 5297 final String alias = aliasArgument.getValue(); 5298 5299 boolean exportPEM = true; 5300 final StringArgument outputFormatArgument = 5301 subCommandParser.getStringArgument("output-format"); 5302 if ((outputFormatArgument != null) && outputFormatArgument.isPresent()) 5303 { 5304 final String format = outputFormatArgument.getValue().toLowerCase(); 5305 if (format.equals("der") || format.equals("binary") || 5306 format.equals("bin")) 5307 { 5308 exportPEM = false; 5309 } 5310 } 5311 5312 File outputFile = null; 5313 final FileArgument outputFileArgument = 5314 subCommandParser.getFileArgument("output-file"); 5315 if ((outputFileArgument != null) && outputFileArgument.isPresent()) 5316 { 5317 outputFile = outputFileArgument.getValue(); 5318 } 5319 5320 if ((outputFile == null) && (! exportPEM)) 5321 { 5322 wrapErr(0, WRAP_COLUMN, 5323 ERR_MANAGE_CERTS_EXPORT_KEY_NO_FILE_WITH_DER.get()); 5324 return ResultCode.PARAM_ERROR; 5325 } 5326 5327 final String keystoreType; 5328 final File keystorePath = getKeystorePath(); 5329 try 5330 { 5331 keystoreType = inferKeystoreType(keystorePath); 5332 } 5333 catch (final LDAPException le) 5334 { 5335 Debug.debugException(le); 5336 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5337 return le.getResultCode(); 5338 } 5339 5340 final char[] keystorePassword; 5341 try 5342 { 5343 keystorePassword = getKeystorePassword(keystorePath); 5344 } 5345 catch (final LDAPException le) 5346 { 5347 Debug.debugException(le); 5348 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5349 return le.getResultCode(); 5350 } 5351 5352 5353 // Get the keystore. 5354 final KeyStore keystore; 5355 try 5356 { 5357 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 5358 } 5359 catch (final LDAPException le) 5360 { 5361 Debug.debugException(le); 5362 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5363 return le.getResultCode(); 5364 } 5365 5366 5367 // See if we need to use a private key password that is different from the 5368 // keystore password. 5369 final char[] privateKeyPassword; 5370 try 5371 { 5372 privateKeyPassword = 5373 getPrivateKeyPassword(keystore, alias, keystorePassword); 5374 } 5375 catch (final LDAPException le) 5376 { 5377 Debug.debugException(le); 5378 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5379 return le.getResultCode(); 5380 } 5381 5382 5383 // Get the private key to export. 5384 final PrivateKey privateKey; 5385 try 5386 { 5387 final Key key = keystore.getKey(alias, privateKeyPassword); 5388 if (key == null) 5389 { 5390 wrapErr(0, WRAP_COLUMN, 5391 ERR_MANAGE_CERTS_EXPORT_KEY_NO_KEY_WITH_ALIAS.get(alias, 5392 keystorePath.getAbsolutePath())); 5393 return ResultCode.PARAM_ERROR; 5394 } 5395 5396 privateKey = (PrivateKey) key; 5397 } 5398 catch (final UnrecoverableKeyException e) 5399 { 5400 Debug.debugException(e); 5401 wrapErr(0, WRAP_COLUMN, 5402 ERR_MANAGE_CERTS_EXPORT_KEY_WRONG_KEY_PW.get(alias, 5403 keystorePath.getAbsolutePath())); 5404 return ResultCode.PARAM_ERROR; 5405 } 5406 catch (final Exception e) 5407 { 5408 Debug.debugException(e); 5409 wrapErr(0, WRAP_COLUMN, 5410 ERR_MANAGE_CERTS_EXPORT_KEY_ERROR_GETTING_KEY.get(alias, 5411 keystorePath.getAbsolutePath())); 5412 e.printStackTrace(getErr()); 5413 return ResultCode.LOCAL_ERROR; 5414 } 5415 5416 5417 // Get a PrintStream to use for the output. 5418 final PrintStream printStream; 5419 if (outputFile == null) 5420 { 5421 printStream = getOut(); 5422 } 5423 else 5424 { 5425 try 5426 { 5427 printStream = new PrintStream(outputFile); 5428 } 5429 catch (final Exception e) 5430 { 5431 Debug.debugException(e); 5432 wrapErr(0, WRAP_COLUMN, 5433 ERR_MANAGE_CERTS_EXPORT_KEY_ERROR_OPENING_OUTPUT.get( 5434 outputFile.getAbsolutePath())); 5435 e.printStackTrace(getErr()); 5436 return ResultCode.LOCAL_ERROR; 5437 } 5438 } 5439 5440 try 5441 { 5442 try 5443 { 5444 if (exportPEM) 5445 { 5446 writePEMPrivateKey(printStream, privateKey.getEncoded()); 5447 } 5448 else 5449 { 5450 printStream.write(privateKey.getEncoded()); 5451 } 5452 } 5453 catch (final Exception e) 5454 { 5455 Debug.debugException(e); 5456 wrapErr(0, WRAP_COLUMN, 5457 ERR_MANAGE_CERTS_EXPORT_KEY_ERROR_WRITING_KEY.get(alias)); 5458 e.printStackTrace(getErr()); 5459 return ResultCode.LOCAL_ERROR; 5460 } 5461 5462 if (outputFile != null) 5463 { 5464 out(); 5465 wrapOut(0, WRAP_COLUMN, 5466 INFO_MANAGE_CERTS_EXPORT_KEY_EXPORT_SUCCESSFUL.get()); 5467 } 5468 } 5469 finally 5470 { 5471 printStream.flush(); 5472 if (outputFile != null) 5473 { 5474 printStream.close(); 5475 } 5476 } 5477 5478 return ResultCode.SUCCESS; 5479 } 5480 5481 5482 5483 /** 5484 * Performs the necessary processing for the import-certificate subcommand. 5485 * 5486 * @return A result code that indicates whether the processing completed 5487 * successfully. 5488 */ 5489 @NotNull() 5490 private ResultCode doImportCertificate() 5491 { 5492 // Get the values of a number of configured arguments. 5493 final StringArgument aliasArgument = 5494 subCommandParser.getStringArgument("alias"); 5495 final String alias = aliasArgument.getValue(); 5496 5497 final FileArgument certificateFileArgument = 5498 subCommandParser.getFileArgument("certificate-file"); 5499 final List<File> certFiles = certificateFileArgument.getValues(); 5500 5501 final File privateKeyFile; 5502 final FileArgument privateKeyFileArgument = 5503 subCommandParser.getFileArgument("private-key-file"); 5504 if ((privateKeyFileArgument != null) && privateKeyFileArgument.isPresent()) 5505 { 5506 privateKeyFile = privateKeyFileArgument.getValue(); 5507 } 5508 else 5509 { 5510 privateKeyFile = null; 5511 } 5512 5513 final BooleanArgument noPromptArgument = 5514 subCommandParser.getBooleanArgument("no-prompt"); 5515 final boolean noPrompt = 5516 ((noPromptArgument != null) && noPromptArgument.isPresent()); 5517 5518 final String keystoreType; 5519 final File keystorePath = getKeystorePath(); 5520 final boolean isNewKeystore = (! keystorePath.exists()); 5521 try 5522 { 5523 keystoreType = inferKeystoreType(keystorePath); 5524 } 5525 catch (final LDAPException le) 5526 { 5527 Debug.debugException(le); 5528 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5529 return le.getResultCode(); 5530 } 5531 5532 5533 final char[] keystorePassword; 5534 try 5535 { 5536 keystorePassword = getKeystorePassword(keystorePath); 5537 } 5538 catch (final LDAPException le) 5539 { 5540 Debug.debugException(le); 5541 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5542 return le.getResultCode(); 5543 } 5544 5545 5546 // Read the contents of the certificate files. 5547 final ArrayList<X509Certificate> certList = new ArrayList<>(5); 5548 for (final File certFile : certFiles) 5549 { 5550 try 5551 { 5552 final List<X509Certificate> certs = readCertificatesFromFile(certFile); 5553 if (certs.isEmpty()) 5554 { 5555 wrapErr(0, WRAP_COLUMN, 5556 ERR_MANAGE_CERTS_IMPORT_CERT_NO_CERTS_IN_FILE.get( 5557 certFile.getAbsolutePath())); 5558 return ResultCode.PARAM_ERROR; 5559 } 5560 5561 certList.addAll(certs); 5562 } 5563 catch (final LDAPException le) 5564 { 5565 Debug.debugException(le); 5566 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5567 return le.getResultCode(); 5568 } 5569 } 5570 5571 5572 // If a private key file was specified, then read the private key. 5573 final PKCS8PrivateKey privateKey; 5574 if (privateKeyFile == null) 5575 { 5576 privateKey = null; 5577 } 5578 else 5579 { 5580 try 5581 { 5582 privateKey = readPrivateKeyFromFile(privateKeyFile); 5583 } 5584 catch (final LDAPException le) 5585 { 5586 Debug.debugException(le); 5587 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5588 return le.getResultCode(); 5589 } 5590 } 5591 5592 5593 // Get the keystore. 5594 final KeyStore keystore; 5595 try 5596 { 5597 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 5598 } 5599 catch (final LDAPException le) 5600 { 5601 Debug.debugException(le); 5602 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5603 return le.getResultCode(); 5604 } 5605 5606 5607 // If there is a private key, then see if we need to use a private key 5608 // password that is different from the keystore password. 5609 final char[] privateKeyPassword; 5610 try 5611 { 5612 privateKeyPassword = 5613 getPrivateKeyPassword(keystore, alias, keystorePassword); 5614 } 5615 catch (final LDAPException le) 5616 { 5617 Debug.debugException(le); 5618 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5619 return le.getResultCode(); 5620 } 5621 5622 5623 // If we should display an equivalent keytool command, then do that now. 5624 final BooleanArgument displayKeytoolCommandArgument = 5625 subCommandParser.getBooleanArgument("display-keytool-command"); 5626 if ((displayKeytoolCommandArgument != null) && 5627 displayKeytoolCommandArgument.isPresent()) 5628 { 5629 final ArrayList<String> keytoolArgs = new ArrayList<>(10); 5630 keytoolArgs.add("-import"); 5631 5632 keytoolArgs.add("-keystore"); 5633 keytoolArgs.add(keystorePath.getAbsolutePath()); 5634 keytoolArgs.add("-storetype"); 5635 keytoolArgs.add(keystoreType); 5636 keytoolArgs.add("-storepass"); 5637 keytoolArgs.add("*****REDACTED*****"); 5638 keytoolArgs.add("-keypass"); 5639 keytoolArgs.add("*****REDACTED*****"); 5640 keytoolArgs.add("-alias"); 5641 keytoolArgs.add(alias); 5642 keytoolArgs.add("-file"); 5643 keytoolArgs.add(certFiles.get(0).getAbsolutePath()); 5644 keytoolArgs.add("-trustcacerts"); 5645 5646 displayKeytoolCommand(keytoolArgs); 5647 } 5648 5649 5650 // Look at all the certificates to be imported. Make sure that every 5651 // subsequent certificate in the chain is the issuer for the previous. 5652 final Iterator<X509Certificate> certIterator = certList.iterator(); 5653 X509Certificate subjectCert = certIterator.next(); 5654 while (true) 5655 { 5656 if (subjectCert.isSelfSigned()) 5657 { 5658 if (certIterator.hasNext()) 5659 { 5660 wrapErr(0, WRAP_COLUMN, 5661 ERR_MANAGE_CERTS_IMPORT_CERT_SELF_SIGNED_NOT_LAST.get( 5662 subjectCert.getSubjectDN())); 5663 return ResultCode.PARAM_ERROR; 5664 } 5665 } 5666 5667 if (! certIterator.hasNext()) 5668 { 5669 break; 5670 } 5671 5672 final X509Certificate issuerCert = certIterator.next(); 5673 final StringBuilder notIssuerReason = new StringBuilder(); 5674 if (! issuerCert.isIssuerFor(subjectCert, notIssuerReason)) 5675 { 5676 // In some cases, the process of signing a certificate can put two 5677 // certificates in the output file (both the signed certificate and its 5678 // issuer. If the same certificate is in the chain twice, then we'll 5679 // silently ignore it. 5680 if (Arrays.equals(issuerCert.getX509CertificateBytes(), 5681 subjectCert.getX509CertificateBytes())) 5682 { 5683 certIterator.remove(); 5684 } 5685 else 5686 { 5687 wrapErr(0, WRAP_COLUMN, 5688 ERR_MANAGE_CERTS_IMPORT_CERT_NEXT_NOT_ISSUER_OF_PREV.get( 5689 notIssuerReason.toString())); 5690 return ResultCode.PARAM_ERROR; 5691 } 5692 } 5693 5694 subjectCert = issuerCert; 5695 } 5696 5697 5698 // If the last certificate in the chain is not self-signed, then make sure 5699 // that we can complete the chain using other certificates in the keystore 5700 // or in the JVM's set of default trusted issuers. If we can't complete 5701 // the chain, then that's an error, although we'll go ahead and proceed 5702 // anyway with the import if we're not also importing a private key. 5703 final ArrayList<X509Certificate> chain; 5704 if (certList.get(certList.size() - 1).isSelfSigned()) 5705 { 5706 chain = certList; 5707 } 5708 else 5709 { 5710 chain = new ArrayList<>(certList.size() + 5); 5711 chain.addAll(certList); 5712 5713 final AtomicReference<KeyStore> jvmDefaultTrustStoreRef = 5714 new AtomicReference<>(); 5715 final AtomicReference<DN> missingIssuerRef = new AtomicReference<>(); 5716 5717 X509Certificate c = certList.get(certList.size() - 1); 5718 while (! c.isSelfSigned()) 5719 { 5720 final X509Certificate issuer; 5721 try 5722 { 5723 issuer = getIssuerCertificate(c, keystore, jvmDefaultTrustStoreRef, 5724 missingIssuerRef); 5725 } 5726 catch (final Exception e) 5727 { 5728 Debug.debugException(e); 5729 wrapErr(0, WRAP_COLUMN, 5730 ERR_MANAGE_CERTS_IMPORT_CERT_CANNOT_GET_ISSUER.get( 5731 c.getIssuerDN())); 5732 e.printStackTrace(getErr()); 5733 return ResultCode.LOCAL_ERROR; 5734 } 5735 5736 if (issuer == null) 5737 { 5738 final byte[] authorityKeyIdentifier = getAuthorityKeyIdentifier(c); 5739 5740 // We couldn't find the issuer certificate. If we're importing a 5741 // private key, or if the keystore already has a key entry with the 5742 // same alias that we're going to use, then this is definitely an 5743 // error because we can only write a key entry if we have a complete 5744 // certificate chain. 5745 // 5746 // If we weren't explicitly provided with a private key, then it's 5747 // still an undesirable thing to import a certificate without having 5748 // the complete set of issuers, but we'll go ahead and let it slide 5749 // with just a warning. 5750 if ((privateKey != null) || hasKeyAlias(keystore, alias)) 5751 { 5752 if (authorityKeyIdentifier == null) 5753 { 5754 err(); 5755 wrapErr(0, WRAP_COLUMN, 5756 ERR_MANAGE_CERTS_IMPORT_CERT_NO_ISSUER_NO_AKI.get( 5757 c.getIssuerDN())); 5758 } 5759 else 5760 { 5761 err(); 5762 wrapErr(0, WRAP_COLUMN, 5763 ERR_MANAGE_CERTS_IMPORT_CERT_NO_ISSUER_WITH_AKI.get( 5764 c.getIssuerDN(), 5765 toColonDelimitedHex(authorityKeyIdentifier))); 5766 } 5767 5768 return ResultCode.PARAM_ERROR; 5769 } 5770 else 5771 { 5772 if (authorityKeyIdentifier == null) 5773 { 5774 err(); 5775 wrapErr(0, WRAP_COLUMN, 5776 WARN_MANAGE_CERTS_IMPORT_CERT_NO_ISSUER_NO_AKI.get( 5777 c.getIssuerDN())); 5778 } 5779 else 5780 { 5781 err(); 5782 wrapErr(0, WRAP_COLUMN, 5783 WARN_MANAGE_CERTS_IMPORT_CERT_NO_ISSUER_WITH_AKI.get( 5784 c.getIssuerDN(), 5785 toColonDelimitedHex(authorityKeyIdentifier))); 5786 } 5787 5788 break; 5789 } 5790 } 5791 else 5792 { 5793 chain.add(issuer); 5794 c = issuer; 5795 } 5796 } 5797 } 5798 5799 5800 // If we're going to import a private key with a certificate chain, then 5801 // perform the necessary validation and do the import. 5802 if (privateKey != null) 5803 { 5804 // Make sure that the keystore doesn't already have a key or certificate 5805 // with the specified alias. 5806 if (hasKeyAlias(keystore, alias)) 5807 { 5808 wrapErr(0, WRAP_COLUMN, 5809 ERR_MANAGE_CERTS_IMPORT_CERT_WITH_PK_KEY_ALIAS_CONFLICT.get( 5810 alias)); 5811 return ResultCode.PARAM_ERROR; 5812 } 5813 else if (hasCertificateAlias(keystore, alias)) 5814 { 5815 wrapErr(0, WRAP_COLUMN, 5816 ERR_MANAGE_CERTS_IMPORT_CERT_WITH_PK_CERT_ALIAS_CONFLICT.get( 5817 alias)); 5818 return ResultCode.PARAM_ERROR; 5819 } 5820 5821 5822 // Make sure that the private key has a key algorithm of either RSA or EC, 5823 // and convert it into a Java PrivateKey object. 5824 final PrivateKey javaPrivateKey; 5825 try 5826 { 5827 javaPrivateKey = privateKey.toPrivateKey(); 5828 } 5829 catch (final Exception e) 5830 { 5831 Debug.debugException(e); 5832 wrapErr(0, WRAP_COLUMN, 5833 ERR_MANAGE_CERTS_IMPORT_CERT_ERROR_CONVERTING_KEY.get( 5834 privateKeyFile.getAbsolutePath())); 5835 e.printStackTrace(getErr()); 5836 return ResultCode.LOCAL_ERROR; 5837 } 5838 5839 5840 // Convert the certificate chain into a Java Certificate[]. 5841 final Certificate[] javaCertificateChain = new Certificate[chain.size()]; 5842 for (int i=0; i < javaCertificateChain.length; i++) 5843 { 5844 final X509Certificate c = chain.get(i); 5845 try 5846 { 5847 javaCertificateChain[i] = c.toCertificate(); 5848 } 5849 catch (final Exception e) 5850 { 5851 Debug.debugException(e); 5852 wrapErr(0, WRAP_COLUMN, 5853 ERR_MANAGE_CERTS_IMPORT_CERT_ERROR_CONVERTING_CERT.get( 5854 c.getSubjectDN())); 5855 e.printStackTrace(getErr()); 5856 return ResultCode.LOCAL_ERROR; 5857 } 5858 } 5859 5860 5861 // Prompt the user to confirm the import, if appropriate. 5862 if (! noPrompt) 5863 { 5864 out(); 5865 wrapOut(0, WRAP_COLUMN, 5866 INFO_MANAGE_CERTS_IMPORT_CERT_CONFIRM_IMPORT_CHAIN_NEW_KEY.get( 5867 alias)); 5868 5869 for (final X509Certificate c : chain) 5870 { 5871 out(); 5872 printCertificate(c, "", false); 5873 } 5874 5875 out(); 5876 5877 try 5878 { 5879 if (! promptForYesNo( 5880 INFO_MANAGE_CERTS_IMPORT_CERT_PROMPT_IMPORT_CHAIN.get())) 5881 { 5882 wrapErr(0, WRAP_COLUMN, 5883 ERR_MANAGE_CERTS_IMPORT_CERT_CANCELED.get()); 5884 return ResultCode.USER_CANCELED; 5885 } 5886 } 5887 catch (final LDAPException le) 5888 { 5889 Debug.debugException(le); 5890 err(); 5891 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5892 return le.getResultCode(); 5893 } 5894 } 5895 5896 5897 // Set the private key entry in the keystore. 5898 try 5899 { 5900 keystore.setKeyEntry(alias, javaPrivateKey, privateKeyPassword, 5901 javaCertificateChain); 5902 } 5903 catch (final Exception e) 5904 { 5905 Debug.debugException(e); 5906 wrapErr(0, WRAP_COLUMN, 5907 ERR_MANAGE_CERTS_IMPORT_CERT_ERROR_UPDATING_KS_WITH_CHAIN.get( 5908 alias)); 5909 e.printStackTrace(getErr()); 5910 return ResultCode.LOCAL_ERROR; 5911 } 5912 5913 5914 // Write the updated keystore to disk. 5915 try 5916 { 5917 writeKeystore(keystore, keystorePath, keystorePassword); 5918 } 5919 catch (final LDAPException le) 5920 { 5921 Debug.debugException(le); 5922 wrapErr(0, WRAP_COLUMN, le.getMessage()); 5923 return le.getResultCode(); 5924 } 5925 5926 if (isNewKeystore) 5927 { 5928 out(); 5929 wrapOut(0, WRAP_COLUMN, 5930 INFO_MANAGE_CERTS_IMPORT_CERT_CREATED_KEYSTORE.get( 5931 getUserFriendlyKeystoreType(keystoreType))); 5932 } 5933 5934 out(); 5935 wrapOut(0, WRAP_COLUMN, 5936 INFO_MANAGE_CERTS_IMPORT_CERT_IMPORTED_CHAIN_WITH_PK.get()); 5937 return ResultCode.SUCCESS; 5938 } 5939 5940 5941 // If we've gotten here, then we were given one or more certificates but no 5942 // private key. See if the keystore already has a certificate entry with 5943 // the specified alias. If so, then that's always an error. 5944 if (hasCertificateAlias(keystore, alias)) 5945 { 5946 wrapErr(0, WRAP_COLUMN, 5947 ERR_MANAGE_CERTS_IMPORT_CERT_WITH_CONFLICTING_CERT_ALIAS.get(alias)); 5948 return ResultCode.PARAM_ERROR; 5949 } 5950 5951 5952 // See if the keystore already has a key entry with the specified alias. 5953 // If so, then it may or may not be an error. This can happen if we 5954 // generated a certificate signing request from an existing key pair, and 5955 // now want to import the signed certificate. If that is the case, then we 5956 // will replace the existing key entry with a new one that contains the full 5957 // new certificate chain and the existing private key, but only if the 5958 // new certificate uses the same public key as the certificate at the head 5959 // of the existing chain in that alias. 5960 if (hasKeyAlias(keystore, alias)) 5961 { 5962 // Make sure that the existing key pair uses the same public key as the 5963 // new certificate we are importing. 5964 final PrivateKey existingPrivateKey; 5965 final Certificate[] existingChain; 5966 final X509Certificate existingEndCertificate; 5967 try 5968 { 5969 existingPrivateKey = 5970 (PrivateKey) keystore.getKey(alias, privateKeyPassword); 5971 existingChain = keystore.getCertificateChain(alias); 5972 existingEndCertificate = 5973 new X509Certificate(existingChain[0].getEncoded()); 5974 } 5975 catch (final Exception e) 5976 { 5977 Debug.debugException(e); 5978 wrapErr(0, WRAP_COLUMN, 5979 ERR_MANAGE_CERTS_IMPORT_CERT_INTO_KEY_ALIAS_CANNOT_GET_KEY.get( 5980 alias)); 5981 e.printStackTrace(getErr()); 5982 return ResultCode.LOCAL_ERROR; 5983 } 5984 5985 final boolean[] existingPublicKeyBits = 5986 existingEndCertificate.getEncodedPublicKey().getBits(); 5987 final boolean[] newPublicKeyBits = 5988 chain.get(0).getEncodedPublicKey().getBits(); 5989 if (! Arrays.equals(existingPublicKeyBits, newPublicKeyBits)) 5990 { 5991 wrapErr(0, WRAP_COLUMN, 5992 ERR_MANAGE_CERTS_IMPORT_CERT_INTO_KEY_ALIAS_KEY_MISMATCH.get( 5993 alias)); 5994 return ResultCode.PARAM_ERROR; 5995 } 5996 5997 5998 // Prepare the new certificate chain to store in the alias. 5999 final Certificate[] newChain = new Certificate[chain.size()]; 6000 for (int i=0; i < chain.size(); i++) 6001 { 6002 final X509Certificate c = chain.get(i); 6003 try 6004 { 6005 newChain[i] = c.toCertificate(); 6006 } 6007 catch (final Exception e) 6008 { 6009 Debug.debugException(e); 6010 wrapErr(0, WRAP_COLUMN, 6011 ERR_MANAGE_CERTS_IMPORT_CERT_ERROR_CONVERTING_CERT.get( 6012 c.getSubjectDN())); 6013 e.printStackTrace(getErr()); 6014 return ResultCode.LOCAL_ERROR; 6015 } 6016 } 6017 6018 6019 // Prompt the user to confirm the import, if appropriate. 6020 if (! noPrompt) 6021 { 6022 out(); 6023 wrapOut(0, WRAP_COLUMN, 6024 INFO_MANAGE_CERTS_IMPORT_CERT_CONFIRM_IMPORT_CHAIN_EXISTING_KEY. 6025 get(alias)); 6026 6027 for (final X509Certificate c : chain) 6028 { 6029 out(); 6030 printCertificate(c, "", false); 6031 } 6032 6033 out(); 6034 6035 try 6036 { 6037 if (! promptForYesNo( 6038 INFO_MANAGE_CERTS_IMPORT_CERT_PROMPT_IMPORT_CHAIN.get())) 6039 { 6040 wrapErr(0, WRAP_COLUMN, 6041 ERR_MANAGE_CERTS_IMPORT_CERT_CANCELED.get()); 6042 return ResultCode.USER_CANCELED; 6043 } 6044 } 6045 catch (final LDAPException le) 6046 { 6047 Debug.debugException(le); 6048 err(); 6049 wrapErr(0, WRAP_COLUMN, le.getMessage()); 6050 return le.getResultCode(); 6051 } 6052 } 6053 6054 6055 // Set the private key entry in the keystore. 6056 try 6057 { 6058 keystore.setKeyEntry(alias, existingPrivateKey, privateKeyPassword, 6059 newChain); 6060 } 6061 catch (final Exception e) 6062 { 6063 Debug.debugException(e); 6064 wrapErr(0, WRAP_COLUMN, 6065 ERR_MANAGE_CERTS_IMPORT_CERT_ERROR_UPDATING_KS_WITH_CHAIN.get( 6066 alias)); 6067 e.printStackTrace(getErr()); 6068 return ResultCode.LOCAL_ERROR; 6069 } 6070 6071 6072 // Write the updated keystore to disk. 6073 try 6074 { 6075 writeKeystore(keystore, keystorePath, keystorePassword); 6076 } 6077 catch (final LDAPException le) 6078 { 6079 Debug.debugException(le); 6080 wrapErr(0, WRAP_COLUMN, le.getMessage()); 6081 return le.getResultCode(); 6082 } 6083 6084 out(); 6085 6086 if (isNewKeystore) 6087 { 6088 wrapOut(0, WRAP_COLUMN, 6089 INFO_MANAGE_CERTS_IMPORT_CERT_CREATED_KEYSTORE.get( 6090 getUserFriendlyKeystoreType(keystoreType))); 6091 } 6092 6093 wrapOut(0, WRAP_COLUMN, 6094 INFO_MANAGE_CERTS_IMPORT_CERT_IMPORTED_CHAIN_WITHOUT_PK.get()); 6095 return ResultCode.SUCCESS; 6096 } 6097 6098 6099 // If we've gotten here, then we know that we're just going to add 6100 // certificate entries to the keystore. Iterate through the certificates 6101 // and add them to the keystore under the appropriate aliases, first making 6102 // sure that the alias isn't already in use. 6103 final LinkedHashMap<String,X509Certificate> certMap = 6104 new LinkedHashMap<>(StaticUtils.computeMapCapacity(certList.size())); 6105 for (int i=0; i < certList.size(); i++) 6106 { 6107 final X509Certificate x509Certificate = certList.get(i); 6108 final Certificate javaCertificate; 6109 try 6110 { 6111 javaCertificate = x509Certificate.toCertificate(); 6112 } 6113 catch (final Exception e) 6114 { 6115 Debug.debugException(e); 6116 wrapErr(0, WRAP_COLUMN, 6117 ERR_MANAGE_CERTS_IMPORT_CERT_ERROR_CONVERTING_CERT.get( 6118 x509Certificate.getSubjectDN())); 6119 e.printStackTrace(getErr()); 6120 return ResultCode.LOCAL_ERROR; 6121 } 6122 6123 final String certAlias; 6124 if (i == 0) 6125 { 6126 certAlias = alias; 6127 } 6128 else if (certList.size() > 2) 6129 { 6130 certAlias = alias + "-issuer-" + i; 6131 } 6132 else 6133 { 6134 certAlias = alias + "-issuer"; 6135 } 6136 6137 certMap.put(certAlias, x509Certificate); 6138 6139 if (hasKeyAlias(keystore, certAlias) || 6140 hasCertificateAlias(keystore, certAlias)) 6141 { 6142 wrapErr(0, WRAP_COLUMN, 6143 ERR_MANAGE_CERTS_IMPORT_CERT_WITH_CONFLICTING_ISSUER_ALIAS.get( 6144 x509Certificate.getSubjectDN(), certAlias)); 6145 return ResultCode.PARAM_ERROR; 6146 } 6147 6148 try 6149 { 6150 keystore.setCertificateEntry(certAlias, javaCertificate); 6151 } 6152 catch (final Exception e) 6153 { 6154 Debug.debugException(e); 6155 wrapErr(0, WRAP_COLUMN, 6156 ERR_MANAGE_CERTS_IMPORT_CERT_ERROR_UPDATING_KS_WITH_CERT.get( 6157 x509Certificate.getSubjectDN(), alias)); 6158 e.printStackTrace(getErr()); 6159 return ResultCode.LOCAL_ERROR; 6160 } 6161 } 6162 6163 6164 // Prompt about whether to perform the import, if appropriate. 6165 if (! noPrompt) 6166 { 6167 out(); 6168 wrapOut(0, WRAP_COLUMN, 6169 INFO_MANAGE_CERTS_IMPORT_CERT_CONFIRM_IMPORT_CHAIN_NO_KEY. 6170 get(alias)); 6171 6172 for (final Map.Entry<String,X509Certificate> e : certMap.entrySet()) 6173 { 6174 out(); 6175 wrapOut(0, WRAP_COLUMN, 6176 INFO_MANAGE_CERTS_IMPORT_CERT_LABEL_ALIAS.get(e.getKey())); 6177 printCertificate(e.getValue(), "", false); 6178 } 6179 6180 out(); 6181 6182 try 6183 { 6184 if (! promptForYesNo( 6185 INFO_MANAGE_CERTS_IMPORT_CERT_PROMPT_IMPORT_CHAIN.get())) 6186 { 6187 wrapErr(0, WRAP_COLUMN, 6188 ERR_MANAGE_CERTS_IMPORT_CERT_CANCELED.get()); 6189 return ResultCode.USER_CANCELED; 6190 } 6191 } 6192 catch (final LDAPException le) 6193 { 6194 Debug.debugException(le); 6195 err(); 6196 wrapErr(0, WRAP_COLUMN, le.getMessage()); 6197 return le.getResultCode(); 6198 } 6199 } 6200 6201 6202 // Write the updated keystore to disk. 6203 try 6204 { 6205 writeKeystore(keystore, keystorePath, keystorePassword); 6206 } 6207 catch (final LDAPException le) 6208 { 6209 Debug.debugException(le); 6210 wrapErr(0, WRAP_COLUMN, le.getMessage()); 6211 return le.getResultCode(); 6212 } 6213 6214 out(); 6215 6216 if (isNewKeystore) 6217 { 6218 wrapOut(0, WRAP_COLUMN, 6219 INFO_MANAGE_CERTS_IMPORT_CERT_CREATED_KEYSTORE.get( 6220 getUserFriendlyKeystoreType(keystoreType))); 6221 } 6222 6223 wrapOut(0, WRAP_COLUMN, 6224 INFO_MANAGE_CERTS_IMPORT_CERT_IMPORTED_CHAIN_WITHOUT_PK.get()); 6225 return ResultCode.SUCCESS; 6226 } 6227 6228 6229 6230 /** 6231 * Performs the necessary processing for the delete-certificate subcommand. 6232 * 6233 * @return A result code that indicates whether the processing completed 6234 * successfully. 6235 */ 6236 @NotNull() 6237 private ResultCode doDeleteCertificate() 6238 { 6239 // Get the values of a number of configured arguments. 6240 final StringArgument aliasArgument = 6241 subCommandParser.getStringArgument("alias"); 6242 final String alias = aliasArgument.getValue(); 6243 6244 final BooleanArgument noPromptArgument = 6245 subCommandParser.getBooleanArgument("no-prompt"); 6246 final boolean noPrompt = 6247 ((noPromptArgument != null) && noPromptArgument.isPresent()); 6248 6249 final String keystoreType; 6250 final File keystorePath = getKeystorePath(); 6251 try 6252 { 6253 keystoreType = inferKeystoreType(keystorePath); 6254 } 6255 catch (final LDAPException le) 6256 { 6257 Debug.debugException(le); 6258 wrapErr(0, WRAP_COLUMN, le.getMessage()); 6259 return le.getResultCode(); 6260 } 6261 6262 final char[] keystorePassword; 6263 try 6264 { 6265 keystorePassword = getKeystorePassword(keystorePath); 6266 } 6267 catch (final LDAPException le) 6268 { 6269 Debug.debugException(le); 6270 wrapErr(0, WRAP_COLUMN, le.getMessage()); 6271 return le.getResultCode(); 6272 } 6273 6274 final BooleanArgument displayKeytoolCommandArgument = 6275 subCommandParser.getBooleanArgument("display-keytool-command"); 6276 if ((displayKeytoolCommandArgument != null) && 6277 displayKeytoolCommandArgument.isPresent()) 6278 { 6279 final ArrayList<String> keytoolArgs = new ArrayList<>(10); 6280 keytoolArgs.add("-delete"); 6281 6282 keytoolArgs.add("-keystore"); 6283 keytoolArgs.add(keystorePath.getAbsolutePath()); 6284 keytoolArgs.add("-storetype"); 6285 keytoolArgs.add(keystoreType); 6286 keytoolArgs.add("-storepass"); 6287 keytoolArgs.add("*****REDACTED*****"); 6288 keytoolArgs.add("-alias"); 6289 keytoolArgs.add(alias); 6290 6291 displayKeytoolCommand(keytoolArgs); 6292 } 6293 6294 6295 // Get the keystore. 6296 final KeyStore keystore; 6297 try 6298 { 6299 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 6300 } 6301 catch (final LDAPException le) 6302 { 6303 Debug.debugException(le); 6304 wrapErr(0, WRAP_COLUMN, le.getMessage()); 6305 return le.getResultCode(); 6306 } 6307 6308 6309 // Get the entry for the specified alias. 6310 final boolean hasPrivateKey; 6311 final ArrayList<X509Certificate> certList = new ArrayList<>(5); 6312 if (hasCertificateAlias(keystore, alias)) 6313 { 6314 try 6315 { 6316 hasPrivateKey = false; 6317 certList.add( 6318 new X509Certificate(keystore.getCertificate(alias).getEncoded())); 6319 } 6320 catch (final Exception e) 6321 { 6322 Debug.debugException(e); 6323 wrapErr(0, WRAP_COLUMN, 6324 ERR_MANAGE_CERTS_DELETE_CERT_ERROR_GETTING_CERT.get(alias)); 6325 e.printStackTrace(getErr()); 6326 return ResultCode.LOCAL_ERROR; 6327 } 6328 } 6329 else if (hasKeyAlias(keystore, alias)) 6330 { 6331 try 6332 { 6333 hasPrivateKey = true; 6334 for (final Certificate c : keystore.getCertificateChain(alias)) 6335 { 6336 certList.add(new X509Certificate(c.getEncoded())); 6337 } 6338 } 6339 catch (final Exception e) 6340 { 6341 Debug.debugException(e); 6342 wrapErr(0, WRAP_COLUMN, 6343 ERR_MANAGE_CERTS_DELETE_CERT_ERROR_GETTING_CHAIN.get(alias)); 6344 e.printStackTrace(getErr()); 6345 return ResultCode.LOCAL_ERROR; 6346 } 6347 } 6348 else 6349 { 6350 wrapErr(0, WRAP_COLUMN, 6351 ERR_MANAGE_CERTS_DELETE_CERT_ERROR_ALIAS_NOT_CERT_OR_KEY.get(alias)); 6352 return ResultCode.PARAM_ERROR; 6353 } 6354 6355 6356 // Prompt about whether to perform the delete, if appropriate. 6357 if (! noPrompt) 6358 { 6359 out(); 6360 if (! hasPrivateKey) 6361 { 6362 wrapOut(0, WRAP_COLUMN, 6363 INFO_MANAGE_CERTS_DELETE_CERT_CONFIRM_DELETE_CERT.get()); 6364 } 6365 else 6366 { 6367 wrapOut(0, WRAP_COLUMN, 6368 INFO_MANAGE_CERTS_DELETE_CERT_CONFIRM_DELETE_CHAIN.get()); 6369 } 6370 6371 for (final X509Certificate c : certList) 6372 { 6373 out(); 6374 printCertificate(c, "", false); 6375 } 6376 6377 out(); 6378 6379 try 6380 { 6381 if (! promptForYesNo( 6382 INFO_MANAGE_CERTS_DELETE_CERT_PROMPT_DELETE.get())) 6383 { 6384 wrapErr(0, WRAP_COLUMN, 6385 ERR_MANAGE_CERTS_DELETE_CERT_CANCELED.get()); 6386 return ResultCode.USER_CANCELED; 6387 } 6388 } 6389 catch (final LDAPException le) 6390 { 6391 Debug.debugException(le); 6392 err(); 6393 wrapErr(0, WRAP_COLUMN, le.getMessage()); 6394 return le.getResultCode(); 6395 } 6396 } 6397 6398 6399 // Delete the entry from the keystore. 6400 try 6401 { 6402 keystore.deleteEntry(alias); 6403 } 6404 catch (final Exception e) 6405 { 6406 Debug.debugException(e); 6407 wrapErr(0, WRAP_COLUMN, 6408 ERR_MANAGE_CERTS_DELETE_CERT_DELETE_ERROR.get(alias)); 6409 e.printStackTrace(getErr()); 6410 return ResultCode.LOCAL_ERROR; 6411 } 6412 6413 6414 // Write the updated keystore to disk. 6415 try 6416 { 6417 writeKeystore(keystore, keystorePath, keystorePassword); 6418 } 6419 catch (final LDAPException le) 6420 { 6421 Debug.debugException(le); 6422 wrapErr(0, WRAP_COLUMN, le.getMessage()); 6423 return le.getResultCode(); 6424 } 6425 6426 if (certList.size() == 1) 6427 { 6428 out(); 6429 wrapOut(0, WRAP_COLUMN, 6430 INFO_MANAGE_CERTS_DELETE_CERT_DELETED_CERT.get()); 6431 } 6432 else 6433 { 6434 out(); 6435 wrapOut(0, WRAP_COLUMN, 6436 INFO_MANAGE_CERTS_DELETE_CERT_DELETED_CHAIN.get()); 6437 } 6438 6439 return ResultCode.SUCCESS; 6440 } 6441 6442 6443 6444 /** 6445 * Performs the necessary processing for the generate-self-signed-certificate, 6446 * generate-certificate-signing-request, and sign-certificate-signing-request 6447 * subcommands. 6448 * 6449 * @return A result code that indicates whether the processing completed 6450 * successfully. 6451 */ 6452 @NotNull() 6453 private ResultCode doGenerateOrSignCertificateOrCSR() 6454 { 6455 // Figure out which subcommand we're processing. 6456 final boolean isGenerateCertificate; 6457 final boolean isGenerateCSR; 6458 final boolean isSignCSR; 6459 final SubCommand selectedSubCommand = globalParser.getSelectedSubCommand(); 6460 if (selectedSubCommand.hasName("generate-self-signed-certificate")) 6461 { 6462 isGenerateCertificate = true; 6463 isGenerateCSR = false; 6464 isSignCSR = false; 6465 } 6466 else if (selectedSubCommand.hasName("generate-certificate-signing-request")) 6467 { 6468 isGenerateCertificate = false; 6469 isGenerateCSR = true; 6470 isSignCSR = false; 6471 } 6472 else 6473 { 6474 Validator.ensureTrue( 6475 selectedSubCommand.hasName("sign-certificate-signing-request")); 6476 isGenerateCertificate = false; 6477 isGenerateCSR = false; 6478 isSignCSR = true; 6479 } 6480 6481 6482 // Get the values of a number of configured arguments. 6483 final StringArgument aliasArgument = 6484 subCommandParser.getStringArgument("alias"); 6485 final String alias = aliasArgument.getValue(); 6486 6487 final File keystorePath = getKeystorePath(); 6488 final boolean isNewKeystore = (! keystorePath.exists()); 6489 6490 DN subjectDN = null; 6491 final DNArgument subjectDNArgument = 6492 subCommandParser.getDNArgument("subject-dn"); 6493 if ((subjectDNArgument != null) && subjectDNArgument.isPresent()) 6494 { 6495 subjectDN = subjectDNArgument.getValue(); 6496 } 6497 6498 File inputFile = null; 6499 final FileArgument inputFileArgument = 6500 subCommandParser.getFileArgument("input-file"); 6501 if ((inputFileArgument != null) && inputFileArgument.isPresent()) 6502 { 6503 inputFile = inputFileArgument.getValue(); 6504 } 6505 6506 File outputFile = null; 6507 final FileArgument outputFileArgument = 6508 subCommandParser.getFileArgument("output-file"); 6509 if ((outputFileArgument != null) && outputFileArgument.isPresent()) 6510 { 6511 outputFile = outputFileArgument.getValue(); 6512 } 6513 6514 boolean outputPEM = true; 6515 final StringArgument outputFormatArgument = 6516 subCommandParser.getStringArgument("output-format"); 6517 if ((outputFormatArgument != null) && outputFormatArgument.isPresent()) 6518 { 6519 final String format = outputFormatArgument.getValue().toLowerCase(); 6520 if (format.equals("der") || format.equals("binary") || 6521 format.equals("bin")) 6522 { 6523 outputPEM = false; 6524 } 6525 } 6526 6527 if ((! outputPEM) && (outputFile == null)) 6528 { 6529 wrapErr(0, WRAP_COLUMN, 6530 ERR_MANAGE_CERTS_GEN_CERT_NO_FILE_WITH_DER.get()); 6531 return ResultCode.PARAM_ERROR; 6532 } 6533 6534 final BooleanArgument replaceExistingCertificateArgument = 6535 subCommandParser.getBooleanArgument("replace-existing-certificate"); 6536 final boolean replaceExistingCertificate = 6537 ((replaceExistingCertificateArgument != null) && 6538 replaceExistingCertificateArgument.isPresent()); 6539 if (replaceExistingCertificate && (! keystorePath.exists())) 6540 { 6541 wrapErr(0, WRAP_COLUMN, 6542 ERR_MANAGE_CERTS_GEN_CERT_REPLACE_WITHOUT_KS.get()); 6543 return ResultCode.PARAM_ERROR; 6544 } 6545 6546 final BooleanArgument inheritExtensionsArgument = 6547 subCommandParser.getBooleanArgument("inherit-extensions"); 6548 final boolean inheritExtensions = 6549 ((inheritExtensionsArgument != null) && 6550 inheritExtensionsArgument.isPresent()); 6551 6552 final BooleanArgument includeRequestedExtensionsArgument = 6553 subCommandParser.getBooleanArgument("include-requested-extensions"); 6554 final boolean includeRequestedExtensions = 6555 ((includeRequestedExtensionsArgument != null) && 6556 includeRequestedExtensionsArgument.isPresent()); 6557 6558 final BooleanArgument noPromptArgument = 6559 subCommandParser.getBooleanArgument("no-prompt"); 6560 final boolean noPrompt = 6561 ((noPromptArgument != null) && noPromptArgument.isPresent()); 6562 6563 final BooleanArgument displayKeytoolCommandArgument = 6564 subCommandParser.getBooleanArgument("display-keytool-command"); 6565 final boolean displayKeytoolCommand = 6566 ((displayKeytoolCommandArgument != null) && 6567 displayKeytoolCommandArgument.isPresent()); 6568 6569 int daysValid = 365; 6570 final IntegerArgument daysValidArgument = 6571 subCommandParser.getIntegerArgument("days-valid"); 6572 if ((daysValidArgument != null) && daysValidArgument.isPresent()) 6573 { 6574 daysValid = daysValidArgument.getValue(); 6575 } 6576 6577 Date validityStartTime = null; 6578 final TimestampArgument validityStartTimeArgument = 6579 subCommandParser.getTimestampArgument("validity-start-time"); 6580 if ((validityStartTimeArgument != null) && 6581 validityStartTimeArgument.isPresent()) 6582 { 6583 validityStartTime = validityStartTimeArgument.getValue(); 6584 } 6585 6586 PublicKeyAlgorithmIdentifier keyAlgorithmIdentifier = null; 6587 String keyAlgorithmName = null; 6588 final StringArgument keyAlgorithmArgument = 6589 subCommandParser.getStringArgument("key-algorithm"); 6590 if ((keyAlgorithmArgument != null) && keyAlgorithmArgument.isPresent()) 6591 { 6592 final String name = keyAlgorithmArgument.getValue(); 6593 keyAlgorithmIdentifier = PublicKeyAlgorithmIdentifier.forName(name); 6594 if (keyAlgorithmIdentifier == null) 6595 { 6596 wrapErr(0, WRAP_COLUMN, 6597 ERR_MANAGE_CERTS_GEN_CERT_UNKNOWN_KEY_ALG.get(name)); 6598 return ResultCode.PARAM_ERROR; 6599 } 6600 else 6601 { 6602 keyAlgorithmName = keyAlgorithmIdentifier.getName(); 6603 } 6604 } 6605 6606 Integer keySizeBits = null; 6607 final IntegerArgument keySizeBitsArgument = 6608 subCommandParser.getIntegerArgument("key-size-bits"); 6609 if ((keySizeBitsArgument != null) && keySizeBitsArgument.isPresent()) 6610 { 6611 keySizeBits = keySizeBitsArgument.getValue(); 6612 } 6613 6614 if ((keyAlgorithmIdentifier != null) && 6615 (keyAlgorithmIdentifier != PublicKeyAlgorithmIdentifier.RSA) && 6616 (keySizeBits == null)) 6617 { 6618 wrapErr(0, WRAP_COLUMN, 6619 ERR_MANAGE_CERTS_GEN_CERT_NO_KEY_SIZE_FOR_NON_RSA_KEY.get()); 6620 return ResultCode.PARAM_ERROR; 6621 } 6622 6623 String signatureAlgorithmName = null; 6624 SignatureAlgorithmIdentifier signatureAlgorithmIdentifier = null; 6625 final StringArgument signatureAlgorithmArgument = 6626 subCommandParser.getStringArgument("signature-algorithm"); 6627 if ((signatureAlgorithmArgument != null) && 6628 signatureAlgorithmArgument.isPresent()) 6629 { 6630 final String name = signatureAlgorithmArgument.getValue(); 6631 signatureAlgorithmIdentifier = SignatureAlgorithmIdentifier.forName(name); 6632 if (signatureAlgorithmIdentifier == null) 6633 { 6634 wrapErr(0, WRAP_COLUMN, 6635 ERR_MANAGE_CERTS_GEN_CERT_UNKNOWN_SIG_ALG.get(name)); 6636 return ResultCode.PARAM_ERROR; 6637 } 6638 else 6639 { 6640 signatureAlgorithmName = signatureAlgorithmIdentifier.getJavaName(); 6641 } 6642 } 6643 6644 if ((keyAlgorithmIdentifier != null) && 6645 (keyAlgorithmIdentifier != PublicKeyAlgorithmIdentifier.RSA) && 6646 (signatureAlgorithmIdentifier == null)) 6647 { 6648 wrapErr(0, WRAP_COLUMN, 6649 ERR_MANAGE_CERTS_GEN_CERT_NO_SIG_ALG_FOR_NON_RSA_KEY.get()); 6650 return ResultCode.PARAM_ERROR; 6651 } 6652 6653 6654 // Build a subject alternative name extension, if appropriate. 6655 final ArrayList<X509CertificateExtension> extensionList = 6656 new ArrayList<>(10); 6657 final GeneralNamesBuilder sanBuilder = new GeneralNamesBuilder(); 6658 final LinkedHashSet<String> sanValues = 6659 new LinkedHashSet<>(StaticUtils.computeMapCapacity(10)); 6660 final StringArgument sanDNSArgument = 6661 subCommandParser.getStringArgument("subject-alternative-name-dns"); 6662 if ((sanDNSArgument != null) && sanDNSArgument.isPresent()) 6663 { 6664 for (final String value : sanDNSArgument.getValues()) 6665 { 6666 sanBuilder.addDNSName(value); 6667 sanValues.add("DNS:" + value); 6668 } 6669 } 6670 6671 final StringArgument sanIPArgument = subCommandParser.getStringArgument( 6672 "subject-alternative-name-ip-address"); 6673 if ((sanIPArgument != null) && sanIPArgument.isPresent()) 6674 { 6675 for (final String value : sanIPArgument.getValues()) 6676 { 6677 try 6678 { 6679 sanBuilder.addIPAddress(LDAPConnectionOptions.DEFAULT_NAME_RESOLVER. 6680 getByName(value)); 6681 sanValues.add("IP:" + value); 6682 } 6683 catch (final Exception e) 6684 { 6685 // This should never happen. 6686 Debug.debugException(e); 6687 throw new RuntimeException(e); 6688 } 6689 } 6690 } 6691 6692 final StringArgument sanEmailArgument = subCommandParser.getStringArgument( 6693 "subject-alternative-name-email-address"); 6694 if ((sanEmailArgument != null) && sanEmailArgument.isPresent()) 6695 { 6696 for (final String value : sanEmailArgument.getValues()) 6697 { 6698 sanBuilder.addRFC822Name(value); 6699 sanValues.add("EMAIL:" + value); 6700 } 6701 } 6702 6703 final StringArgument sanURIArgument = 6704 subCommandParser.getStringArgument("subject-alternative-name-uri"); 6705 if ((sanURIArgument != null) && sanURIArgument.isPresent()) 6706 { 6707 for (final String value : sanURIArgument.getValues()) 6708 { 6709 sanBuilder.addUniformResourceIdentifier(value); 6710 sanValues.add("URI:" + value); 6711 } 6712 } 6713 6714 final StringArgument sanOIDArgument = 6715 subCommandParser.getStringArgument("subject-alternative-name-oid"); 6716 if ((sanOIDArgument != null) && sanOIDArgument.isPresent()) 6717 { 6718 for (final String value : sanOIDArgument.getValues()) 6719 { 6720 sanBuilder.addRegisteredID(new OID(value)); 6721 sanValues.add("OID:" + value); 6722 } 6723 } 6724 6725 if (! sanValues.isEmpty()) 6726 { 6727 try 6728 { 6729 extensionList.add( 6730 new SubjectAlternativeNameExtension(false, sanBuilder.build())); 6731 } 6732 catch (final Exception e) 6733 { 6734 // This should never happen. 6735 Debug.debugException(e); 6736 throw new RuntimeException(e); 6737 } 6738 } 6739 6740 // Build a set of issuer alternative name extension values. 6741 final GeneralNamesBuilder ianBuilder = new GeneralNamesBuilder(); 6742 final LinkedHashSet<String> ianValues = 6743 new LinkedHashSet<>(StaticUtils.computeMapCapacity(10)); 6744 final StringArgument ianDNSArgument = 6745 subCommandParser.getStringArgument("issuer-alternative-name-dns"); 6746 if ((ianDNSArgument != null) && ianDNSArgument.isPresent()) 6747 { 6748 for (final String value : ianDNSArgument.getValues()) 6749 { 6750 ianBuilder.addDNSName(value); 6751 ianValues.add("DNS:" + value); 6752 } 6753 } 6754 6755 final StringArgument ianIPArgument = subCommandParser.getStringArgument( 6756 "issuer-alternative-name-ip-address"); 6757 if ((ianIPArgument != null) && ianIPArgument.isPresent()) 6758 { 6759 for (final String value : ianIPArgument.getValues()) 6760 { 6761 try 6762 { 6763 ianBuilder.addIPAddress(LDAPConnectionOptions.DEFAULT_NAME_RESOLVER. 6764 getByName(value)); 6765 ianValues.add("IP:" + value); 6766 } 6767 catch (final Exception e) 6768 { 6769 // This should never happen. 6770 Debug.debugException(e); 6771 throw new RuntimeException(e); 6772 } 6773 } 6774 } 6775 6776 final StringArgument ianEmailArgument = subCommandParser.getStringArgument( 6777 "issuer-alternative-name-email-address"); 6778 if ((ianEmailArgument != null) && ianEmailArgument.isPresent()) 6779 { 6780 for (final String value : ianEmailArgument.getValues()) 6781 { 6782 ianBuilder.addRFC822Name(value); 6783 ianValues.add("EMAIL:" + value); 6784 } 6785 } 6786 6787 final StringArgument ianURIArgument = 6788 subCommandParser.getStringArgument("issuer-alternative-name-uri"); 6789 if ((ianURIArgument != null) && ianURIArgument.isPresent()) 6790 { 6791 for (final String value : ianURIArgument.getValues()) 6792 { 6793 ianBuilder.addUniformResourceIdentifier(value); 6794 ianValues.add("URI:" + value); 6795 } 6796 } 6797 6798 final StringArgument ianOIDArgument = 6799 subCommandParser.getStringArgument("issuer-alternative-name-oid"); 6800 if ((ianOIDArgument != null) && ianOIDArgument.isPresent()) 6801 { 6802 for (final String value : ianOIDArgument.getValues()) 6803 { 6804 ianBuilder.addRegisteredID(new OID(value)); 6805 ianValues.add("OID:" + value); 6806 } 6807 } 6808 6809 if (! ianValues.isEmpty()) 6810 { 6811 try 6812 { 6813 extensionList.add( 6814 new IssuerAlternativeNameExtension(false, ianBuilder.build())); 6815 } 6816 catch (final Exception e) 6817 { 6818 // This should never happen. 6819 Debug.debugException(e); 6820 throw new RuntimeException(e); 6821 } 6822 } 6823 6824 6825 // Build a basic constraints extension, if appropriate. 6826 BasicConstraintsExtension basicConstraints = null; 6827 final BooleanValueArgument basicConstraintsIsCAArgument = 6828 subCommandParser.getBooleanValueArgument("basic-constraints-is-ca"); 6829 if ((basicConstraintsIsCAArgument != null) && 6830 basicConstraintsIsCAArgument.isPresent()) 6831 { 6832 final boolean isCA = basicConstraintsIsCAArgument.getValue(); 6833 6834 Integer pathLength = null; 6835 final IntegerArgument pathLengthArgument = 6836 subCommandParser.getIntegerArgument( 6837 "basic-constraints-maximum-path-length"); 6838 if ((pathLengthArgument != null) && pathLengthArgument.isPresent()) 6839 { 6840 if (isCA) 6841 { 6842 pathLength = pathLengthArgument.getValue(); 6843 } 6844 else 6845 { 6846 wrapErr(0, WRAP_COLUMN, 6847 ERR_MANAGE_CERTS_GEN_CERT_BC_PATH_LENGTH_WITHOUT_CA.get()); 6848 return ResultCode.PARAM_ERROR; 6849 } 6850 } 6851 6852 basicConstraints = new BasicConstraintsExtension(false, isCA, pathLength); 6853 extensionList.add(basicConstraints); 6854 } 6855 6856 6857 // Build a key usage extension, if appropriate. 6858 KeyUsageExtension keyUsage = null; 6859 final StringArgument keyUsageArgument = 6860 subCommandParser.getStringArgument("key-usage"); 6861 if ((keyUsageArgument != null) && keyUsageArgument.isPresent()) 6862 { 6863 boolean digitalSignature = false; 6864 boolean nonRepudiation = false; 6865 boolean keyEncipherment = false; 6866 boolean dataEncipherment = false; 6867 boolean keyAgreement = false; 6868 boolean keyCertSign = false; 6869 boolean crlSign = false; 6870 boolean encipherOnly = false; 6871 boolean decipherOnly = false; 6872 6873 for (final String value : keyUsageArgument.getValues()) 6874 { 6875 if (value.equalsIgnoreCase("digital-signature") || 6876 value.equalsIgnoreCase("digitalSignature")) 6877 { 6878 digitalSignature = true; 6879 } 6880 else if (value.equalsIgnoreCase("non-repudiation") || 6881 value.equalsIgnoreCase("nonRepudiation") || 6882 value.equalsIgnoreCase("content-commitment") || 6883 value.equalsIgnoreCase("contentCommitment")) 6884 { 6885 nonRepudiation = true; 6886 } 6887 else if (value.equalsIgnoreCase("key-encipherment") || 6888 value.equalsIgnoreCase("keyEncipherment")) 6889 { 6890 keyEncipherment = true; 6891 } 6892 else if (value.equalsIgnoreCase("data-encipherment") || 6893 value.equalsIgnoreCase("dataEncipherment")) 6894 { 6895 dataEncipherment = true; 6896 } 6897 else if (value.equalsIgnoreCase("key-agreement") || 6898 value.equalsIgnoreCase("keyAgreement")) 6899 { 6900 keyAgreement = true; 6901 } 6902 else if (value.equalsIgnoreCase("key-cert-sign") || 6903 value.equalsIgnoreCase("keyCertSign")) 6904 { 6905 keyCertSign = true; 6906 } 6907 else if (value.equalsIgnoreCase("crl-sign") || 6908 value.equalsIgnoreCase("crlSign")) 6909 { 6910 crlSign = true; 6911 } 6912 else if (value.equalsIgnoreCase("encipher-only") || 6913 value.equalsIgnoreCase("encipherOnly")) 6914 { 6915 encipherOnly = true; 6916 } 6917 else if (value.equalsIgnoreCase("decipher-only") || 6918 value.equalsIgnoreCase("decipherOnly")) 6919 { 6920 decipherOnly = true; 6921 } 6922 else 6923 { 6924 wrapErr(0, WRAP_COLUMN, 6925 ERR_MANAGE_CERTS_GEN_CERT_INVALID_KEY_USAGE.get(value)); 6926 return ResultCode.PARAM_ERROR; 6927 } 6928 } 6929 6930 keyUsage = new KeyUsageExtension(false, digitalSignature, nonRepudiation, 6931 keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, 6932 crlSign, encipherOnly, decipherOnly); 6933 extensionList.add(keyUsage); 6934 } 6935 6936 6937 // Build an extended key usage extension, if appropriate. 6938 ExtendedKeyUsageExtension extendedKeyUsage = null; 6939 final StringArgument extendedKeyUsageArgument = 6940 subCommandParser.getStringArgument("extended-key-usage"); 6941 if ((extendedKeyUsageArgument != null) && 6942 extendedKeyUsageArgument.isPresent()) 6943 { 6944 final List<String> values = extendedKeyUsageArgument.getValues(); 6945 final ArrayList<OID> keyPurposeIDs = new ArrayList<>(values.size()); 6946 for (final String value : values) 6947 { 6948 if (value.equalsIgnoreCase("server-auth") || 6949 value.equalsIgnoreCase("serverAuth") || 6950 value.equalsIgnoreCase("server-authentication") || 6951 value.equalsIgnoreCase("serverAuthentication") || 6952 value.equalsIgnoreCase("tls-server-authentication") || 6953 value.equalsIgnoreCase("tlsServerAuthentication")) 6954 { 6955 keyPurposeIDs.add( 6956 ExtendedKeyUsageID.TLS_SERVER_AUTHENTICATION.getOID()); 6957 } 6958 else if (value.equalsIgnoreCase("client-auth") || 6959 value.equalsIgnoreCase("clientAuth") || 6960 value.equalsIgnoreCase("client-authentication") || 6961 value.equalsIgnoreCase("clientAuthentication") || 6962 value.equalsIgnoreCase("tls-client-authentication") || 6963 value.equalsIgnoreCase("tlsClientAuthentication")) 6964 { 6965 keyPurposeIDs.add( 6966 ExtendedKeyUsageID.TLS_CLIENT_AUTHENTICATION.getOID()); 6967 } 6968 else if (value.equalsIgnoreCase("code-signing") || 6969 value.equalsIgnoreCase("codeSigning")) 6970 { 6971 keyPurposeIDs.add(ExtendedKeyUsageID.CODE_SIGNING.getOID()); 6972 } 6973 else if (value.equalsIgnoreCase("email-protection") || 6974 value.equalsIgnoreCase("emailProtection")) 6975 { 6976 keyPurposeIDs.add(ExtendedKeyUsageID.EMAIL_PROTECTION.getOID()); 6977 } 6978 else if (value.equalsIgnoreCase("time-stamping") || 6979 value.equalsIgnoreCase("timeStamping")) 6980 { 6981 keyPurposeIDs.add(ExtendedKeyUsageID.TIME_STAMPING.getOID()); 6982 } 6983 else if (value.equalsIgnoreCase("ocsp-signing") || 6984 value.equalsIgnoreCase("ocspSigning")) 6985 { 6986 keyPurposeIDs.add(ExtendedKeyUsageID.OCSP_SIGNING.getOID()); 6987 } 6988 else if (OID.isStrictlyValidNumericOID(value)) 6989 { 6990 keyPurposeIDs.add(new OID(value)); 6991 } 6992 else 6993 { 6994 wrapErr(0, WRAP_COLUMN, 6995 ERR_MANAGE_CERTS_GEN_CERT_INVALID_EXTENDED_KEY_USAGE.get(value)); 6996 return ResultCode.PARAM_ERROR; 6997 } 6998 } 6999 7000 try 7001 { 7002 extendedKeyUsage = new ExtendedKeyUsageExtension(false, keyPurposeIDs); 7003 } 7004 catch (final Exception e) 7005 { 7006 // This should never happen. 7007 Debug.debugException(e); 7008 wrapErr(0, WRAP_COLUMN, 7009 ERR_MANAGE_CERTS_GEN_CERT_EXTENDED_KEY_USAGE_ERROR.get()); 7010 e.printStackTrace(getErr()); 7011 return ResultCode.PARAM_ERROR; 7012 } 7013 7014 extensionList.add(extendedKeyUsage); 7015 } 7016 7017 7018 // Build a list of generic extensions. 7019 final ArrayList<X509CertificateExtension> genericExtensions = 7020 new ArrayList<>(5); 7021 final StringArgument extensionArgument = 7022 subCommandParser.getStringArgument("extension"); 7023 if ((extensionArgument != null) && extensionArgument.isPresent()) 7024 { 7025 for (final String value : extensionArgument.getValues()) 7026 { 7027 try 7028 { 7029 final int firstColonPos = value.indexOf(':'); 7030 final int secondColonPos = value.indexOf(':', firstColonPos + 1); 7031 final OID oid = new OID(value.substring(0, firstColonPos)); 7032 if (! oid.isStrictlyValidNumericOID()) 7033 { 7034 wrapErr(0, WRAP_COLUMN, 7035 ERR_MANAGE_CERTS_GEN_CERT_EXT_MALFORMED_OID.get(value, 7036 oid.toString())); 7037 return ResultCode.PARAM_ERROR; 7038 } 7039 7040 final boolean criticality; 7041 final String criticalityString = 7042 value.substring(firstColonPos + 1, secondColonPos); 7043 if (criticalityString.equalsIgnoreCase("true") || 7044 criticalityString.equalsIgnoreCase("t") || 7045 criticalityString.equalsIgnoreCase("yes") || 7046 criticalityString.equalsIgnoreCase("y") || 7047 criticalityString.equalsIgnoreCase("on") || 7048 criticalityString.equalsIgnoreCase("1")) 7049 { 7050 criticality = true; 7051 } 7052 else if (criticalityString.equalsIgnoreCase("false") || 7053 criticalityString.equalsIgnoreCase("f") || 7054 criticalityString.equalsIgnoreCase("no") || 7055 criticalityString.equalsIgnoreCase("n") || 7056 criticalityString.equalsIgnoreCase("off") || 7057 criticalityString.equalsIgnoreCase("0")) 7058 { 7059 criticality = false; 7060 } 7061 else 7062 { 7063 wrapErr(0, WRAP_COLUMN, 7064 ERR_MANAGE_CERTS_GEN_CERT_EXT_INVALID_CRITICALITY.get( 7065 value, criticalityString)); 7066 return ResultCode.PARAM_ERROR; 7067 } 7068 7069 final byte[] valueBytes; 7070 try 7071 { 7072 valueBytes = StaticUtils.fromHex(value.substring(secondColonPos+1)); 7073 } 7074 catch (final Exception e) 7075 { 7076 Debug.debugException(e); 7077 wrapErr(0, WRAP_COLUMN, 7078 ERR_MANAGE_CERTS_GEN_CERT_EXT_INVALID_VALUE.get(value)); 7079 return ResultCode.PARAM_ERROR; 7080 } 7081 7082 final X509CertificateExtension extension = 7083 new X509CertificateExtension(oid, criticality, valueBytes); 7084 genericExtensions.add(extension); 7085 extensionList.add(extension); 7086 } 7087 catch (final Exception e) 7088 { 7089 Debug.debugException(e); 7090 wrapErr(0, WRAP_COLUMN, 7091 ERR_MANAGE_CERTS_GEN_CERT_EXT_MALFORMED.get(value)); 7092 return ResultCode.PARAM_ERROR; 7093 } 7094 } 7095 } 7096 7097 7098 final String keystoreType; 7099 try 7100 { 7101 keystoreType = inferKeystoreType(keystorePath); 7102 } 7103 catch (final LDAPException le) 7104 { 7105 Debug.debugException(le); 7106 wrapErr(0, WRAP_COLUMN, le.getMessage()); 7107 return le.getResultCode(); 7108 } 7109 7110 final char[] keystorePassword; 7111 try 7112 { 7113 keystorePassword = getKeystorePassword(keystorePath); 7114 } 7115 catch (final LDAPException le) 7116 { 7117 Debug.debugException(le); 7118 wrapErr(0, WRAP_COLUMN, le.getMessage()); 7119 return le.getResultCode(); 7120 } 7121 7122 7123 // Get the keystore. 7124 final KeyStore keystore; 7125 try 7126 { 7127 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 7128 } 7129 catch (final LDAPException le) 7130 { 7131 Debug.debugException(le); 7132 wrapErr(0, WRAP_COLUMN, le.getMessage()); 7133 return le.getResultCode(); 7134 } 7135 7136 7137 // If there is a private key, then see if we need to use a private key 7138 // password that is different from the keystore password. 7139 final char[] privateKeyPassword; 7140 try 7141 { 7142 privateKeyPassword = 7143 getPrivateKeyPassword(keystore, alias, keystorePassword); 7144 } 7145 catch (final LDAPException le) 7146 { 7147 Debug.debugException(le); 7148 wrapErr(0, WRAP_COLUMN, le.getMessage()); 7149 return le.getResultCode(); 7150 } 7151 7152 7153 // If we're going to replace an existing certificate in the keystore, then 7154 // perform the appropriate processing for that. 7155 if (replaceExistingCertificate) 7156 { 7157 // Make sure that the keystore already has a private key entry with the 7158 // specified alias. 7159 if (! hasKeyAlias(keystore, alias)) 7160 { 7161 if (hasCertificateAlias(keystore, alias)) 7162 { 7163 wrapErr(0, WRAP_COLUMN, 7164 ERR_MANAGE_CERTS_GEN_CERT_REPLACE_ALIAS_IS_CERT.get(alias, 7165 keystorePath.getAbsolutePath())); 7166 return ResultCode.PARAM_ERROR; 7167 } 7168 else 7169 { 7170 wrapErr(0, WRAP_COLUMN, 7171 ERR_MANAGE_CERTS_GEN_CERT_REPLACE_NO_SUCH_ALIAS.get(alias, 7172 keystorePath.getAbsolutePath())); 7173 return ResultCode.PARAM_ERROR; 7174 } 7175 } 7176 7177 7178 // Get the certificate to replace, along with its key pair. 7179 final X509Certificate certToReplace; 7180 final KeyPair keyPair; 7181 try 7182 { 7183 final Certificate[] chain = keystore.getCertificateChain(alias); 7184 certToReplace = new X509Certificate(chain[0].getEncoded()); 7185 7186 final PublicKey publicKey = chain[0].getPublicKey(); 7187 final PrivateKey privateKey = 7188 (PrivateKey) keystore.getKey(alias, privateKeyPassword); 7189 keyPair = new KeyPair(publicKey, privateKey); 7190 } 7191 catch (final Exception e) 7192 { 7193 Debug.debugException(e); 7194 wrapErr(0, WRAP_COLUMN, 7195 ERR_MANAGE_CERTS_GEN_CERT_REPLACE_COULD_NOT_GET_CERT.get(alias)); 7196 e.printStackTrace(getErr()); 7197 return ResultCode.LOCAL_ERROR; 7198 } 7199 7200 7201 // Assign the remaining values using information in the existing 7202 // certificate. 7203 signatureAlgorithmIdentifier = SignatureAlgorithmIdentifier.forOID( 7204 certToReplace.getSignatureAlgorithmOID()); 7205 if (signatureAlgorithmIdentifier == null) 7206 { 7207 wrapErr(0, WRAP_COLUMN, 7208 ERR_MANAGE_CERTS_GEN_CERT_UNKNOWN_SIG_ALG_IN_CERT.get( 7209 certToReplace.getSignatureAlgorithmOID())); 7210 return ResultCode.PARAM_ERROR; 7211 } 7212 else 7213 { 7214 signatureAlgorithmName = signatureAlgorithmIdentifier.getJavaName(); 7215 } 7216 7217 if (subjectDN == null) 7218 { 7219 subjectDN = certToReplace.getSubjectDN(); 7220 } 7221 7222 if (inheritExtensions) 7223 { 7224 for (final X509CertificateExtension extension : 7225 certToReplace.getExtensions()) 7226 { 7227 if ((extension instanceof AuthorityKeyIdentifierExtension) || 7228 (extension instanceof IssuerAlternativeNameExtension)) 7229 { 7230 // This extension applies to the issuer. We won't include this in 7231 // the set of inherited extensions. 7232 } 7233 else if (extension instanceof SubjectKeyIdentifierExtension) 7234 { 7235 // The generated certificate will automatically include a subject 7236 // key identifier extension, so we don't need to include it. 7237 } 7238 else if (extension instanceof BasicConstraintsExtension) 7239 { 7240 // Don't override a value already provided on the command line. 7241 if (basicConstraints == null) 7242 { 7243 basicConstraints = (BasicConstraintsExtension) extension; 7244 extensionList.add(basicConstraints); 7245 } 7246 } 7247 else if (extension instanceof ExtendedKeyUsageExtension) 7248 { 7249 // Don't override a value already provided on the command line. 7250 if (extendedKeyUsage == null) 7251 { 7252 extendedKeyUsage = (ExtendedKeyUsageExtension) extension; 7253 extensionList.add(extendedKeyUsage); 7254 } 7255 } 7256 else if (extension instanceof KeyUsageExtension) 7257 { 7258 // Don't override a value already provided on the command line. 7259 if (keyUsage == null) 7260 { 7261 keyUsage = (KeyUsageExtension) extension; 7262 extensionList.add(keyUsage); 7263 } 7264 } 7265 else if (extension instanceof SubjectAlternativeNameExtension) 7266 { 7267 // Although we could merge values, it's safer to not do that if any 7268 // subject alternative name values were provided on the command 7269 // line. 7270 if (sanValues.isEmpty()) 7271 { 7272 final SubjectAlternativeNameExtension e = 7273 (SubjectAlternativeNameExtension) extension; 7274 for (final String dnsName : e.getDNSNames()) 7275 { 7276 sanValues.add("DNS:" + dnsName); 7277 } 7278 7279 for (final InetAddress ipAddress : e.getIPAddresses()) 7280 { 7281 sanValues.add("IP:" + ipAddress.getHostAddress()); 7282 } 7283 7284 for (final String emailAddress : e.getRFC822Names()) 7285 { 7286 sanValues.add("EMAIL:" + emailAddress); 7287 } 7288 7289 for (final String uri : e.getUniformResourceIdentifiers()) 7290 { 7291 sanValues.add("URI:" + uri); 7292 } 7293 7294 for (final OID oid : e.getRegisteredIDs()) 7295 { 7296 sanValues.add("OID:" + oid.toString()); 7297 } 7298 7299 extensionList.add(extension); 7300 } 7301 } 7302 else 7303 { 7304 genericExtensions.add(extension); 7305 extensionList.add(extension); 7306 } 7307 } 7308 } 7309 7310 7311 // Create an array with the final set of extensions to include in the 7312 // certificate or certificate signing request. 7313 final X509CertificateExtension[] extensions = 7314 new X509CertificateExtension[extensionList.size()]; 7315 extensionList.toArray(extensions); 7316 7317 7318 // If we're generating a self-signed certificate or a certificate signing 7319 // request, then we should now have everything we need to do that. Build 7320 // a keytool command that we could use to accomplish it. 7321 if (isGenerateCertificate) 7322 { 7323 if (displayKeytoolCommand) 7324 { 7325 final ArrayList<String> keytoolArguments = new ArrayList<>(30); 7326 keytoolArguments.add("-selfcert"); 7327 keytoolArguments.add("-keystore"); 7328 keytoolArguments.add(keystorePath.getAbsolutePath()); 7329 keytoolArguments.add("-storetype"); 7330 keytoolArguments.add(keystoreType); 7331 keytoolArguments.add("-storepass"); 7332 keytoolArguments.add("*****REDACTED*****"); 7333 keytoolArguments.add("-keypass"); 7334 keytoolArguments.add("*****REDACTED*****"); 7335 keytoolArguments.add("-alias"); 7336 keytoolArguments.add(alias); 7337 keytoolArguments.add("-dname"); 7338 keytoolArguments.add(subjectDN.toString()); 7339 keytoolArguments.add("-sigalg"); 7340 keytoolArguments.add(signatureAlgorithmName); 7341 keytoolArguments.add("-validity"); 7342 keytoolArguments.add(String.valueOf(daysValid)); 7343 7344 if (validityStartTime != null) 7345 { 7346 keytoolArguments.add("-startdate"); 7347 keytoolArguments.add(formatValidityStartTime(validityStartTime)); 7348 } 7349 7350 addExtensionArguments(keytoolArguments, basicConstraints, keyUsage, 7351 extendedKeyUsage, sanValues, ianValues, genericExtensions); 7352 7353 displayKeytoolCommand(keytoolArguments); 7354 } 7355 7356 7357 // Generate the self-signed certificate. 7358 final long notBefore; 7359 if (validityStartTime == null) 7360 { 7361 notBefore = System.currentTimeMillis(); 7362 } 7363 else 7364 { 7365 notBefore = validityStartTime.getTime(); 7366 } 7367 7368 final long notAfter = notBefore + TimeUnit.DAYS.toMillis(daysValid); 7369 7370 final X509Certificate certificate; 7371 final Certificate[] chain; 7372 try 7373 { 7374 certificate = X509Certificate.generateSelfSignedCertificate( 7375 signatureAlgorithmIdentifier, keyPair, subjectDN, notBefore, 7376 notAfter, extensions); 7377 chain = new Certificate[] { certificate.toCertificate() }; 7378 } 7379 catch (final Exception e) 7380 { 7381 Debug.debugException(e); 7382 wrapErr(0, WRAP_COLUMN, 7383 ERR_MANAGE_CERTS_GEN_CERT_ERROR_GENERATING_CERT.get()); 7384 e.printStackTrace(getErr()); 7385 return ResultCode.LOCAL_ERROR; 7386 } 7387 7388 7389 // Update the keystore with the new certificate. 7390 try 7391 { 7392 keystore.setKeyEntry(alias, keyPair.getPrivate(), privateKeyPassword, 7393 chain); 7394 writeKeystore(keystore, keystorePath, keystorePassword); 7395 } 7396 catch (final Exception e) 7397 { 7398 Debug.debugException(e); 7399 wrapErr(0, WRAP_COLUMN, 7400 ERR_MANAGE_CERTS_GEN_CERT_ERROR_UPDATING_KEYSTORE.get()); 7401 e.printStackTrace(getErr()); 7402 return ResultCode.LOCAL_ERROR; 7403 } 7404 7405 7406 // Display the certificate we just generated to the end user. 7407 out(); 7408 wrapOut(0, WRAP_COLUMN, 7409 INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_SELF_CERT. 7410 get()); 7411 printCertificate(certificate, "", false); 7412 7413 7414 // If we should write an output file, then do that now. 7415 if (outputFile != null) 7416 { 7417 try (PrintStream ps = new PrintStream(outputFile)) 7418 { 7419 final byte[] certBytes = certificate.getX509CertificateBytes(); 7420 if (outputPEM) 7421 { 7422 writePEMCertificate(ps, certBytes); 7423 } 7424 else 7425 { 7426 ps.write(certBytes); 7427 } 7428 7429 out(); 7430 wrapOut(0, WRAP_COLUMN, 7431 INFO_MANAGE_CERTS_GEN_CERT_WROTE_OUTPUT_FILE.get( 7432 outputFile.getAbsolutePath())); 7433 } 7434 catch (final Exception e) 7435 { 7436 Debug.debugException(e); 7437 err(); 7438 wrapErr(0, WRAP_COLUMN, 7439 ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_CERT.get( 7440 outputFile.getAbsolutePath())); 7441 e.printStackTrace(getErr()); 7442 return ResultCode.LOCAL_ERROR; 7443 } 7444 } 7445 7446 return ResultCode.SUCCESS; 7447 } 7448 else 7449 { 7450 // Build the keytool command used to generate the certificate signing 7451 // request. 7452 Validator.ensureTrue(isGenerateCSR); 7453 if (displayKeytoolCommand) 7454 { 7455 final ArrayList<String> keytoolArguments = new ArrayList<>(30); 7456 keytoolArguments.add("-certreq"); 7457 keytoolArguments.add("-keystore"); 7458 keytoolArguments.add(keystorePath.getAbsolutePath()); 7459 keytoolArguments.add("-storetype"); 7460 keytoolArguments.add(keystoreType); 7461 keytoolArguments.add("-storepass"); 7462 keytoolArguments.add("*****REDACTED*****"); 7463 keytoolArguments.add("-keypass"); 7464 keytoolArguments.add("*****REDACTED*****"); 7465 keytoolArguments.add("-alias"); 7466 keytoolArguments.add(alias); 7467 keytoolArguments.add("-dname"); 7468 keytoolArguments.add(subjectDN.toString()); 7469 keytoolArguments.add("-sigalg"); 7470 keytoolArguments.add(signatureAlgorithmName); 7471 7472 addExtensionArguments(keytoolArguments, basicConstraints, keyUsage, 7473 extendedKeyUsage, sanValues, ianValues, genericExtensions); 7474 7475 if (outputFile != null) 7476 { 7477 keytoolArguments.add("-file"); 7478 keytoolArguments.add(outputFile.getAbsolutePath()); 7479 } 7480 7481 displayKeytoolCommand(keytoolArguments); 7482 } 7483 7484 7485 // Generate the certificate signing request. 7486 final PKCS10CertificateSigningRequest certificateSigningRequest; 7487 try 7488 { 7489 certificateSigningRequest = PKCS10CertificateSigningRequest. 7490 generateCertificateSigningRequest(signatureAlgorithmIdentifier, 7491 keyPair, subjectDN, extensions); 7492 } 7493 catch (final Exception e) 7494 { 7495 Debug.debugException(e); 7496 wrapErr(0, WRAP_COLUMN, 7497 ERR_MANAGE_CERTS_GEN_CERT_ERROR_GENERATING_CSR.get()); 7498 e.printStackTrace(getErr()); 7499 return ResultCode.LOCAL_ERROR; 7500 } 7501 7502 7503 // Write the generated certificate signing request to the appropriate 7504 // location. 7505 try 7506 { 7507 final PrintStream ps; 7508 if (outputFile == null) 7509 { 7510 ps = getOut(); 7511 } 7512 else 7513 { 7514 ps = new PrintStream(outputFile); 7515 } 7516 7517 if (outputPEM) 7518 { 7519 writePEMCertificateSigningRequest(ps, 7520 certificateSigningRequest. 7521 getPKCS10CertificateSigningRequestBytes()); 7522 } 7523 else 7524 { 7525 ps.write(certificateSigningRequest. 7526 getPKCS10CertificateSigningRequestBytes()); 7527 } 7528 7529 if (outputFile != null) 7530 { 7531 ps.close(); 7532 } 7533 } 7534 catch (final Exception e) 7535 { 7536 Debug.debugException(e); 7537 wrapErr(0, WRAP_COLUMN, 7538 ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_CSR.get()); 7539 e.printStackTrace(getErr()); 7540 return ResultCode.LOCAL_ERROR; 7541 } 7542 7543 7544 // If the certificate signing request was written to an output file, 7545 // then let the user know that it was successful. If it was written to 7546 // standard output, then we don't need to tell them because they'll be 7547 // able to see it. 7548 if (outputFile != null) 7549 { 7550 out(); 7551 wrapOut(0, WRAP_COLUMN, 7552 INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_CSR.get( 7553 outputFile.getAbsolutePath())); 7554 } 7555 7556 return ResultCode.SUCCESS; 7557 } 7558 } 7559 7560 7561 // If we've gotten here, then we know we're not replacing an existing 7562 // certificate. Perform any remaining argument assignment and validation. 7563 if ((subjectDN == null) && (! isSignCSR)) 7564 { 7565 wrapErr(0, WRAP_COLUMN, 7566 ERR_MANAGE_CERTS_GEN_CERT_NO_SUBJECT_DN_WITHOUT_REPLACE.get()); 7567 return ResultCode.PARAM_ERROR; 7568 } 7569 7570 if (keyAlgorithmIdentifier == null) 7571 { 7572 keyAlgorithmIdentifier = PublicKeyAlgorithmIdentifier.RSA; 7573 keyAlgorithmName = keyAlgorithmIdentifier.getName(); 7574 } 7575 7576 if (keySizeBits == null) 7577 { 7578 keySizeBits = 2048; 7579 } 7580 7581 if ((signatureAlgorithmIdentifier == null) && (! isSignCSR)) 7582 { 7583 signatureAlgorithmIdentifier = 7584 SignatureAlgorithmIdentifier.SHA_256_WITH_RSA; 7585 signatureAlgorithmName = signatureAlgorithmIdentifier.getJavaName(); 7586 } 7587 7588 7589 // If we're going to generate a self-signed certificate or a certificate 7590 // signing request, then we first need to generate a key pair. Put together 7591 // the appropriate set of keytool arguments and then generate a self-signed 7592 // certificate. 7593 if (isGenerateCertificate || isGenerateCSR) 7594 { 7595 // Make sure that the specified alias is not already in use in the 7596 // keystore. 7597 if (hasKeyAlias(keystore, alias) || hasCertificateAlias(keystore, alias)) 7598 { 7599 wrapErr(0, WRAP_COLUMN, 7600 ERR_MANAGE_CERTS_GEN_CERT_ALIAS_EXISTS_WITHOUT_REPLACE.get(alias)); 7601 return ResultCode.PARAM_ERROR; 7602 } 7603 7604 7605 if (displayKeytoolCommand) 7606 { 7607 final ArrayList<String> keytoolArguments = new ArrayList<>(30); 7608 keytoolArguments.add("-genkeypair"); 7609 keytoolArguments.add("-keystore"); 7610 keytoolArguments.add(keystorePath.getAbsolutePath()); 7611 keytoolArguments.add("-storetype"); 7612 keytoolArguments.add(keystoreType); 7613 keytoolArguments.add("-storepass"); 7614 keytoolArguments.add("*****REDACTED*****"); 7615 keytoolArguments.add("-keypass"); 7616 keytoolArguments.add("*****REDACTED*****"); 7617 keytoolArguments.add("-alias"); 7618 keytoolArguments.add(alias); 7619 keytoolArguments.add("-dname"); 7620 keytoolArguments.add(subjectDN.toString()); 7621 keytoolArguments.add("-keyalg"); 7622 keytoolArguments.add(keyAlgorithmName); 7623 keytoolArguments.add("-keysize"); 7624 keytoolArguments.add(String.valueOf(keySizeBits)); 7625 keytoolArguments.add("-sigalg"); 7626 keytoolArguments.add(signatureAlgorithmName); 7627 keytoolArguments.add("-validity"); 7628 keytoolArguments.add(String.valueOf(daysValid)); 7629 7630 if (validityStartTime != null) 7631 { 7632 keytoolArguments.add("-startdate"); 7633 keytoolArguments.add(formatValidityStartTime(validityStartTime)); 7634 } 7635 7636 addExtensionArguments(keytoolArguments, basicConstraints, 7637 keyUsage, extendedKeyUsage, sanValues, ianValues, 7638 genericExtensions); 7639 7640 displayKeytoolCommand(keytoolArguments); 7641 } 7642 7643 7644 // Generate the self-signed certificate. 7645 final long notBefore; 7646 if (validityStartTime == null) 7647 { 7648 notBefore = System.currentTimeMillis(); 7649 } 7650 else 7651 { 7652 notBefore = validityStartTime.getTime(); 7653 } 7654 7655 final long notAfter = notBefore + TimeUnit.DAYS.toMillis(daysValid); 7656 7657 final X509CertificateExtension[] extensions = 7658 new X509CertificateExtension[extensionList.size()]; 7659 extensionList.toArray(extensions); 7660 7661 final Certificate[] chain; 7662 final KeyPair keyPair; 7663 final X509Certificate certificate; 7664 try 7665 { 7666 final ObjectPair<X509Certificate,KeyPair> p = 7667 X509Certificate.generateSelfSignedCertificate( 7668 signatureAlgorithmIdentifier, keyAlgorithmIdentifier, 7669 keySizeBits, subjectDN, notBefore, notAfter, extensions); 7670 certificate = p.getFirst(); 7671 chain = new Certificate[] { certificate.toCertificate() }; 7672 keyPair = p.getSecond(); 7673 } 7674 catch (final Exception e) 7675 { 7676 Debug.debugException(e); 7677 wrapErr(0, WRAP_COLUMN, 7678 ERR_MANAGE_CERTS_GEN_CERT_ERROR_GENERATING_CERT.get()); 7679 e.printStackTrace(getErr()); 7680 return ResultCode.LOCAL_ERROR; 7681 } 7682 7683 7684 // Update the keystore with the new certificate. 7685 try 7686 { 7687 keystore.setKeyEntry(alias, keyPair.getPrivate(), privateKeyPassword, 7688 chain); 7689 writeKeystore(keystore, keystorePath, keystorePassword); 7690 } 7691 catch (final Exception e) 7692 { 7693 Debug.debugException(e); 7694 wrapErr(0, WRAP_COLUMN, 7695 ERR_MANAGE_CERTS_GEN_CERT_ERROR_UPDATING_KEYSTORE.get()); 7696 e.printStackTrace(getErr()); 7697 return ResultCode.LOCAL_ERROR; 7698 } 7699 7700 if (isNewKeystore) 7701 { 7702 out(); 7703 wrapOut(0, WRAP_COLUMN, 7704 INFO_MANAGE_CERTS_GEN_CERT_CERT_CREATED_KEYSTORE.get( 7705 getUserFriendlyKeystoreType(keystoreType))); 7706 } 7707 7708 7709 // If we're just generating a self-signed certificate, then display the 7710 // certificate that we generated and potentially write it to an output 7711 // file. 7712 if (isGenerateCertificate) 7713 { 7714 out(); 7715 wrapOut(0, WRAP_COLUMN, 7716 INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_SELF_CERT.get()); 7717 printCertificate(certificate, "", false); 7718 7719 7720 // If we should write an output file, then do that now. 7721 if (outputFile != null) 7722 { 7723 try (PrintStream ps = new PrintStream(outputFile)) 7724 { 7725 final byte[] certBytes = certificate.getX509CertificateBytes(); 7726 if (outputPEM) 7727 { 7728 writePEMCertificate(ps, certBytes); 7729 } 7730 else 7731 { 7732 ps.write(certBytes); 7733 } 7734 7735 out(); 7736 wrapOut(0, WRAP_COLUMN, 7737 INFO_MANAGE_CERTS_GEN_CERT_WROTE_OUTPUT_FILE.get( 7738 outputFile.getAbsolutePath())); 7739 } 7740 catch (final Exception e) 7741 { 7742 Debug.debugException(e); 7743 err(); 7744 wrapErr(0, WRAP_COLUMN, 7745 ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_CERT.get( 7746 outputFile.getAbsolutePath())); 7747 e.printStackTrace(getErr()); 7748 return ResultCode.LOCAL_ERROR; 7749 } 7750 } 7751 7752 return ResultCode.SUCCESS; 7753 } 7754 7755 7756 // If we're generating a certificate signing request, then put together 7757 // the appropriate set of arguments for that. 7758 Validator.ensureTrue(isGenerateCSR); 7759 out(); 7760 wrapOut(0, WRAP_COLUMN, 7761 INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_KEYPAIR.get()); 7762 7763 if (displayKeytoolCommand) 7764 { 7765 final ArrayList<String> keytoolArguments = new ArrayList<>(30); 7766 keytoolArguments.add("-certreq"); 7767 keytoolArguments.add("-keystore"); 7768 keytoolArguments.add(keystorePath.getAbsolutePath()); 7769 keytoolArguments.add("-storetype"); 7770 keytoolArguments.add(keystoreType); 7771 keytoolArguments.add("-storepass"); 7772 keytoolArguments.add("*****REDACTED*****"); 7773 keytoolArguments.add("-keypass"); 7774 keytoolArguments.add("*****REDACTED*****"); 7775 keytoolArguments.add("-alias"); 7776 keytoolArguments.add(alias); 7777 keytoolArguments.add("-dname"); 7778 keytoolArguments.add(subjectDN.toString()); 7779 keytoolArguments.add("-sigalg"); 7780 keytoolArguments.add(signatureAlgorithmName); 7781 7782 addExtensionArguments(keytoolArguments, basicConstraints, keyUsage, 7783 extendedKeyUsage, sanValues, ianValues, genericExtensions); 7784 7785 if (outputFile != null) 7786 { 7787 keytoolArguments.add("-file"); 7788 keytoolArguments.add(outputFile.getAbsolutePath()); 7789 } 7790 7791 displayKeytoolCommand(keytoolArguments); 7792 } 7793 7794 7795 // Generate the certificate signing request. 7796 final PKCS10CertificateSigningRequest certificateSigningRequest; 7797 try 7798 { 7799 certificateSigningRequest = PKCS10CertificateSigningRequest. 7800 generateCertificateSigningRequest(signatureAlgorithmIdentifier, 7801 keyPair, subjectDN, extensions); 7802 } 7803 catch (final Exception e) 7804 { 7805 Debug.debugException(e); 7806 wrapErr(0, WRAP_COLUMN, 7807 ERR_MANAGE_CERTS_GEN_CERT_ERROR_GENERATING_CSR.get()); 7808 e.printStackTrace(getErr()); 7809 return ResultCode.LOCAL_ERROR; 7810 } 7811 7812 7813 // Write the generated certificate signing request to the appropriate 7814 // location. 7815 try 7816 { 7817 final PrintStream ps; 7818 if (outputFile == null) 7819 { 7820 ps = getOut(); 7821 } 7822 else 7823 { 7824 ps = new PrintStream(outputFile); 7825 } 7826 7827 if (outputPEM) 7828 { 7829 writePEMCertificateSigningRequest(ps, 7830 certificateSigningRequest. 7831 getPKCS10CertificateSigningRequestBytes()); 7832 } 7833 else 7834 { 7835 ps.write(certificateSigningRequest. 7836 getPKCS10CertificateSigningRequestBytes()); 7837 } 7838 7839 if (outputFile != null) 7840 { 7841 ps.close(); 7842 } 7843 } 7844 catch (final Exception e) 7845 { 7846 Debug.debugException(e); 7847 wrapErr(0, WRAP_COLUMN, 7848 ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_CSR.get()); 7849 e.printStackTrace(getErr()); 7850 return ResultCode.LOCAL_ERROR; 7851 } 7852 7853 7854 // If the certificate signing request was written to an output file, 7855 // then let the user know that it was successful. If it was written to 7856 // standard output, then we don't need to tell them because they'll be 7857 // able to see it. 7858 if (outputFile != null) 7859 { 7860 out(); 7861 wrapOut(0, WRAP_COLUMN, 7862 INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_GENERATED_CSR.get( 7863 outputFile.getAbsolutePath())); 7864 } 7865 7866 return ResultCode.SUCCESS; 7867 } 7868 7869 7870 // If we've gotten here, then we should be signing a certificate signing 7871 // request. Make sure that the keystore already has a private key entry 7872 // with the specified alias. 7873 Validator.ensureTrue(isSignCSR); 7874 if (! hasKeyAlias(keystore, alias)) 7875 { 7876 if (hasCertificateAlias(keystore, alias)) 7877 { 7878 wrapErr(0, WRAP_COLUMN, 7879 ERR_MANAGE_CERTS_GEN_CERT_SIGN_ALIAS_IS_CERT.get(alias, 7880 keystorePath.getAbsolutePath())); 7881 return ResultCode.PARAM_ERROR; 7882 } 7883 else 7884 { 7885 wrapErr(0, WRAP_COLUMN, 7886 ERR_MANAGE_CERTS_GEN_CERT_SIGN_NO_SUCH_ALIAS.get(alias, 7887 keystorePath.getAbsolutePath())); 7888 return ResultCode.PARAM_ERROR; 7889 } 7890 } 7891 7892 7893 // Get the signing certificate and its key pair. 7894 final PrivateKey issuerPrivateKey; 7895 final X509Certificate issuerCertificate; 7896 try 7897 { 7898 final Certificate[] chain = keystore.getCertificateChain(alias); 7899 issuerCertificate = new X509Certificate(chain[0].getEncoded()); 7900 7901 issuerPrivateKey = 7902 (PrivateKey) keystore.getKey(alias, privateKeyPassword); 7903 } 7904 catch (final Exception e) 7905 { 7906 Debug.debugException(e); 7907 wrapErr(0, WRAP_COLUMN, 7908 ERR_MANAGE_CERTS_GEN_CERT_SIGN_CANNOT_GET_SIGNING_CERT.get(alias)); 7909 e.printStackTrace(getErr()); 7910 return ResultCode.LOCAL_ERROR; 7911 } 7912 7913 7914 // Make sure that we can decode the certificate signing request. 7915 final PKCS10CertificateSigningRequest csr; 7916 try 7917 { 7918 csr = readCertificateSigningRequestFromFile(inputFile); 7919 } 7920 catch (final LDAPException le) 7921 { 7922 Debug.debugException(le); 7923 wrapErr(0, WRAP_COLUMN, le.getMessage()); 7924 return le.getResultCode(); 7925 } 7926 7927 7928 // Make sure that we can verify the certificate signing request's signature. 7929 try 7930 { 7931 csr.verifySignature(); 7932 } 7933 catch (final CertException ce) 7934 { 7935 Debug.debugException(ce); 7936 wrapErr(0, WRAP_COLUMN, ce.getMessage()); 7937 return ResultCode.PARAM_ERROR; 7938 } 7939 7940 7941 // Prompt about whether to sign the request, if appropriate. 7942 if (! noPrompt) 7943 { 7944 out(); 7945 wrapOut(0, WRAP_COLUMN, 7946 INFO_MANAGE_CERTS_GEN_CERT_SIGN_CONFIRM.get()); 7947 out(); 7948 printCertificateSigningRequest(csr, false, ""); 7949 out(); 7950 7951 try 7952 { 7953 if (! promptForYesNo( 7954 INFO_MANAGE_CERTS_GEN_CERT_PROMPT_SIGN.get())) 7955 { 7956 wrapErr(0, WRAP_COLUMN, 7957 ERR_MANAGE_CERTS_GEN_CERT_SIGN_CANCELED.get()); 7958 return ResultCode.USER_CANCELED; 7959 } 7960 } 7961 catch (final LDAPException le) 7962 { 7963 Debug.debugException(le); 7964 err(); 7965 wrapErr(0, WRAP_COLUMN, le.getMessage()); 7966 return le.getResultCode(); 7967 } 7968 } 7969 7970 7971 // Read the certificate signing request and see if we need to take values 7972 // from it. 7973 if ((subjectDN == null) || (signatureAlgorithmIdentifier == null) || 7974 includeRequestedExtensions) 7975 { 7976 if (subjectDN == null) 7977 { 7978 subjectDN = csr.getSubjectDN(); 7979 } 7980 7981 if (signatureAlgorithmIdentifier == null) 7982 { 7983 signatureAlgorithmIdentifier = SignatureAlgorithmIdentifier.forOID( 7984 csr.getSignatureAlgorithmOID()); 7985 if (signatureAlgorithmIdentifier == null) 7986 { 7987 wrapErr(0, WRAP_COLUMN, 7988 ERR_MANAGE_CERTS_GEN_CERT_UNKNOWN_SIG_ALG_IN_CSR.get( 7989 csr.getSignatureAlgorithmOID())); 7990 return ResultCode.PARAM_ERROR; 7991 } 7992 else 7993 { 7994 signatureAlgorithmName = signatureAlgorithmIdentifier.getJavaName(); 7995 } 7996 } 7997 7998 if (includeRequestedExtensions) 7999 { 8000 for (final X509CertificateExtension extension : csr.getExtensions()) 8001 { 8002 if ((extension instanceof AuthorityKeyIdentifierExtension) || 8003 (extension instanceof IssuerAlternativeNameExtension)) 8004 { 8005 // This extension applies to the issuer. We won't include this in 8006 // the set of inherited extensions. 8007 } 8008 else if (extension instanceof SubjectKeyIdentifierExtension) 8009 { 8010 // The generated certificate will automatically include a subject 8011 // key identifier extension, so we don't need to include it. 8012 } 8013 else if (extension instanceof BasicConstraintsExtension) 8014 { 8015 // Don't override a value already provided on the command line. 8016 if (basicConstraints == null) 8017 { 8018 basicConstraints = (BasicConstraintsExtension) extension; 8019 extensionList.add(basicConstraints); 8020 } 8021 } 8022 else if (extension instanceof ExtendedKeyUsageExtension) 8023 { 8024 // Don't override a value already provided on the command line. 8025 if (extendedKeyUsage == null) 8026 { 8027 extendedKeyUsage = (ExtendedKeyUsageExtension) extension; 8028 extensionList.add(extendedKeyUsage); 8029 } 8030 } 8031 else if (extension instanceof KeyUsageExtension) 8032 { 8033 // Don't override a value already provided on the command line. 8034 if (keyUsage == null) 8035 { 8036 keyUsage = (KeyUsageExtension) extension; 8037 extensionList.add(keyUsage); 8038 } 8039 } 8040 else if (extension instanceof SubjectAlternativeNameExtension) 8041 { 8042 // Although we could merge values, it's safer to not do that if any 8043 // subject alternative name values were provided on the command 8044 // line. 8045 if (sanValues.isEmpty()) 8046 { 8047 final SubjectAlternativeNameExtension e = 8048 (SubjectAlternativeNameExtension) extension; 8049 for (final String dnsName : e.getDNSNames()) 8050 { 8051 sanBuilder.addDNSName(dnsName); 8052 sanValues.add("DNS:" + dnsName); 8053 } 8054 8055 for (final InetAddress ipAddress : e.getIPAddresses()) 8056 { 8057 sanBuilder.addIPAddress(ipAddress); 8058 sanValues.add("IP:" + ipAddress.getHostAddress()); 8059 } 8060 8061 for (final String emailAddress : e.getRFC822Names()) 8062 { 8063 sanBuilder.addRFC822Name(emailAddress); 8064 sanValues.add("EMAIL:" + emailAddress); 8065 } 8066 8067 for (final String uri : e.getUniformResourceIdentifiers()) 8068 { 8069 sanBuilder.addUniformResourceIdentifier(uri); 8070 sanValues.add("URI:" + uri); 8071 } 8072 8073 for (final OID oid : e.getRegisteredIDs()) 8074 { 8075 sanBuilder.addRegisteredID(oid); 8076 sanValues.add("OID:" + oid.toString()); 8077 } 8078 8079 try 8080 { 8081 extensionList.add( 8082 new SubjectAlternativeNameExtension(false, 8083 sanBuilder.build())); 8084 } 8085 catch (final Exception ex) 8086 { 8087 // This should never happen. 8088 Debug.debugException(ex); 8089 throw new RuntimeException(ex); 8090 } 8091 } 8092 } 8093 else 8094 { 8095 genericExtensions.add(extension); 8096 extensionList.add(extension); 8097 } 8098 } 8099 } 8100 } 8101 8102 8103 // Generate the keytool arguments to use to sign the requested certificate. 8104 final ArrayList<String> keytoolArguments = new ArrayList<>(30); 8105 keytoolArguments.add("-gencert"); 8106 keytoolArguments.add("-keystore"); 8107 keytoolArguments.add(keystorePath.getAbsolutePath()); 8108 keytoolArguments.add("-storetype"); 8109 keytoolArguments.add(keystoreType); 8110 keytoolArguments.add("-storepass"); 8111 keytoolArguments.add("*****REDACTED*****"); 8112 keytoolArguments.add("-keypass"); 8113 keytoolArguments.add("*****REDACTED*****"); 8114 keytoolArguments.add("-alias"); 8115 keytoolArguments.add(alias); 8116 keytoolArguments.add("-dname"); 8117 keytoolArguments.add(subjectDN.toString()); 8118 keytoolArguments.add("-sigalg"); 8119 keytoolArguments.add(signatureAlgorithmName); 8120 keytoolArguments.add("-validity"); 8121 keytoolArguments.add(String.valueOf(daysValid)); 8122 8123 if (validityStartTime != null) 8124 { 8125 keytoolArguments.add("-startdate"); 8126 keytoolArguments.add(formatValidityStartTime(validityStartTime)); 8127 } 8128 8129 addExtensionArguments(keytoolArguments, basicConstraints, keyUsage, 8130 extendedKeyUsage, sanValues, ianValues, genericExtensions); 8131 8132 keytoolArguments.add("-infile"); 8133 keytoolArguments.add(inputFile.getAbsolutePath()); 8134 8135 if (outputFile != null) 8136 { 8137 keytoolArguments.add("-outfile"); 8138 keytoolArguments.add(outputFile.getAbsolutePath()); 8139 } 8140 8141 if (outputPEM) 8142 { 8143 keytoolArguments.add("-rfc"); 8144 } 8145 8146 if (displayKeytoolCommand) 8147 { 8148 displayKeytoolCommand(keytoolArguments); 8149 } 8150 8151 8152 // Generate the signed certificate. 8153 final long notBefore; 8154 if (validityStartTime == null) 8155 { 8156 notBefore = System.currentTimeMillis(); 8157 } 8158 else 8159 { 8160 notBefore = validityStartTime.getTime(); 8161 } 8162 8163 final long notAfter = notBefore + TimeUnit.DAYS.toMillis(daysValid); 8164 8165 final X509CertificateExtension[] extensions = 8166 new X509CertificateExtension[extensionList.size()]; 8167 extensionList.toArray(extensions); 8168 8169 final X509Certificate signedCertificate; 8170 try 8171 { 8172 signedCertificate = X509Certificate.generateIssuerSignedCertificate( 8173 signatureAlgorithmIdentifier, issuerCertificate, issuerPrivateKey, 8174 csr.getPublicKeyAlgorithmOID(), 8175 csr.getPublicKeyAlgorithmParameters(), csr.getEncodedPublicKey(), 8176 csr.getDecodedPublicKey(), subjectDN, notBefore, notAfter, 8177 extensions); 8178 } 8179 catch (final Exception e) 8180 { 8181 Debug.debugException(e); 8182 wrapErr(0, WRAP_COLUMN, 8183 ERR_MANAGE_CERTS_GEN_CERT_ERROR_SIGNING_CERT.get()); 8184 e.printStackTrace(getErr()); 8185 return ResultCode.LOCAL_ERROR; 8186 } 8187 8188 8189 // Write the signed certificate signing request to the appropriate location. 8190 try 8191 { 8192 final PrintStream ps; 8193 if (outputFile == null) 8194 { 8195 ps = getOut(); 8196 } 8197 else 8198 { 8199 ps = new PrintStream(outputFile); 8200 } 8201 8202 if (outputPEM) 8203 { 8204 writePEMCertificate(ps, signedCertificate.getX509CertificateBytes()); 8205 } 8206 else 8207 { 8208 ps.write(signedCertificate.getX509CertificateBytes()); 8209 } 8210 8211 if (outputFile != null) 8212 { 8213 ps.close(); 8214 } 8215 } 8216 catch (final Exception e) 8217 { 8218 Debug.debugException(e); 8219 wrapErr(0, WRAP_COLUMN, 8220 ERR_MANAGE_CERTS_GEN_CERT_ERROR_WRITING_SIGNED_CERT.get()); 8221 e.printStackTrace(getErr()); 8222 return ResultCode.LOCAL_ERROR; 8223 } 8224 8225 8226 // If the certificate signing request was written to an output file, 8227 // then let the user know that it was successful. If it was written to 8228 // standard output, then we don't need to tell them because they'll be 8229 // able to see it. 8230 if (outputFile != null) 8231 { 8232 out(); 8233 wrapOut(0, WRAP_COLUMN, 8234 INFO_MANAGE_CERTS_GEN_CERT_SUCCESSFULLY_SIGNED_CERT.get( 8235 outputFile.getAbsolutePath())); 8236 } 8237 8238 return ResultCode.SUCCESS; 8239 } 8240 8241 8242 8243 /** 8244 * Performs the necessary processing for the change-certificate-alias 8245 * subcommand. 8246 * 8247 * @return A result code that indicates whether the processing completed 8248 * successfully. 8249 */ 8250 @NotNull() 8251 private ResultCode doChangeCertificateAlias() 8252 { 8253 // Get the values of a number of configured arguments. 8254 final StringArgument currentAliasArgument = 8255 subCommandParser.getStringArgument("current-alias"); 8256 final String currentAlias = currentAliasArgument.getValue(); 8257 8258 final StringArgument newAliasArgument = 8259 subCommandParser.getStringArgument("new-alias"); 8260 final String newAlias = newAliasArgument.getValue(); 8261 8262 final String keystoreType; 8263 final File keystorePath = getKeystorePath(); 8264 try 8265 { 8266 keystoreType = inferKeystoreType(keystorePath); 8267 } 8268 catch (final LDAPException le) 8269 { 8270 Debug.debugException(le); 8271 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8272 return le.getResultCode(); 8273 } 8274 8275 final char[] keystorePassword; 8276 try 8277 { 8278 keystorePassword = getKeystorePassword(keystorePath); 8279 } 8280 catch (final LDAPException le) 8281 { 8282 Debug.debugException(le); 8283 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8284 return le.getResultCode(); 8285 } 8286 8287 8288 // Get the keystore. 8289 final KeyStore keystore; 8290 try 8291 { 8292 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 8293 } 8294 catch (final LDAPException le) 8295 { 8296 Debug.debugException(le); 8297 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8298 return le.getResultCode(); 8299 } 8300 8301 8302 // See if we need to use a private key password that is different from the 8303 // keystore password. 8304 final char[] privateKeyPassword; 8305 try 8306 { 8307 privateKeyPassword = 8308 getPrivateKeyPassword(keystore, currentAlias, keystorePassword); 8309 } 8310 catch (final LDAPException le) 8311 { 8312 Debug.debugException(le); 8313 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8314 return le.getResultCode(); 8315 } 8316 8317 8318 // Make sure that the keystore has an existing entry with the current alias. 8319 // It must be either a certificate entry or a private key entry. 8320 final Certificate existingCertificate; 8321 final Certificate[] existingCertificateChain; 8322 final PrivateKey existingPrivateKey; 8323 try 8324 { 8325 if (hasCertificateAlias(keystore, currentAlias)) 8326 { 8327 existingCertificate = keystore.getCertificate(currentAlias); 8328 existingCertificateChain = null; 8329 existingPrivateKey = null; 8330 } 8331 else if (hasKeyAlias(keystore, currentAlias)) 8332 { 8333 existingCertificateChain = keystore.getCertificateChain(currentAlias); 8334 existingPrivateKey = 8335 (PrivateKey) keystore.getKey(currentAlias, privateKeyPassword); 8336 existingCertificate = null; 8337 } 8338 else 8339 { 8340 wrapErr(0, WRAP_COLUMN, 8341 ERR_MANAGE_CERTS_CHANGE_ALIAS_NO_SUCH_ALIAS.get(currentAlias)); 8342 return ResultCode.PARAM_ERROR; 8343 } 8344 } 8345 catch (final Exception e) 8346 { 8347 Debug.debugException(e); 8348 wrapErr(0, WRAP_COLUMN, 8349 ERR_MANAGE_CERTS_CHANGE_ALIAS_CANNOT_GET_EXISTING_ENTRY.get( 8350 currentAlias)); 8351 e.printStackTrace(getErr()); 8352 return ResultCode.LOCAL_ERROR; 8353 } 8354 8355 8356 // Make sure that the keystore does not have an entry with the new alias. 8357 if (hasCertificateAlias(keystore, newAlias) || 8358 hasKeyAlias(keystore, newAlias)) 8359 { 8360 wrapErr(0, WRAP_COLUMN, 8361 ERR_MANAGE_CERTS_CHANGE_ALIAS_NEW_ALIAS_IN_USE.get(newAlias)); 8362 return ResultCode.PARAM_ERROR; 8363 } 8364 8365 8366 // Generate the keytool arguments to use to change the certificate alias. 8367 final BooleanArgument displayKeytoolCommandArgument = 8368 subCommandParser.getBooleanArgument("display-keytool-command"); 8369 if ((displayKeytoolCommandArgument != null) && 8370 displayKeytoolCommandArgument.isPresent()) 8371 { 8372 final ArrayList<String> keytoolArguments = new ArrayList<>(30); 8373 keytoolArguments.add("-changealias"); 8374 keytoolArguments.add("-keystore"); 8375 keytoolArguments.add(keystorePath.getAbsolutePath()); 8376 keytoolArguments.add("-storetype"); 8377 keytoolArguments.add(keystoreType); 8378 keytoolArguments.add("-storepass"); 8379 keytoolArguments.add("*****REDACTED*****"); 8380 keytoolArguments.add("-keypass"); 8381 keytoolArguments.add("*****REDACTED*****"); 8382 keytoolArguments.add("-alias"); 8383 keytoolArguments.add(currentAlias); 8384 keytoolArguments.add("-destalias"); 8385 keytoolArguments.add(newAlias); 8386 8387 displayKeytoolCommand(keytoolArguments); 8388 } 8389 8390 8391 // Update the keystore to remove the entry with the current alias and 8392 // re-write it with the new alias. 8393 try 8394 { 8395 keystore.deleteEntry(currentAlias); 8396 if (existingCertificate != null) 8397 { 8398 keystore.setCertificateEntry(newAlias, existingCertificate); 8399 } 8400 else 8401 { 8402 keystore.setKeyEntry(newAlias, existingPrivateKey, 8403 privateKeyPassword, existingCertificateChain); 8404 } 8405 8406 writeKeystore(keystore, keystorePath, keystorePassword); 8407 } 8408 catch (final Exception e) 8409 { 8410 Debug.debugException(e); 8411 wrapErr(0, WRAP_COLUMN, 8412 ERR_MANAGE_CERTS_CHANGE_ALIAS_CANNOT_UPDATE_KEYSTORE.get()); 8413 e.printStackTrace(getErr()); 8414 return ResultCode.LOCAL_ERROR; 8415 } 8416 8417 wrapOut(0, WRAP_COLUMN, 8418 INFO_MANAGE_CERTS_CHANGE_ALIAS_SUCCESSFUL.get(currentAlias, 8419 newAlias)); 8420 return ResultCode.SUCCESS; 8421 } 8422 8423 8424 8425 /** 8426 * Performs the necessary processing for the change-keystore-password 8427 * subcommand. 8428 * 8429 * @return A result code that indicates whether the processing completed 8430 * successfully. 8431 */ 8432 @NotNull() 8433 private ResultCode doChangeKeystorePassword() 8434 { 8435 // Get the values of a number of configured arguments. 8436 final String keystoreType; 8437 final File keystorePath = getKeystorePath(); 8438 try 8439 { 8440 keystoreType = inferKeystoreType(keystorePath); 8441 } 8442 catch (final LDAPException le) 8443 { 8444 Debug.debugException(le); 8445 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8446 return le.getResultCode(); 8447 } 8448 8449 final char[] currentKeystorePassword; 8450 try 8451 { 8452 currentKeystorePassword = getKeystorePassword(keystorePath, "current"); 8453 } 8454 catch (final LDAPException le) 8455 { 8456 Debug.debugException(le); 8457 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8458 return le.getResultCode(); 8459 } 8460 8461 final char[] newKeystorePassword; 8462 try 8463 { 8464 newKeystorePassword = getKeystorePassword(keystorePath, "new"); 8465 } 8466 catch (final LDAPException le) 8467 { 8468 Debug.debugException(le); 8469 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8470 return le.getResultCode(); 8471 } 8472 8473 8474 // Get the keystore. 8475 final KeyStore keystore; 8476 try 8477 { 8478 keystore = getKeystore(keystoreType, keystorePath, 8479 currentKeystorePassword); 8480 } 8481 catch (final LDAPException le) 8482 { 8483 Debug.debugException(le); 8484 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8485 return le.getResultCode(); 8486 } 8487 8488 8489 // Generate the keytool arguments to use to change the keystore password. 8490 final BooleanArgument displayKeytoolCommandArgument = 8491 subCommandParser.getBooleanArgument("display-keytool-command"); 8492 if ((displayKeytoolCommandArgument != null) && 8493 displayKeytoolCommandArgument.isPresent()) 8494 { 8495 final ArrayList<String> keytoolArguments = new ArrayList<>(30); 8496 keytoolArguments.add("-storepasswd"); 8497 keytoolArguments.add("-keystore"); 8498 keytoolArguments.add(keystorePath.getAbsolutePath()); 8499 keytoolArguments.add("-storetype"); 8500 keytoolArguments.add(keystoreType); 8501 keytoolArguments.add("-storepass"); 8502 keytoolArguments.add("*****REDACTED*****"); 8503 keytoolArguments.add("-new"); 8504 keytoolArguments.add("*****REDACTED*****"); 8505 8506 displayKeytoolCommand(keytoolArguments); 8507 } 8508 8509 8510 // Rewrite the keystore with the new password. 8511 try 8512 { 8513 writeKeystore(keystore, keystorePath, newKeystorePassword); 8514 } 8515 catch (final LDAPException le) 8516 { 8517 Debug.debugException(le); 8518 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8519 return le.getResultCode(); 8520 } 8521 8522 wrapOut(0, WRAP_COLUMN, 8523 INFO_MANAGE_CERTS_CHANGE_KS_PW_SUCCESSFUL.get( 8524 keystorePath.getAbsolutePath())); 8525 return ResultCode.SUCCESS; 8526 } 8527 8528 8529 8530 /** 8531 * Performs the necessary processing for the change-private-key-password 8532 * subcommand. 8533 * 8534 * @return A result code that indicates whether the processing completed 8535 * successfully. 8536 */ 8537 @NotNull() 8538 private ResultCode doChangePrivateKeyPassword() 8539 { 8540 // Get the values of a number of configured arguments. 8541 final StringArgument aliasArgument = 8542 subCommandParser.getStringArgument("alias"); 8543 final String alias = aliasArgument.getValue(); 8544 8545 final String keystoreType; 8546 final File keystorePath = getKeystorePath(); 8547 try 8548 { 8549 keystoreType = inferKeystoreType(keystorePath); 8550 } 8551 catch (final LDAPException le) 8552 { 8553 Debug.debugException(le); 8554 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8555 return le.getResultCode(); 8556 } 8557 8558 final char[] keystorePassword; 8559 try 8560 { 8561 keystorePassword = getKeystorePassword(keystorePath); 8562 } 8563 catch (final LDAPException le) 8564 { 8565 Debug.debugException(le); 8566 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8567 return le.getResultCode(); 8568 } 8569 8570 8571 // Get the keystore. 8572 final KeyStore keystore; 8573 try 8574 { 8575 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 8576 } 8577 catch (final LDAPException le) 8578 { 8579 Debug.debugException(le); 8580 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8581 return le.getResultCode(); 8582 } 8583 8584 8585 // Make sure that the keystore has a key entry with the specified alias. 8586 if (hasCertificateAlias(keystore, alias)) 8587 { 8588 wrapErr(0, WRAP_COLUMN, 8589 ERR_MANAGE_CERTS_CHANGE_PK_PW_ALIAS_IS_CERT.get(alias)); 8590 return ResultCode.PARAM_ERROR; 8591 } 8592 else if (! hasKeyAlias(keystore, alias)) 8593 { 8594 wrapErr(0, WRAP_COLUMN, 8595 ERR_MANAGE_CERTS_CHANGE_PK_PW_NO_SUCH_ALIAS.get(alias)); 8596 return ResultCode.PARAM_ERROR; 8597 } 8598 8599 8600 // Get the current and new private key passwords. 8601 final char[] currentPrivateKeyPassword; 8602 try 8603 { 8604 currentPrivateKeyPassword = 8605 getPrivateKeyPassword(keystore, alias, "current", keystorePassword); 8606 } 8607 catch (final LDAPException le) 8608 { 8609 Debug.debugException(le); 8610 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8611 return le.getResultCode(); 8612 } 8613 8614 final char[] newPrivateKeyPassword; 8615 try 8616 { 8617 newPrivateKeyPassword = 8618 getPrivateKeyPassword(keystore, alias, "new", keystorePassword); 8619 } 8620 catch (final LDAPException le) 8621 { 8622 Debug.debugException(le); 8623 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8624 return le.getResultCode(); 8625 } 8626 8627 8628 // Generate the keytool arguments to use to change the private key. 8629 final BooleanArgument displayKeytoolCommandArgument = 8630 subCommandParser.getBooleanArgument("display-keytool-command"); 8631 if ((displayKeytoolCommandArgument != null) && 8632 displayKeytoolCommandArgument.isPresent()) 8633 { 8634 final ArrayList<String> keytoolArguments = new ArrayList<>(30); 8635 keytoolArguments.add("-keypasswd"); 8636 keytoolArguments.add("-keystore"); 8637 keytoolArguments.add(keystorePath.getAbsolutePath()); 8638 keytoolArguments.add("-storetype"); 8639 keytoolArguments.add(keystoreType); 8640 keytoolArguments.add("-storepass"); 8641 keytoolArguments.add("*****REDACTED*****"); 8642 keytoolArguments.add("-alias"); 8643 keytoolArguments.add(alias); 8644 keytoolArguments.add("-keypass"); 8645 keytoolArguments.add("*****REDACTED*****"); 8646 keytoolArguments.add("-new"); 8647 keytoolArguments.add("*****REDACTED*****"); 8648 8649 displayKeytoolCommand(keytoolArguments); 8650 } 8651 8652 8653 // Get the contents of the private key entry. 8654 final Certificate[] chain; 8655 final PrivateKey privateKey; 8656 try 8657 { 8658 chain = keystore.getCertificateChain(alias); 8659 privateKey = 8660 (PrivateKey) keystore.getKey(alias, currentPrivateKeyPassword); 8661 } 8662 catch (final UnrecoverableKeyException e) 8663 { 8664 Debug.debugException(e); 8665 wrapErr(0, WRAP_COLUMN, 8666 ERR_MANAGE_CERTS_CHANGE_PK_PW_WRONG_PK_PW.get(alias)); 8667 return ResultCode.PARAM_ERROR; 8668 } 8669 catch (final Exception e) 8670 { 8671 Debug.debugException(e); 8672 wrapErr(0, WRAP_COLUMN, 8673 ERR_MANAGE_CERTS_CHANGE_PK_PW_CANNOT_GET_PK.get(alias)); 8674 e.printStackTrace(getErr()); 8675 return ResultCode.LOCAL_ERROR; 8676 } 8677 8678 8679 // Remove the existing key entry and re-add it with the new password. 8680 try 8681 { 8682 keystore.deleteEntry(alias); 8683 keystore.setKeyEntry(alias, privateKey, newPrivateKeyPassword, chain); 8684 writeKeystore(keystore, keystorePath, keystorePassword); 8685 } 8686 catch (final Exception e) 8687 { 8688 Debug.debugException(e); 8689 wrapErr(0, WRAP_COLUMN, 8690 ERR_MANAGE_CERTS_CHANGE_PK_PW_CANNOT_UPDATE_KS.get()); 8691 e.printStackTrace(getErr()); 8692 return ResultCode.LOCAL_ERROR; 8693 } 8694 8695 wrapOut(0, WRAP_COLUMN, 8696 INFO_MANAGE_CERTS_CHANGE_PK_PW_SUCCESSFUL.get(alias)); 8697 return ResultCode.SUCCESS; 8698 } 8699 8700 8701 8702 /** 8703 * Performs the necessary processing for the copy-keystore subcommand. 8704 * 8705 * @return A result code that indicates whether the processing completed 8706 * successfully. 8707 */ 8708 @NotNull() 8709 private ResultCode doCopyKeystore() 8710 { 8711 // Get the source key store. 8712 final String sourceKeyStoreType; 8713 final File sourceKeyStorePath = getKeystorePath("source-keystore"); 8714 try 8715 { 8716 sourceKeyStoreType = inferKeystoreType(sourceKeyStorePath, "source"); 8717 } 8718 catch (final LDAPException le) 8719 { 8720 Debug.debugException(le); 8721 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8722 return le.getResultCode(); 8723 } 8724 8725 final char[] sourceKeyStorePassword; 8726 try 8727 { 8728 sourceKeyStorePassword = 8729 getKeystorePassword(sourceKeyStorePath, "source"); 8730 } 8731 catch (final LDAPException le) 8732 { 8733 Debug.debugException(le); 8734 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8735 return le.getResultCode(); 8736 } 8737 8738 final KeyStore sourceKeyStore; 8739 try 8740 { 8741 sourceKeyStore = getKeystore(sourceKeyStoreType, sourceKeyStorePath, 8742 sourceKeyStorePassword); 8743 } 8744 catch (final LDAPException le) 8745 { 8746 Debug.debugException(le); 8747 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8748 return le.getResultCode(); 8749 } 8750 8751 8752 // Get the destination key store. 8753 final String destinationKeyStoreType; 8754 final File destinationKeyStorePath = 8755 getKeystorePath("destination-keystore"); 8756 try 8757 { 8758 destinationKeyStoreType = inferKeystoreType(destinationKeyStorePath, 8759 "destination"); 8760 } 8761 catch (final LDAPException le) 8762 { 8763 Debug.debugException(le); 8764 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8765 return le.getResultCode(); 8766 } 8767 8768 final boolean destinationExists = destinationKeyStorePath.exists(); 8769 8770 char[] destinationKeyStorePassword; 8771 try 8772 { 8773 destinationKeyStorePassword = 8774 getKeystorePassword(destinationKeyStorePath, "destination"); 8775 if (destinationKeyStorePassword == null) 8776 { 8777 destinationKeyStorePassword = sourceKeyStorePassword; 8778 } 8779 } 8780 catch (final LDAPException le) 8781 { 8782 Debug.debugException(le); 8783 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8784 return le.getResultCode(); 8785 } 8786 8787 final KeyStore destinationKeyStore; 8788 try 8789 { 8790 destinationKeyStore = getKeystore(destinationKeyStoreType, 8791 destinationKeyStorePath, destinationKeyStorePassword); 8792 } 8793 catch (final LDAPException le) 8794 { 8795 Debug.debugException(le); 8796 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8797 return le.getResultCode(); 8798 } 8799 8800 8801 // Get the value of the aliases argument, if it was provided. 8802 final Set<String> aliases = new LinkedHashSet<>(); 8803 try 8804 { 8805 final StringArgument aliasArg = 8806 subCommandParser.getStringArgument("alias"); 8807 if ((aliasArg != null) && aliasArg.isPresent()) 8808 { 8809 for (final String alias : aliasArg.getValues()) 8810 { 8811 aliases.add(alias); 8812 if (! sourceKeyStore.containsAlias(alias)) 8813 { 8814 wrapErr(0, WRAP_COLUMN, 8815 ERR_MANAGE_CERTS_COPY_KS_NO_SUCH_SOURCE_ALIAS.get( 8816 sourceKeyStorePath.getAbsolutePath(), alias)); 8817 return ResultCode.PARAM_ERROR; 8818 } 8819 } 8820 } 8821 else 8822 { 8823 final Enumeration<String> sourceAliases = sourceKeyStore.aliases(); 8824 while (sourceAliases.hasMoreElements()) 8825 { 8826 aliases.add(sourceAliases.nextElement()); 8827 } 8828 } 8829 } 8830 catch (final Exception e) 8831 { 8832 Debug.debugException(e); 8833 wrapErr(0, WRAP_COLUMN, 8834 ERR_MANAGE_CERTS_COPY_KS_CANNOT_GET_SOURCE_ALIASES.get( 8835 sourceKeyStorePath.getAbsolutePath(), 8836 StaticUtils.getExceptionMessage(e))); 8837 return ResultCode.LOCAL_ERROR; 8838 } 8839 8840 8841 // If the set of aliases is empty and the destination key store already 8842 // exists, then exit without doing anything. 8843 if (aliases.isEmpty() && destinationExists) 8844 { 8845 wrapOut(0, WRAP_COLUMN, 8846 INFO_MANAGE_CERTS_COPY_KS_NO_CERTS_COPIED_EXISTING_KS.get( 8847 sourceKeyStorePath.getAbsolutePath(), 8848 destinationKeyStorePath.getAbsolutePath())); 8849 return ResultCode.SUCCESS; 8850 } 8851 8852 8853 // Make sure that none of the target aliases exist in the destination key 8854 // store. 8855 for (final String alias : aliases) 8856 { 8857 try 8858 { 8859 if (destinationKeyStore.containsAlias(alias)) 8860 { 8861 wrapErr(0, WRAP_COLUMN, 8862 ERR_MANAGE_CERTS_COPY_KS_CONFLICTING_ALIAS.get(alias, 8863 destinationKeyStorePath.getAbsolutePath(), 8864 subCommandParser.getCommandName())); 8865 return ResultCode.CONSTRAINT_VIOLATION; 8866 } 8867 } 8868 catch (final Exception e) 8869 { 8870 Debug.debugException(e); 8871 wrapErr(0, WRAP_COLUMN, 8872 ERR_MANAGE_CERTS_COPY_KS_CANNOT_CHECK_DEST_ALIAS.get(alias, 8873 destinationKeyStorePath.getAbsolutePath(), 8874 StaticUtils.getExceptionMessage(e))); 8875 return ResultCode.LOCAL_ERROR; 8876 } 8877 } 8878 8879 8880 // Copy each of the targeted entries from the source key store into the 8881 // destination key store. 8882 char[] sourcePrivateKeyPassword = null; 8883 char[] destinationPrivateKeyPassword = null; 8884 for (final String alias : aliases) 8885 { 8886 try 8887 { 8888 if (sourceKeyStore.isCertificateEntry(alias)) 8889 { 8890 final Certificate certificate = sourceKeyStore.getCertificate(alias); 8891 destinationKeyStore.setCertificateEntry(alias, certificate); 8892 } 8893 else 8894 { 8895 if (sourcePrivateKeyPassword == null) 8896 { 8897 sourcePrivateKeyPassword = getPrivateKeyPassword(sourceKeyStore, 8898 alias, "source", sourceKeyStorePassword); 8899 } 8900 8901 if (destinationPrivateKeyPassword == null) 8902 { 8903 destinationPrivateKeyPassword = getPrivateKeyPassword( 8904 destinationKeyStore, alias, "destination", 8905 destinationKeyStorePassword); 8906 } 8907 8908 final Certificate[] chain = sourceKeyStore.getCertificateChain(alias); 8909 final Key key = 8910 sourceKeyStore.getKey(alias, sourcePrivateKeyPassword); 8911 destinationKeyStore.setKeyEntry(alias, key, 8912 destinationPrivateKeyPassword, chain); 8913 } 8914 } 8915 catch (final Exception e) 8916 { 8917 Debug.debugException(e); 8918 wrapErr(0, WRAP_COLUMN, 8919 ERR_MANAGE_CERTS_COPY_KS_ERROR_COPYING_ENTRY.get(alias, 8920 sourceKeyStorePath.getAbsolutePath(), 8921 destinationKeyStorePath.getAbsolutePath(), 8922 StaticUtils.getExceptionMessage(e))); 8923 return ResultCode.LOCAL_ERROR; 8924 } 8925 } 8926 8927 8928 // Rewrite the destination keystore. 8929 try 8930 { 8931 writeKeystore(destinationKeyStore, destinationKeyStorePath, 8932 destinationKeyStorePassword); 8933 } 8934 catch (final LDAPException le) 8935 { 8936 Debug.debugException(le); 8937 wrapErr(0, WRAP_COLUMN, le.getMessage()); 8938 return le.getResultCode(); 8939 } 8940 8941 if (aliases.isEmpty()) 8942 { 8943 // This should only happen if the alias argument was not provided, the 8944 // source key store is empty, and the destination key store doesn't exist. 8945 // In that case, the destination key store will have been created. 8946 wrapOut(0, WRAP_COLUMN, 8947 INFO_MANAGE_CERTS_COPY_KS_NO_CERTS_COPIED_KS_CREATED.get( 8948 sourceKeyStorePath.getAbsolutePath(), 8949 destinationKeyStoreType, 8950 destinationKeyStorePath.getAbsolutePath())); 8951 } 8952 else 8953 { 8954 // Write a message about the entries that were successfully copied. 8955 wrapOut(0, WRAP_COLUMN, 8956 INFO_MANAGE_CERTS_COPY_KS_CERTS_COPIED_HEADER.get( 8957 sourceKeyStorePath.getAbsolutePath(), 8958 destinationKeyStoreType, 8959 destinationKeyStorePath.getAbsolutePath())); 8960 for (final String alias : aliases) 8961 { 8962 out("* ", alias); 8963 } 8964 } 8965 8966 return ResultCode.SUCCESS; 8967 } 8968 8969 8970 8971 /** 8972 * Performs the necessary processing for the retrieve-server-certificate 8973 * subcommand. 8974 * 8975 * @return A result code that indicates whether the processing completed 8976 * successfully. 8977 */ 8978 @NotNull() 8979 private ResultCode doRetrieveServerCertificate() 8980 { 8981 // Get the values of a number of configured arguments. 8982 final StringArgument hostnameArgument = 8983 subCommandParser.getStringArgument("hostname"); 8984 final String hostname = hostnameArgument.getValue(); 8985 8986 final IntegerArgument portArgument = 8987 subCommandParser.getIntegerArgument("port"); 8988 final int port = portArgument.getValue(); 8989 8990 final BooleanArgument useLDAPStartTLSArgument = 8991 subCommandParser.getBooleanArgument("use-ldap-start-tls"); 8992 final boolean useLDAPStartTLS = 8993 ((useLDAPStartTLSArgument != null) && 8994 useLDAPStartTLSArgument.isPresent()); 8995 8996 final BooleanArgument onlyPeerArgument = 8997 subCommandParser.getBooleanArgument("only-peer-certificate"); 8998 final boolean onlyPeer = 8999 ((onlyPeerArgument != null) && onlyPeerArgument.isPresent()); 9000 9001 final BooleanArgument verboseArgument = 9002 subCommandParser.getBooleanArgument("verbose"); 9003 final boolean verbose = 9004 ((verboseArgument != null) && verboseArgument.isPresent()); 9005 9006 boolean outputPEM = true; 9007 final StringArgument outputFormatArgument = 9008 subCommandParser.getStringArgument("output-format"); 9009 if ((outputFormatArgument != null) && outputFormatArgument.isPresent()) 9010 { 9011 final String format = outputFormatArgument.getValue().toLowerCase(); 9012 if (format.equals("der") || format.equals("binary") || 9013 format.equals("bin")) 9014 { 9015 outputPEM = false; 9016 } 9017 } 9018 9019 File outputFile = null; 9020 final FileArgument outputFileArgument = 9021 subCommandParser.getFileArgument("output-file"); 9022 if ((outputFileArgument != null) && outputFileArgument.isPresent()) 9023 { 9024 outputFile = outputFileArgument.getValue(); 9025 } 9026 9027 9028 // Spawn a background thread to establish a connection and get the 9029 // certificate chain from the target server. 9030 final LinkedBlockingQueue<Object> responseQueue = 9031 new LinkedBlockingQueue<>(10); 9032 final ManageCertificatesServerCertificateCollector certificateCollector = 9033 new ManageCertificatesServerCertificateCollector(this, hostname, port, 9034 useLDAPStartTLS, verbose, responseQueue); 9035 certificateCollector.start(); 9036 9037 Object responseObject = 9038 ERR_MANAGE_CERTS_RETRIEVE_CERT_NO_CERT_CHAIN_RECEIVED.get( 9039 hostname + ':' + port); 9040 try 9041 { 9042 responseObject = responseQueue.poll(90L, TimeUnit.SECONDS); 9043 } 9044 catch (final Exception e) 9045 { 9046 Debug.debugException(e); 9047 } 9048 9049 final X509Certificate[] chain; 9050 if (responseObject instanceof X509Certificate[]) 9051 { 9052 chain = (X509Certificate[]) responseObject; 9053 if (chain.length == 0) 9054 { 9055 wrapErr(0, WRAP_COLUMN, 9056 ERR_MANAGE_CERTS_RETRIEVE_CERT_EMPTY_CHAIN.get()); 9057 return ResultCode.NO_RESULTS_RETURNED; 9058 } 9059 } 9060 else if (responseObject instanceof CertException) 9061 { 9062 // The error message will have already been recorded by the collector 9063 // thread, so we can just return a non-success result. 9064 return ResultCode.LOCAL_ERROR; 9065 } 9066 else 9067 { 9068 wrapErr(0, WRAP_COLUMN, String.valueOf(responseObject)); 9069 return ResultCode.LOCAL_ERROR; 9070 } 9071 9072 try 9073 { 9074 certificateCollector.join(10_000L); 9075 } 9076 catch (final Exception e) 9077 { 9078 Debug.debugException(e); 9079 } 9080 9081 9082 // If the certificates should be written to a file, then do that now. 9083 if (outputFile != null) 9084 { 9085 try (PrintStream s = new PrintStream(outputFile)) 9086 { 9087 for (final X509Certificate c : chain) 9088 { 9089 if (outputPEM) 9090 { 9091 writePEMCertificate(s, c.getX509CertificateBytes()); 9092 } 9093 else 9094 { 9095 s.write(c.getX509CertificateBytes()); 9096 } 9097 9098 if (onlyPeer) 9099 { 9100 break; 9101 } 9102 } 9103 } 9104 catch (final Exception e) 9105 { 9106 Debug.debugException(e); 9107 wrapErr(0, WRAP_COLUMN, 9108 ERR_MANAGE_CERTS_RETRIEVE_CERT_CANNOT_WRITE_TO_FILE.get( 9109 outputFile.getAbsolutePath(), 9110 StaticUtils.getExceptionMessage(e))); 9111 return ResultCode.LOCAL_ERROR; 9112 } 9113 } 9114 9115 9116 // Display information about the certificates. 9117 for (int i=0; i < chain.length; i++) 9118 { 9119 if (verbose || (i > 0)) 9120 { 9121 out(); 9122 out(); 9123 } 9124 9125 if ((! onlyPeer) && (chain.length > 1)) 9126 { 9127 wrapOut(0, WRAP_COLUMN, 9128 INFO_MANAGE_CERTS_RETRIEVE_CERT_DISPLAY_HEADER.get((i+1), 9129 chain.length)); 9130 out(); 9131 } 9132 9133 final X509Certificate c = chain[i]; 9134 writePEMCertificate(getOut(), c.getX509CertificateBytes()); 9135 out(); 9136 printCertificate(c, "", verbose); 9137 9138 if (onlyPeer) 9139 { 9140 break; 9141 } 9142 } 9143 9144 return ResultCode.SUCCESS; 9145 } 9146 9147 9148 9149 /** 9150 * Performs the necessary processing for the trust-server-certificate 9151 * subcommand. 9152 * 9153 * @return A result code that indicates whether the processing completed 9154 * successfully. 9155 */ 9156 @NotNull() 9157 private ResultCode doTrustServerCertificate() 9158 { 9159 // Get the values of a number of configured arguments. 9160 final StringArgument hostnameArgument = 9161 subCommandParser.getStringArgument("hostname"); 9162 final String hostname = hostnameArgument.getValue(); 9163 9164 final IntegerArgument portArgument = 9165 subCommandParser.getIntegerArgument("port"); 9166 final int port = portArgument.getValue(); 9167 9168 final String alias; 9169 final StringArgument aliasArgument = 9170 subCommandParser.getStringArgument("alias"); 9171 if ((aliasArgument != null) && aliasArgument.isPresent()) 9172 { 9173 alias = aliasArgument.getValue(); 9174 } 9175 else 9176 { 9177 alias = hostname + ':' + port; 9178 } 9179 9180 final BooleanArgument useLDAPStartTLSArgument = 9181 subCommandParser.getBooleanArgument("use-ldap-start-tls"); 9182 final boolean useLDAPStartTLS = 9183 ((useLDAPStartTLSArgument != null) && 9184 useLDAPStartTLSArgument.isPresent()); 9185 9186 final BooleanArgument issuersOnlyArgument = 9187 subCommandParser.getBooleanArgument("issuers-only"); 9188 final boolean issuersOnly = 9189 ((issuersOnlyArgument != null) && issuersOnlyArgument.isPresent()); 9190 9191 final BooleanArgument noPromptArgument = 9192 subCommandParser.getBooleanArgument("no-prompt"); 9193 final boolean noPrompt = 9194 ((noPromptArgument != null) && noPromptArgument.isPresent()); 9195 9196 final BooleanArgument verboseArgument = 9197 subCommandParser.getBooleanArgument("verbose"); 9198 final boolean verbose = 9199 ((verboseArgument != null) && verboseArgument.isPresent()); 9200 9201 final String keystoreType; 9202 final File keystorePath = getKeystorePath(); 9203 final boolean isNewKeystore = (! keystorePath.exists()); 9204 try 9205 { 9206 keystoreType = inferKeystoreType(keystorePath); 9207 } 9208 catch (final LDAPException le) 9209 { 9210 Debug.debugException(le); 9211 wrapErr(0, WRAP_COLUMN, le.getMessage()); 9212 return le.getResultCode(); 9213 } 9214 9215 final char[] keystorePassword; 9216 try 9217 { 9218 keystorePassword = getKeystorePassword(keystorePath); 9219 } 9220 catch (final LDAPException le) 9221 { 9222 Debug.debugException(le); 9223 wrapErr(0, WRAP_COLUMN, le.getMessage()); 9224 return le.getResultCode(); 9225 } 9226 9227 9228 // Get the keystore. 9229 final KeyStore keystore; 9230 try 9231 { 9232 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 9233 } 9234 catch (final LDAPException le) 9235 { 9236 Debug.debugException(le); 9237 wrapErr(0, WRAP_COLUMN, le.getMessage()); 9238 return le.getResultCode(); 9239 } 9240 9241 9242 // Make sure that the specified alias is not already in use. 9243 if (hasCertificateAlias(keystore, alias) || 9244 hasKeyAlias(keystore, alias)) 9245 { 9246 wrapErr(0, WRAP_COLUMN, 9247 ERR_MANAGE_CERTS_TRUST_SERVER_ALIAS_IN_USE.get(alias)); 9248 return ResultCode.PARAM_ERROR; 9249 } 9250 9251 9252 // Spawn a background thread to establish a connection and get the 9253 // certificate chain from the target server. 9254 final LinkedBlockingQueue<Object> responseQueue = 9255 new LinkedBlockingQueue<>(10); 9256 final ManageCertificatesServerCertificateCollector certificateCollector = 9257 new ManageCertificatesServerCertificateCollector(this, hostname, port, 9258 useLDAPStartTLS, verbose, responseQueue); 9259 certificateCollector.start(); 9260 9261 Object responseObject = 9262 ERR_MANAGE_CERTS_TRUST_SERVER_NO_CERT_CHAIN_RECEIVED.get( 9263 hostname + ':' + port); 9264 try 9265 { 9266 responseObject = responseQueue.poll(90L, TimeUnit.SECONDS); 9267 } 9268 catch (final Exception e) 9269 { 9270 Debug.debugException(e); 9271 } 9272 9273 final X509Certificate[] chain; 9274 if (responseObject instanceof X509Certificate[]) 9275 { 9276 chain = (X509Certificate[]) responseObject; 9277 } 9278 else if (responseObject instanceof CertException) 9279 { 9280 // The error message will have already been recorded by the collector 9281 // thread, so we can just return a non-success result. 9282 return ResultCode.LOCAL_ERROR; 9283 } 9284 else 9285 { 9286 wrapErr(0, WRAP_COLUMN, String.valueOf(responseObject)); 9287 return ResultCode.LOCAL_ERROR; 9288 } 9289 9290 try 9291 { 9292 certificateCollector.join(10_000L); 9293 } 9294 catch (final Exception e) 9295 { 9296 Debug.debugException(e); 9297 } 9298 9299 9300 // If we should prompt the user about whether to trust the certificates, 9301 // then do so now. 9302 if (! noPrompt) 9303 { 9304 out(); 9305 wrapOut(0, WRAP_COLUMN, 9306 INFO_MANAGE_CERTS_TRUST_SERVER_RETRIEVED_CHAIN.get( 9307 hostname + ':' + port)); 9308 9309 boolean isFirst = true; 9310 for (final X509Certificate c : chain) 9311 { 9312 out(); 9313 9314 if (isFirst) 9315 { 9316 isFirst = false; 9317 if (issuersOnly && (chain.length > 1)) 9318 { 9319 wrapOut(0, WRAP_COLUMN, 9320 INFO_MANAGE_CERTS_TRUST_SERVER_NOTE_OMITTED.get()); 9321 out(); 9322 } 9323 } 9324 9325 printCertificate(c, "", verbose); 9326 } 9327 9328 out(); 9329 9330 try 9331 { 9332 if (! promptForYesNo(INFO_MANAGE_CERTS_TRUST_SERVER_PROMPT_TRUST.get())) 9333 { 9334 wrapErr(0, WRAP_COLUMN, 9335 ERR_MANAGE_CERTS_TRUST_SERVER_CHAIN_REJECTED.get()); 9336 return ResultCode.USER_CANCELED; 9337 } 9338 } 9339 catch (final LDAPException le) 9340 { 9341 Debug.debugException(le); 9342 err(); 9343 wrapErr(0, WRAP_COLUMN, le.getMessage()); 9344 return le.getResultCode(); 9345 } 9346 } 9347 9348 9349 // Add the certificates to the keystore. 9350 final LinkedHashMap<String,X509Certificate> certsByAlias = 9351 new LinkedHashMap<>(StaticUtils.computeMapCapacity(chain.length)); 9352 for (int i=0; i < chain.length; i++) 9353 { 9354 if (i == 0) 9355 { 9356 if (issuersOnly && (chain.length > 1)) 9357 { 9358 continue; 9359 } 9360 9361 certsByAlias.put(alias, chain[i]); 9362 } 9363 else if ((i == 1) && (chain.length == 2)) 9364 { 9365 certsByAlias.put(alias + "-issuer", chain[i]); 9366 } 9367 else 9368 { 9369 certsByAlias.put(alias + "-issuer-" + i, chain[i]); 9370 } 9371 } 9372 9373 for (final Map.Entry<String,X509Certificate> e : certsByAlias.entrySet()) 9374 { 9375 final String certAlias = e.getKey(); 9376 final X509Certificate cert = e.getValue(); 9377 9378 try 9379 { 9380 Validator.ensureFalse( 9381 (hasCertificateAlias(keystore, certAlias) || 9382 hasKeyAlias(keystore, certAlias)), 9383 "ERROR: Alias '" + certAlias + "' is already in use in the " + 9384 "keystore."); 9385 keystore.setCertificateEntry(certAlias, cert.toCertificate()); 9386 } 9387 catch (final Exception ex) 9388 { 9389 Debug.debugException(ex); 9390 wrapErr(0, WRAP_COLUMN, 9391 ERR_MANAGE_CERTS_TRUST_SERVER_ERROR_ADDING_CERT_TO_KS.get( 9392 cert.getSubjectDN())); 9393 ex.printStackTrace(getErr()); 9394 return ResultCode.LOCAL_ERROR; 9395 } 9396 } 9397 9398 9399 // Save the updated keystore. 9400 try 9401 { 9402 writeKeystore(keystore, keystorePath, keystorePassword); 9403 } 9404 catch (final LDAPException le) 9405 { 9406 Debug.debugException(le); 9407 wrapErr(0, WRAP_COLUMN, le.getMessage()); 9408 return le.getResultCode(); 9409 } 9410 9411 if (isNewKeystore) 9412 { 9413 out(); 9414 wrapOut(0, WRAP_COLUMN, 9415 INFO_MANAGE_CERTS_TRUST_SERVER_CERT_CREATED_KEYSTORE.get( 9416 getUserFriendlyKeystoreType(keystoreType))); 9417 } 9418 9419 out(); 9420 if (certsByAlias.size() == 1) 9421 { 9422 wrapOut(0, WRAP_COLUMN, 9423 INFO_MANAGE_CERTS_TRUST_SERVER_ADDED_CERT_TO_KS.get()); 9424 } 9425 else 9426 { 9427 wrapOut(0, WRAP_COLUMN, 9428 INFO_MANAGE_CERTS_TRUST_SERVER_ADDED_CERTS_TO_KS.get( 9429 certsByAlias.size())); 9430 } 9431 9432 return ResultCode.SUCCESS; 9433 } 9434 9435 9436 9437 /** 9438 * Performs the necessary processing for the check-certificate-usability 9439 * subcommand. 9440 * 9441 * @return A result code that indicates whether the processing completed 9442 * successfully. 9443 */ 9444 @NotNull() 9445 private ResultCode doCheckCertificateUsability() 9446 { 9447 // Get the values of a number of configured arguments. 9448 final StringArgument aliasArgument = 9449 subCommandParser.getStringArgument("alias"); 9450 final String alias = aliasArgument.getValue(); 9451 9452 final String keystoreType; 9453 final File keystorePath = getKeystorePath(); 9454 try 9455 { 9456 keystoreType = inferKeystoreType(keystorePath); 9457 } 9458 catch (final LDAPException le) 9459 { 9460 Debug.debugException(le); 9461 wrapErr(0, WRAP_COLUMN, le.getMessage()); 9462 return le.getResultCode(); 9463 } 9464 9465 final char[] keystorePassword; 9466 try 9467 { 9468 keystorePassword = getKeystorePassword(keystorePath); 9469 } 9470 catch (final LDAPException le) 9471 { 9472 Debug.debugException(le); 9473 wrapErr(0, WRAP_COLUMN, le.getMessage()); 9474 return le.getResultCode(); 9475 } 9476 9477 9478 // Get the keystore. 9479 final KeyStore keystore; 9480 try 9481 { 9482 keystore = getKeystore(keystoreType, keystorePath, keystorePassword); 9483 } 9484 catch (final LDAPException le) 9485 { 9486 Debug.debugException(le); 9487 wrapErr(0, WRAP_COLUMN, le.getMessage()); 9488 return le.getResultCode(); 9489 } 9490 9491 9492 // Make sure that the specified entry exists in the keystore and is 9493 // associated with a certificate chain and a private key. 9494 final X509Certificate[] chain; 9495 if (hasKeyAlias(keystore, alias)) 9496 { 9497 try 9498 { 9499 final Certificate[] genericChain = keystore.getCertificateChain(alias); 9500 Validator.ensureTrue((genericChain.length > 0), 9501 "ERROR: The keystore has a private key entry for alias '" + 9502 alias + "', but the associated certificate chain is empty."); 9503 9504 chain = new X509Certificate[genericChain.length]; 9505 for (int i=0; i < genericChain.length; i++) 9506 { 9507 chain[i] = new X509Certificate(genericChain[i].getEncoded()); 9508 } 9509 9510 out(); 9511 wrapOut(0, WRAP_COLUMN, 9512 INFO_MANAGE_CERTS_CHECK_USABILITY_GOT_CHAIN.get(alias)); 9513 9514 for (final X509Certificate c : chain) 9515 { 9516 out(); 9517 printCertificate(c, "", false); 9518 } 9519 } 9520 catch (final Exception e) 9521 { 9522 Debug.debugException(e); 9523 wrapErr(0, WRAP_COLUMN, 9524 ERR_MANAGE_CERTS_CHECK_USABILITY_CANNOT_GET_CHAIN.get(alias)); 9525 e.printStackTrace(getErr()); 9526 return ResultCode.LOCAL_ERROR; 9527 } 9528 } 9529 else if (hasCertificateAlias(keystore, alias)) 9530 { 9531 wrapErr(0, WRAP_COLUMN, 9532 ERR_MANAGE_CERTS_CHECK_USABILITY_NO_PRIVATE_KEY.get(alias)); 9533 return ResultCode.PARAM_ERROR; 9534 } 9535 else 9536 { 9537 wrapErr(0, WRAP_COLUMN, 9538 ERR_MANAGE_CERTS_CHECK_USABILITY_NO_SUCH_ALIAS.get(alias)); 9539 return ResultCode.PARAM_ERROR; 9540 } 9541 9542 9543 // Check to see if the certificate is self-signed. If so, then that's a 9544 // warning. If not, then make sure that the chain is complete and that each 9545 // subsequent certificate is the issuer of the previous. 9546 int numWarnings = 0; 9547 int numErrors = 0; 9548 if (chain[0].isSelfSigned()) 9549 { 9550 err(); 9551 wrapErr(0, WRAP_COLUMN, 9552 WARN_MANAGE_CERTS_CHECK_USABILITY_CERT_IS_SELF_SIGNED.get( 9553 chain[0].getSubjectDN())); 9554 numWarnings++; 9555 } 9556 else if ((chain.length == 1) || (! chain[chain.length - 1].isSelfSigned())) 9557 { 9558 err(); 9559 wrapErr(0, WRAP_COLUMN, 9560 ERR_MANAGE_CERTS_CHECK_USABILITY_END_OF_CHAIN_NOT_SELF_SIGNED.get( 9561 alias)); 9562 numErrors++; 9563 } 9564 else 9565 { 9566 boolean chainError = false; 9567 final StringBuilder nonMatchReason = new StringBuilder(); 9568 for (int i=1; i < chain.length; i++) 9569 { 9570 if (! chain[i].isIssuerFor(chain[i-1], nonMatchReason)) 9571 { 9572 err(); 9573 wrapErr(0, WRAP_COLUMN, 9574 ERR_MANAGE_CERTS_CHECK_USABILITY_CHAIN_ISSUER_MISMATCH.get( 9575 alias, chain[i].getSubjectDN(), chain[i-1].getSubjectDN(), 9576 nonMatchReason)); 9577 numErrors++; 9578 chainError = true; 9579 } 9580 } 9581 9582 if (! chainError) 9583 { 9584 out(); 9585 wrapOut(0, WRAP_COLUMN, 9586 INFO_MANAGE_CERTS_CHECK_USABILITY_CHAIN_COMPLETE.get()); 9587 } 9588 } 9589 9590 9591 // If there are multiple certificates in the chain, and if the last 9592 // certificate in the chain is self-signed, then check to see if it is 9593 // contained in the JVM-default trust manager. If it isn't, then we'll 9594 // display a notice, but we won't consider it a warning in and of itself. 9595 if ((chain.length > 1) && chain[chain.length-1].isSelfSigned()) 9596 { 9597 final X509Certificate caCert = chain[chain.length-1]; 9598 9599 try 9600 { 9601 final String jvmDefaultTrustStoreType = 9602 inferKeystoreType(JVM_DEFAULT_CACERTS_FILE); 9603 final KeyStore jvmDefaultTrustStore = 9604 CryptoHelper.getKeyStore(jvmDefaultTrustStoreType); 9605 try (FileInputStream inputStream = 9606 new FileInputStream(JVM_DEFAULT_CACERTS_FILE)) 9607 { 9608 jvmDefaultTrustStore.load(inputStream, null); 9609 } 9610 9611 boolean found = false; 9612 final Enumeration<String> aliases = jvmDefaultTrustStore.aliases(); 9613 while (aliases.hasMoreElements()) 9614 { 9615 final String jvmDefaultCertAlias = aliases.nextElement(); 9616 if (jvmDefaultTrustStore.isCertificateEntry(jvmDefaultCertAlias)) 9617 { 9618 final Certificate c = 9619 jvmDefaultTrustStore.getCertificate(jvmDefaultCertAlias); 9620 final X509Certificate xc = new X509Certificate(c.getEncoded()); 9621 if ((caCert.getSubjectDN().equals(xc.getSubjectDN())) && 9622 Arrays.equals(caCert.getSignatureValue().getBits(), 9623 xc.getSignatureValue().getBits())) 9624 { 9625 found = true; 9626 break; 9627 } 9628 } 9629 } 9630 9631 if (found) 9632 { 9633 out(); 9634 wrapOut(0, WRAP_COLUMN, 9635 INFO_MANAGE_CERTS_CHECK_USABILITY_CA_TRUSTED_OK.get( 9636 caCert.getSubjectDN())); 9637 } 9638 else 9639 { 9640 out(); 9641 wrapOut(0, WRAP_COLUMN, 9642 INFO_MANAGE_CERTS_CHECK_USABILITY_CA_NOT_IN_JVM_DEFAULT_TS.get( 9643 caCert.getSubjectDN())); 9644 } 9645 } 9646 catch (final Exception e) 9647 { 9648 Debug.debugException(e); 9649 err(); 9650 wrapErr(0, WRAP_COLUMN, 9651 WARN_MANAGE_CERTS_CHECK_USABILITY_CHECK_CA_IN_TS_ERROR.get( 9652 caCert.getSubjectDN(), StaticUtils.getExceptionMessage(e))); 9653 numWarnings++; 9654 } 9655 } 9656 9657 9658 // Make sure that the signature is valid for each certificate in the 9659 // chain. If any certificate has an invalid signature, then that's an 9660 // error. 9661 for (int i=0; i < chain.length; i++) 9662 { 9663 final X509Certificate c = chain[i]; 9664 9665 try 9666 { 9667 if (c.isSelfSigned()) 9668 { 9669 c.verifySignature(null); 9670 } 9671 else if ((i + 1) < chain.length) 9672 { 9673 c.verifySignature(chain[i+1]); 9674 } 9675 9676 out(); 9677 wrapOut(0, WRAP_COLUMN, 9678 INFO_MANAGE_CERTS_CHECK_USABILITY_CERT_SIGNATURE_VALID.get( 9679 c.getSubjectDN())); 9680 } 9681 catch (final CertException ce) 9682 { 9683 err(); 9684 wrapErr(0, WRAP_COLUMN, ce.getMessage()); 9685 numErrors++; 9686 } 9687 } 9688 9689 9690 // Check the validity window for each certificate in the chain. If any of 9691 // them is expired or not yet valid, then that's an error. If any of them 9692 // will expire in the near future, then that's a warning. 9693 final long currentTime = System.currentTimeMillis(); 9694 final long thirtyDaysFromNow = 9695 currentTime + (30L * 24L * 60L * 60L * 1000L); 9696 for (int i=0; i < chain.length; i++) 9697 { 9698 final X509Certificate c = chain[i]; 9699 if (c.getNotBeforeTime() > currentTime) 9700 { 9701 err(); 9702 if (i == 0) 9703 { 9704 wrapErr(0, WRAP_COLUMN, 9705 ERR_MANAGE_CERTS_CHECK_USABILITY_END_CERT_NOT_YET_VALID.get( 9706 c.getSubjectDN(), formatDateAndTime(c.getNotBeforeDate()))); 9707 } 9708 else 9709 { 9710 wrapErr(0, WRAP_COLUMN, 9711 ERR_MANAGE_CERTS_CHECK_USABILITY_ISSUER_CERT_NOT_YET_VALID.get( 9712 c.getSubjectDN(), formatDateAndTime(c.getNotBeforeDate()))); 9713 } 9714 9715 numErrors++; 9716 } 9717 else if (c.getNotAfterTime() < currentTime) 9718 { 9719 err(); 9720 if (i == 0) 9721 { 9722 wrapErr(0, WRAP_COLUMN, 9723 ERR_MANAGE_CERTS_CHECK_USABILITY_END_CERT_EXPIRED.get( 9724 c.getSubjectDN(), formatDateAndTime(c.getNotAfterDate()))); 9725 } 9726 else 9727 { 9728 wrapErr(0, WRAP_COLUMN, 9729 ERR_MANAGE_CERTS_CHECK_USABILITY_ISSUER_CERT_EXPIRED.get( 9730 c.getSubjectDN(), formatDateAndTime(c.getNotAfterDate()))); 9731 } 9732 9733 numErrors++; 9734 } 9735 else if (c.getNotAfterTime() < thirtyDaysFromNow) 9736 { 9737 err(); 9738 if (i == 0) 9739 { 9740 wrapErr(0, WRAP_COLUMN, 9741 WARN_MANAGE_CERTS_CHECK_USABILITY_END_CERT_NEAR_EXPIRATION.get( 9742 c.getSubjectDN(), formatDateAndTime(c.getNotAfterDate()))); 9743 } 9744 else 9745 { 9746 wrapErr(0, WRAP_COLUMN, 9747 WARN_MANAGE_CERTS_CHECK_USABILITY_ISSUER_CERT_NEAR_EXPIRATION. 9748 get(c.getSubjectDN(), 9749 formatDateAndTime(c.getNotAfterDate()))); 9750 } 9751 9752 numWarnings++; 9753 } 9754 else 9755 { 9756 if (i == 0) 9757 { 9758 out(); 9759 wrapOut(0, WRAP_COLUMN, 9760 INFO_MANAGE_CERTS_CHECK_USABILITY_END_CERT_VALIDITY_OK.get( 9761 c.getSubjectDN(), formatDateAndTime(c.getNotAfterDate()))); 9762 } 9763 else 9764 { 9765 out(); 9766 wrapOut(0, WRAP_COLUMN, 9767 INFO_MANAGE_CERTS_CHECK_USABILITY_ISSUER_CERT_VALIDITY_OK.get( 9768 c.getSubjectDN(), formatDateAndTime(c.getNotAfterDate()))); 9769 } 9770 } 9771 } 9772 9773 9774 // Look at all of the extensions for all of the certificates and perform the 9775 // following validation: 9776 // - If the certificate at the head of the chain has an extended key usage 9777 // extension, then make sure it includes the serverAuth usage. If it 9778 // does not include an extended key usage extension, then warn that it 9779 // should. 9780 // - If any of the issuer certificates has a basic constraints extension, 9781 // then make sure it indicates that the associated certificate is a 9782 // certification authority. Further, if it has a path length constraint, 9783 // then make sure the chain does not exceed that length. If any issuer 9784 // certificate does not have a basic constraints extension, then warn that 9785 // it should. 9786 // - If any of the issuer certificates has a key usage extension, then 9787 // make sure it has the certSign usage. If any issuer certificate does 9788 // not have a key usage extension, then warn that it should. 9789 // - TODO: If any certificate has a CRL distribution points extension, then 9790 // retrieve the CRL and make sure the certificate hasn't been revoked. 9791 // - TODO: If any certificate has an authority information access 9792 // extension that points to an OCSP service, then consult that service to 9793 // determine whether the certificate has been revoked. 9794 for (int i=0; i < chain.length; i++) 9795 { 9796 boolean basicConstraintsFound = false; 9797 boolean extendedKeyUsageFound = false; 9798 boolean keyUsageFound = false; 9799 final X509Certificate c = chain[i]; 9800 for (final X509CertificateExtension extension : c.getExtensions()) 9801 { 9802 if (extension instanceof ExtendedKeyUsageExtension) 9803 { 9804 extendedKeyUsageFound = true; 9805 if (i == 0) 9806 { 9807 final ExtendedKeyUsageExtension e = 9808 (ExtendedKeyUsageExtension) extension; 9809 if (!e.getKeyPurposeIDs().contains( 9810 ExtendedKeyUsageID.TLS_SERVER_AUTHENTICATION.getOID())) 9811 { 9812 err(); 9813 wrapErr(0, WRAP_COLUMN, 9814 ERR_MANAGE_CERTS_CHECK_USABILITY_END_CERT_BAD_EKU.get( 9815 c.getSubjectDN())); 9816 numErrors++; 9817 } 9818 else 9819 { 9820 out(); 9821 wrapOut(0, WRAP_COLUMN, 9822 INFO_MANAGE_CERTS_CHECK_USABILITY_END_CERT_GOOD_EKU.get( 9823 c.getSubjectDN())); 9824 } 9825 } 9826 } 9827 else if (extension instanceof BasicConstraintsExtension) 9828 { 9829 basicConstraintsFound = true; 9830 if (i > 0) 9831 { 9832 final BasicConstraintsExtension e = 9833 (BasicConstraintsExtension) extension; 9834 if (!e.isCA()) 9835 { 9836 err(); 9837 wrapErr(0, WRAP_COLUMN, 9838 ERR_MANAGE_CERTS_CHECK_USABILITY_ISSUER_CERT_BAD_BC_CA.get( 9839 c.getSubjectDN())); 9840 numErrors++; 9841 } 9842 else if ((e.getPathLengthConstraint() != null) && 9843 ((i - 1) > e.getPathLengthConstraint())) 9844 { 9845 err(); 9846 wrapErr(0, WRAP_COLUMN, 9847 ERR_MANAGE_CERTS_CHECK_USABILITY_ISSUER_CERT_BAD_BC_LENGTH. 9848 get(c.getSubjectDN(), e.getPathLengthConstraint(), 9849 chain[0].getSubjectDN(), (i-1))); 9850 numErrors++; 9851 } 9852 else 9853 { 9854 out(); 9855 wrapOut(0, WRAP_COLUMN, 9856 INFO_MANAGE_CERTS_CHECK_USABILITY_ISSUER_CERT_GOOD_BC.get( 9857 c.getSubjectDN())); 9858 } 9859 } 9860 } 9861 else if (extension instanceof KeyUsageExtension) 9862 { 9863 keyUsageFound = true; 9864 if (i > 0) 9865 { 9866 final KeyUsageExtension e = (KeyUsageExtension) extension; 9867 if (! e.isKeyCertSignBitSet()) 9868 { 9869 err(); 9870 wrapErr(0, WRAP_COLUMN, 9871 ERR_MANAGE_CERTS_CHECK_USABILITY_ISSUER_NO_CERT_SIGN_KU.get( 9872 c.getSubjectDN())); 9873 numErrors++; 9874 } 9875 else 9876 { 9877 out(); 9878 wrapOut(0, WRAP_COLUMN, 9879 INFO_MANAGE_CERTS_CHECK_USABILITY_ISSUER_GOOD_KU.get( 9880 c.getSubjectDN())); 9881 } 9882 } 9883 } 9884 } 9885 9886 if (i == 0) 9887 { 9888 if (! extendedKeyUsageFound) 9889 { 9890 err(); 9891 wrapErr(0, WRAP_COLUMN, 9892 WARN_MANAGE_CERTS_CHECK_USABILITY_NO_EKU.get( 9893 c.getSubjectDN())); 9894 numWarnings++; 9895 } 9896 } 9897 else 9898 { 9899 if (! basicConstraintsFound) 9900 { 9901 err(); 9902 wrapErr(0, WRAP_COLUMN, 9903 WARN_MANAGE_CERTS_CHECK_USABILITY_NO_BC.get( 9904 c.getSubjectDN())); 9905 numWarnings++; 9906 } 9907 9908 if (! keyUsageFound) 9909 { 9910 err(); 9911 wrapErr(0, WRAP_COLUMN, 9912 WARN_MANAGE_CERTS_CHECK_USABILITY_NO_KU.get( 9913 c.getSubjectDN())); 9914 numWarnings++; 9915 } 9916 } 9917 } 9918 9919 9920 // Make sure that none of the certificates has a signature algorithm that 9921 // uses MD5 or SHA-1. If it uses an unrecognized signature algorithm, then 9922 // that's a warning. 9923 boolean isIssuer = false; 9924 final BooleanArgument ignoreSHA1WarningArg = 9925 subCommandParser.getBooleanArgument( 9926 "allow-sha-1-signature-for-issuer-certificates"); 9927 final boolean ignoreSHA1SignatureWarningForIssuerCertificates = 9928 ((ignoreSHA1WarningArg != null) && ignoreSHA1WarningArg.isPresent()); 9929 for (final X509Certificate c : chain) 9930 { 9931 final OID signatureAlgorithmOID = c.getSignatureAlgorithmOID(); 9932 final SignatureAlgorithmIdentifier id = 9933 SignatureAlgorithmIdentifier.forOID(signatureAlgorithmOID); 9934 if (id == null) 9935 { 9936 err(); 9937 wrapErr(0, WRAP_COLUMN, 9938 WARN_MANAGE_CERTS_CHECK_USABILITY_UNKNOWN_SIG_ALG.get( 9939 c.getSubjectDN(), signatureAlgorithmOID)); 9940 numWarnings++; 9941 } 9942 else 9943 { 9944 switch (id) 9945 { 9946 case MD2_WITH_RSA: 9947 case MD5_WITH_RSA: 9948 err(); 9949 wrapErr(0, WRAP_COLUMN, 9950 ERR_MANAGE_CERTS_CHECK_USABILITY_WEAK_SIG_ALG.get( 9951 c.getSubjectDN(), id.getUserFriendlyName())); 9952 numErrors++; 9953 break; 9954 9955 case SHA_1_WITH_RSA: 9956 case SHA_1_WITH_DSA: 9957 case SHA_1_WITH_ECDSA: 9958 if (isIssuer && ignoreSHA1SignatureWarningForIssuerCertificates) 9959 { 9960 err(); 9961 wrapErr(0, WRAP_COLUMN, 9962 WARN_MANAGE_CERTS_CHECK_USABILITY_ISSUER_WITH_SHA1_SIG.get( 9963 c.getSubjectDN(), id.getUserFriendlyName(), 9964 ignoreSHA1WarningArg.getIdentifierString())); 9965 } 9966 else 9967 { 9968 err(); 9969 wrapErr(0, WRAP_COLUMN, 9970 ERR_MANAGE_CERTS_CHECK_USABILITY_WEAK_SIG_ALG.get( 9971 c.getSubjectDN(), id.getUserFriendlyName())); 9972 numErrors++; 9973 } 9974 break; 9975 9976 case SHA_224_WITH_RSA: 9977 case SHA_224_WITH_DSA: 9978 case SHA_224_WITH_ECDSA: 9979 case SHA_256_WITH_RSA: 9980 case SHA_256_WITH_DSA: 9981 case SHA_256_WITH_ECDSA: 9982 case SHA_384_WITH_RSA: 9983 case SHA_384_WITH_ECDSA: 9984 case SHA_512_WITH_RSA: 9985 case SHA_512_WITH_ECDSA: 9986 out(); 9987 wrapOut(0, WRAP_COLUMN, 9988 INFO_MANAGE_CERTS_CHECK_USABILITY_SIG_ALG_OK.get( 9989 c.getSubjectDN(), id.getUserFriendlyName())); 9990 break; 9991 } 9992 } 9993 9994 isIssuer = true; 9995 } 9996 9997 9998 // Make sure that none of the certificates that uses the RSA key algorithm 9999 // has a public modulus size smaller than 2048 bits. 10000 for (final X509Certificate c : chain) 10001 { 10002 if ((c.getDecodedPublicKey() != null) && 10003 (c.getDecodedPublicKey() instanceof RSAPublicKey)) 10004 { 10005 final RSAPublicKey rsaPublicKey = 10006 (RSAPublicKey) c.getDecodedPublicKey(); 10007 final byte[] modulusBytes = rsaPublicKey.getModulus().toByteArray(); 10008 int modulusSizeBits = modulusBytes.length * 8; 10009 if (((modulusBytes.length % 2) != 0) && (modulusBytes[0] == 0x00)) 10010 { 10011 modulusSizeBits -= 8; 10012 } 10013 10014 if (modulusSizeBits < 2048) 10015 { 10016 err(); 10017 wrapErr(0, WRAP_COLUMN, 10018 ERR_MANAGE_CERTS_CHECK_USABILITY_WEAK_RSA_MODULUS.get( 10019 c.getSubjectDN(), modulusSizeBits)); 10020 numErrors++; 10021 } 10022 else 10023 { 10024 out(); 10025 wrapOut(0, WRAP_COLUMN, 10026 INFO_MANAGE_CERTS_CHECK_USABILITY_RSA_MODULUS_OK.get( 10027 c.getSubjectDN(), modulusSizeBits)); 10028 } 10029 } 10030 } 10031 10032 10033 switch (numErrors) 10034 { 10035 case 0: 10036 break; 10037 case 1: 10038 err(); 10039 wrapErr(0, WRAP_COLUMN, 10040 ERR_MANAGE_CERTS_CHECK_USABILITY_ONE_ERROR.get()); 10041 return ResultCode.PARAM_ERROR; 10042 default: 10043 err(); 10044 wrapErr(0, WRAP_COLUMN, 10045 ERR_MANAGE_CERTS_CHECK_USABILITY_MULTIPLE_ERRORS.get(numErrors)); 10046 return ResultCode.PARAM_ERROR; 10047 } 10048 10049 switch (numWarnings) 10050 { 10051 case 0: 10052 out(); 10053 wrapOut(0, WRAP_COLUMN, 10054 INFO_MANAGE_CERTS_CHECK_USABILITY_NO_ERRORS_OR_WARNINGS.get()); 10055 return ResultCode.SUCCESS; 10056 case 1: 10057 err(); 10058 wrapErr(0, WRAP_COLUMN, 10059 ERR_MANAGE_CERTS_CHECK_USABILITY_ONE_WARNING.get()); 10060 return ResultCode.PARAM_ERROR; 10061 default: 10062 err(); 10063 wrapErr(0, WRAP_COLUMN, 10064 ERR_MANAGE_CERTS_CHECK_USABILITY_MULTIPLE_WARNINGS.get( 10065 numWarnings)); 10066 return ResultCode.PARAM_ERROR; 10067 } 10068 } 10069 10070 10071 10072 /** 10073 * Performs the necessary processing for the display-certificate-file 10074 * subcommand. 10075 * 10076 * @return A result code that indicates whether the processing completed 10077 * successfully. 10078 */ 10079 @NotNull() 10080 private ResultCode doDisplayCertificateFile() 10081 { 10082 // Get the values of a number of configured arguments. 10083 final FileArgument certificateFileArgument = 10084 subCommandParser.getFileArgument("certificate-file"); 10085 final File certificateFile = certificateFileArgument.getValue(); 10086 10087 final BooleanArgument verboseArgument = 10088 subCommandParser.getBooleanArgument("verbose"); 10089 final boolean verbose = 10090 ((verboseArgument != null) && verboseArgument.isPresent()); 10091 10092 final BooleanArgument displayKeytoolCommandArgument = 10093 subCommandParser.getBooleanArgument("display-keytool-command"); 10094 if ((displayKeytoolCommandArgument != null) && 10095 displayKeytoolCommandArgument.isPresent()) 10096 { 10097 final ArrayList<String> keytoolArgs = new ArrayList<>(10); 10098 keytoolArgs.add("-printcert"); 10099 keytoolArgs.add("-file"); 10100 keytoolArgs.add(certificateFile.getAbsolutePath()); 10101 10102 if (verbose) 10103 { 10104 keytoolArgs.add("-v"); 10105 } 10106 10107 displayKeytoolCommand(keytoolArgs); 10108 } 10109 10110 10111 // Read the certificates from the specified file. 10112 final List<X509Certificate> certificates; 10113 try 10114 { 10115 certificates = readCertificatesFromFile(certificateFile); 10116 } 10117 catch (final LDAPException le) 10118 { 10119 Debug.debugException(le); 10120 wrapErr(0, WRAP_COLUMN, le.getMessage()); 10121 return le.getResultCode(); 10122 } 10123 10124 10125 // If there aren't any certificates in the file, print that. 10126 if (certificates.isEmpty()) 10127 { 10128 wrapOut(0, WRAP_COLUMN, INFO_MANAGE_CERTS_DISPLAY_CERT_NO_CERTS.get( 10129 certificateFile.getAbsolutePath())); 10130 } 10131 else 10132 { 10133 for (final X509Certificate c : certificates) 10134 { 10135 out(); 10136 printCertificate(c, "", verbose); 10137 } 10138 } 10139 10140 return ResultCode.SUCCESS; 10141 } 10142 10143 10144 10145 /** 10146 * Performs the necessary processing for the 10147 * display-certificate-signing-request-file subcommand. 10148 * 10149 * @return A result code that indicates whether the processing completed 10150 * successfully. 10151 */ 10152 @NotNull() 10153 private ResultCode doDisplayCertificateSigningRequestFile() 10154 { 10155 // Get the values of a number of configured arguments. 10156 final FileArgument csrFileArgument = 10157 subCommandParser.getFileArgument("certificate-signing-request-file"); 10158 final File csrFile = csrFileArgument.getValue(); 10159 10160 final BooleanArgument verboseArgument = 10161 subCommandParser.getBooleanArgument("verbose"); 10162 final boolean verbose = 10163 ((verboseArgument != null) && verboseArgument.isPresent()); 10164 10165 final BooleanArgument displayKeytoolCommandArgument = 10166 subCommandParser.getBooleanArgument("display-keytool-command"); 10167 if ((displayKeytoolCommandArgument != null) && 10168 displayKeytoolCommandArgument.isPresent()) 10169 { 10170 final ArrayList<String> keytoolArgs = new ArrayList<>(10); 10171 keytoolArgs.add("-printcertreq"); 10172 keytoolArgs.add("-file"); 10173 keytoolArgs.add(csrFile.getAbsolutePath()); 10174 keytoolArgs.add("-v"); 10175 10176 displayKeytoolCommand(keytoolArgs); 10177 } 10178 10179 10180 // Read the certificate signing request from the specified file. 10181 final PKCS10CertificateSigningRequest csr; 10182 try 10183 { 10184 csr = readCertificateSigningRequestFromFile(csrFile); 10185 } 10186 catch (final LDAPException le) 10187 { 10188 Debug.debugException(le); 10189 wrapErr(0, WRAP_COLUMN, le.getMessage()); 10190 return le.getResultCode(); 10191 } 10192 10193 out(); 10194 printCertificateSigningRequest(csr, verbose, ""); 10195 10196 return ResultCode.SUCCESS; 10197 } 10198 10199 10200 10201 /** 10202 * Prints a string representation of the provided certificate to standard 10203 * output. 10204 * 10205 * @param certificate The certificate to be printed. 10206 * @param indent The string to place at the beginning of each line to 10207 * indent that line. 10208 * @param verbose Indicates whether to display verbose information about 10209 * the certificate. 10210 */ 10211 private void printCertificate(@NotNull final X509Certificate certificate, 10212 @NotNull final String indent, 10213 final boolean verbose) 10214 { 10215 if (verbose) 10216 { 10217 out(indent + 10218 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_VERSION.get( 10219 certificate.getVersion().getName())); 10220 } 10221 10222 out(indent + 10223 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_SUBJECT_DN.get( 10224 certificate.getSubjectDN())); 10225 out(indent + 10226 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_ISSUER_DN.get( 10227 certificate.getIssuerDN())); 10228 10229 if (verbose) 10230 { 10231 out(indent + 10232 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_SERIAL_NUMBER.get( 10233 toColonDelimitedHex( 10234 certificate.getSerialNumber().toByteArray()))); 10235 } 10236 10237 out(indent + 10238 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_VALIDITY_START.get( 10239 formatDateAndTime(certificate.getNotBeforeDate()))); 10240 out(indent + 10241 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_VALIDITY_END.get( 10242 formatDateAndTime(certificate.getNotAfterDate()))); 10243 10244 final long currentTime = System.currentTimeMillis(); 10245 if (currentTime < certificate.getNotBeforeTime()) 10246 { 10247 out(indent + 10248 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_VALIDITY_STATE_NOT_YET_VALID. 10249 get()); 10250 } 10251 else if (currentTime > certificate.getNotAfterTime()) 10252 { 10253 out(indent + 10254 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_VALIDITY_STATE_EXPIRED.get()); 10255 } 10256 else 10257 { 10258 out(indent + 10259 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_VALIDITY_STATE_VALID.get()); 10260 } 10261 10262 out(indent + 10263 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_SIG_ALG.get( 10264 certificate.getSignatureAlgorithmNameOrOID())); 10265 if (verbose) 10266 { 10267 String signatureString; 10268 try 10269 { 10270 signatureString = 10271 toColonDelimitedHex(certificate.getSignatureValue().getBytes()); 10272 } 10273 catch (final Exception e) 10274 { 10275 Debug.debugException(e); 10276 signatureString = certificate.getSignatureValue().toString(); 10277 } 10278 out(indent + 10279 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_SIG_VALUE.get()); 10280 for (final String line : StaticUtils.wrapLine(signatureString, 78)) 10281 { 10282 out(indent + " " + line); 10283 } 10284 } 10285 10286 final String pkAlg; 10287 final String pkSummary = getPublicKeySummary( 10288 certificate.getPublicKeyAlgorithmOID(), 10289 certificate.getDecodedPublicKey(), 10290 certificate.getPublicKeyAlgorithmParameters()); 10291 if (pkSummary == null) 10292 { 10293 pkAlg = certificate.getPublicKeyAlgorithmNameOrOID(); 10294 } 10295 else 10296 { 10297 pkAlg = certificate.getPublicKeyAlgorithmNameOrOID() + " (" + 10298 pkSummary + ')'; 10299 } 10300 out(indent + INFO_MANAGE_CERTS_PRINT_CERT_LABEL_PK_ALG.get(pkAlg)); 10301 10302 if (verbose) 10303 { 10304 printPublicKey(certificate.getEncodedPublicKey(), 10305 certificate.getDecodedPublicKey(), 10306 certificate.getPublicKeyAlgorithmParameters(), indent); 10307 10308 if (certificate.getSubjectUniqueID() != null) 10309 { 10310 String subjectUniqueID; 10311 try 10312 { 10313 subjectUniqueID = toColonDelimitedHex( 10314 certificate.getSubjectUniqueID().getBytes()); 10315 } 10316 catch (final Exception e) 10317 { 10318 Debug.debugException(e); 10319 subjectUniqueID = certificate.getSubjectUniqueID().toString(); 10320 } 10321 10322 out(indent + 10323 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_SUBJECT_UNIQUE_ID.get()); 10324 for (final String line : StaticUtils.wrapLine(subjectUniqueID, 78)) 10325 { 10326 out(indent + " " + line); 10327 } 10328 } 10329 10330 if (certificate.getIssuerUniqueID() != null) 10331 { 10332 String issuerUniqueID; 10333 try 10334 { 10335 issuerUniqueID = toColonDelimitedHex( 10336 certificate.getIssuerUniqueID().getBytes()); 10337 } 10338 catch (final Exception e) 10339 { 10340 Debug.debugException(e); 10341 issuerUniqueID = certificate.getIssuerUniqueID().toString(); 10342 } 10343 10344 out(indent + 10345 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_ISSUER_UNIQUE_ID.get()); 10346 for (final String line : StaticUtils.wrapLine(issuerUniqueID, 78)) 10347 { 10348 out(indent + " " + line); 10349 } 10350 } 10351 10352 printExtensions(certificate.getExtensions(), indent); 10353 } 10354 10355 try 10356 { 10357 out(indent + 10358 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_FINGERPRINT.get("SHA-1", 10359 toColonDelimitedHex(certificate.getSHA1Fingerprint()))); 10360 } 10361 catch (final Exception e) 10362 { 10363 Debug.debugException(e); 10364 } 10365 10366 try 10367 { 10368 out(indent + 10369 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_FINGERPRINT.get("SHA-256", 10370 toColonDelimitedHex(certificate.getSHA256Fingerprint()))); 10371 } 10372 catch (final Exception e) 10373 { 10374 Debug.debugException(e); 10375 } 10376 } 10377 10378 10379 10380 /** 10381 * Prints a string representation of the provided certificate signing request 10382 * to standard output. 10383 * 10384 * @param csr The certificate signing request to be printed. 10385 * @param verbose Indicates whether to display verbose information about 10386 * the contents of the request. 10387 * @param indent The string to place at the beginning of each line to 10388 * indent that line. 10389 */ 10390 private void printCertificateSigningRequest( 10391 @NotNull final PKCS10CertificateSigningRequest csr, 10392 final boolean verbose, @NotNull final String indent) 10393 { 10394 out(indent + 10395 INFO_MANAGE_CERTS_PRINT_CSR_LABEL_VERSION.get( 10396 csr.getVersion().getName())); 10397 out(indent + 10398 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_SUBJECT_DN.get( 10399 csr.getSubjectDN())); 10400 out(indent + 10401 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_SIG_ALG.get( 10402 csr.getSignatureAlgorithmNameOrOID())); 10403 10404 if (verbose) 10405 { 10406 String signatureString; 10407 try 10408 { 10409 signatureString = 10410 toColonDelimitedHex(csr.getSignatureValue().getBytes()); 10411 } 10412 catch (final Exception e) 10413 { 10414 Debug.debugException(e); 10415 signatureString = csr.getSignatureValue().toString(); 10416 } 10417 out(indent + 10418 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_SIG_VALUE.get()); 10419 for (final String line : StaticUtils.wrapLine(signatureString, 78)) 10420 { 10421 out(indent + " " + line); 10422 } 10423 } 10424 10425 final String pkAlg; 10426 final String pkSummary = getPublicKeySummary(csr.getPublicKeyAlgorithmOID(), 10427 csr.getDecodedPublicKey(), csr.getPublicKeyAlgorithmParameters()); 10428 if (pkSummary == null) 10429 { 10430 pkAlg = csr.getPublicKeyAlgorithmNameOrOID(); 10431 } 10432 else 10433 { 10434 pkAlg = csr.getPublicKeyAlgorithmNameOrOID() + " (" + 10435 pkSummary + ')'; 10436 } 10437 out(indent + INFO_MANAGE_CERTS_PRINT_CERT_LABEL_PK_ALG.get(pkAlg)); 10438 10439 if (verbose) 10440 { 10441 printPublicKey(csr.getEncodedPublicKey(), csr.getDecodedPublicKey(), 10442 csr.getPublicKeyAlgorithmParameters(), indent); 10443 printExtensions(csr.getExtensions(), indent); 10444 } 10445 } 10446 10447 10448 10449 /** 10450 * Prints information about the provided public key. 10451 * 10452 * @param encodedPublicKey The encoded representation of the public key. 10453 * This must not be {@code null}. 10454 * @param decodedPublicKey The decoded representation of the public key, if 10455 * available. 10456 * @param parameters The public key algorithm parameters, if any. 10457 * @param indent The string to place at the beginning of each 10458 * line to indent that line. 10459 */ 10460 private void printPublicKey(@NotNull final ASN1BitString encodedPublicKey, 10461 @Nullable final DecodedPublicKey decodedPublicKey, 10462 @Nullable final ASN1Element parameters, 10463 @NotNull final String indent) 10464 { 10465 if (decodedPublicKey == null) 10466 { 10467 String pkString; 10468 try 10469 { 10470 pkString = toColonDelimitedHex(encodedPublicKey.getBytes()); 10471 } 10472 catch (final Exception e) 10473 { 10474 Debug.debugException(e); 10475 pkString = encodedPublicKey.toString(); 10476 } 10477 10478 out(indent + INFO_MANAGE_CERTS_PRINT_CERT_LABEL_ENCODED_PK.get()); 10479 for (final String line : StaticUtils.wrapLine(pkString, 78)) 10480 { 10481 out(indent + " " + line); 10482 } 10483 10484 return; 10485 } 10486 10487 if (decodedPublicKey instanceof RSAPublicKey) 10488 { 10489 final RSAPublicKey rsaPublicKey = (RSAPublicKey) decodedPublicKey; 10490 final byte[] modulusBytes = rsaPublicKey.getModulus().toByteArray(); 10491 10492 int modulusSizeBits = modulusBytes.length * 8; 10493 if (((modulusBytes.length % 2) != 0) && (modulusBytes[0] == 0x00)) 10494 { 10495 modulusSizeBits -= 8; 10496 } 10497 10498 out(indent + 10499 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_RSA_MODULUS.get( 10500 modulusSizeBits)); 10501 final String modulusHex = toColonDelimitedHex(modulusBytes); 10502 for (final String line : StaticUtils.wrapLine(modulusHex, 78)) 10503 { 10504 out(indent + " " + line); 10505 } 10506 10507 out(indent + 10508 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_RSA_EXPONENT.get( 10509 toColonDelimitedHex( 10510 rsaPublicKey.getPublicExponent().toByteArray()))); 10511 } 10512 else if (decodedPublicKey instanceof EllipticCurvePublicKey) 10513 { 10514 final EllipticCurvePublicKey ecPublicKey = 10515 (EllipticCurvePublicKey) decodedPublicKey; 10516 10517 out(indent + 10518 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EC_IS_COMPRESSED.get( 10519 String.valueOf(ecPublicKey.usesCompressedForm()))); 10520 out(indent + 10521 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EC_X.get( 10522 String.valueOf(ecPublicKey.getXCoordinate()))); 10523 if (ecPublicKey.getYCoordinate() == null) 10524 { 10525 out(indent + 10526 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EC_Y_IS_EVEN.get( 10527 String.valueOf(ecPublicKey.yCoordinateIsEven()))); 10528 } 10529 else 10530 { 10531 out(indent + 10532 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EC_Y.get( 10533 String.valueOf(ecPublicKey.getYCoordinate()))); 10534 } 10535 } 10536 } 10537 10538 10539 10540 /** 10541 * Retrieves a short summary of the provided public key, if available. For 10542 * RSA keys, this will be the modulus size in bits. For elliptic curve keys, 10543 * this will be the named curve, if available. 10544 * 10545 * @param publicKeyAlgorithmOID The OID that identifies the type of public 10546 * key. 10547 * @param publicKey The decoded public key. This may be 10548 * {@code null} if the decoded public key is 10549 * not available. 10550 * @param parameters The encoded public key algorithm parameters. 10551 * This may be {@code null} if no public key 10552 * algorithm parameters are available. 10553 * 10554 * @return A short summary of the provided public key, or {@code null} if 10555 * no summary is available. 10556 */ 10557 @NotNull() 10558 private static String getPublicKeySummary( 10559 @NotNull final OID publicKeyAlgorithmOID, 10560 @Nullable final DecodedPublicKey publicKey, 10561 @Nullable final ASN1Element parameters) 10562 { 10563 if (publicKey instanceof RSAPublicKey) 10564 { 10565 final RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey; 10566 final byte[] modulusBytes = rsaPublicKey.getModulus().toByteArray(); 10567 10568 int modulusSizeBits = modulusBytes.length * 8; 10569 if (((modulusBytes.length % 2) != 0) && (modulusBytes[0] == 0x00)) 10570 { 10571 modulusSizeBits -= 8; 10572 } 10573 10574 return INFO_MANAGE_CERTS_GET_PK_SUMMARY_RSA_MODULUS_SIZE.get( 10575 modulusSizeBits); 10576 } 10577 else if ((parameters != null) && 10578 publicKeyAlgorithmOID.equals(PublicKeyAlgorithmIdentifier.EC.getOID())) 10579 { 10580 try 10581 { 10582 final OID namedCurveOID = 10583 parameters.decodeAsObjectIdentifier().getOID(); 10584 return NamedCurve.getNameOrOID(namedCurveOID); 10585 } 10586 catch (final Exception e) 10587 { 10588 Debug.debugException(e); 10589 } 10590 } 10591 10592 return null; 10593 } 10594 10595 10596 10597 /** 10598 * Prints information about the provided extensions. 10599 * 10600 * @param extensions The list of extensions to be printed. 10601 * @param indent The string to place at the beginning of each line to 10602 * indent that line. 10603 */ 10604 void printExtensions(@NotNull final List<X509CertificateExtension> extensions, 10605 @NotNull final String indent) 10606 { 10607 if (extensions.isEmpty()) 10608 { 10609 return; 10610 } 10611 10612 out(indent + INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXTENSIONS.get()); 10613 for (final X509CertificateExtension extension : extensions) 10614 { 10615 if (extension instanceof AuthorityKeyIdentifierExtension) 10616 { 10617 out(indent + " " + 10618 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_AUTH_KEY_ID_EXT.get()); 10619 out(indent + " " + 10620 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_OID.get( 10621 extension.getOID().toString())); 10622 out(indent + " " + 10623 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IS_CRITICAL.get( 10624 String.valueOf(extension.isCritical()))); 10625 10626 final AuthorityKeyIdentifierExtension e = 10627 (AuthorityKeyIdentifierExtension) extension; 10628 if (e.getKeyIdentifier() != null) 10629 { 10630 out(indent + " " + 10631 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_AUTH_KEY_ID_ID.get()); 10632 final String idHex = 10633 toColonDelimitedHex(e.getKeyIdentifier().getValue()); 10634 for (final String line : StaticUtils.wrapLine(idHex, 78)) 10635 { 10636 out(indent + " " + line); 10637 } 10638 } 10639 10640 if (e.getAuthorityCertIssuer() != null) 10641 { 10642 out(indent + " " + 10643 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_AUTH_KEY_ID_ISSUER. 10644 get()); 10645 printGeneralNames(e.getAuthorityCertIssuer(), 10646 indent + " "); 10647 } 10648 10649 if (e.getAuthorityCertSerialNumber() != null) 10650 { 10651 out(indent + " " + 10652 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_AUTH_KEY_ID_SERIAL.get( 10653 toColonDelimitedHex(e.getAuthorityCertSerialNumber(). 10654 toByteArray()))); 10655 } 10656 } 10657 else if (extension instanceof BasicConstraintsExtension) 10658 { 10659 out(indent + " " + 10660 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_BASIC_CONST_EXT.get()); 10661 out(indent + " " + 10662 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_OID.get( 10663 extension.getOID().toString())); 10664 out(indent + " " + 10665 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IS_CRITICAL.get( 10666 String.valueOf(extension.isCritical()))); 10667 10668 final BasicConstraintsExtension e = 10669 (BasicConstraintsExtension) extension; 10670 out(indent + " " + 10671 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_BASIC_CONST_IS_CA.get( 10672 String.valueOf(e.isCA()))); 10673 10674 if (e.getPathLengthConstraint() != null) 10675 { 10676 out(indent + " " + 10677 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_BASIC_CONST_LENGTH.get( 10678 e.getPathLengthConstraint())); 10679 } 10680 } 10681 else if (extension instanceof CRLDistributionPointsExtension) 10682 { 10683 out(indent + " " + 10684 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_CRL_DP_EXT.get()); 10685 out(indent + " " + 10686 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_OID.get( 10687 extension.getOID().toString())); 10688 out(indent + " " + 10689 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IS_CRITICAL.get( 10690 String.valueOf(extension.isCritical()))); 10691 10692 final CRLDistributionPointsExtension crlDPE = 10693 (CRLDistributionPointsExtension) extension; 10694 for (final CRLDistributionPoint dp : 10695 crlDPE.getCRLDistributionPoints()) 10696 { 10697 out(indent + " " + 10698 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_CRL_DP_HEADER.get()); 10699 if (dp.getFullName() != null) 10700 { 10701 out(indent + " " + 10702 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_CRL_DP_FULL_NAME. 10703 get()); 10704 printGeneralNames(dp.getFullName(), 10705 indent + " "); 10706 } 10707 10708 if (dp.getNameRelativeToCRLIssuer() != null) 10709 { 10710 out(indent + " " + 10711 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_CRL_DP_REL_NAME.get( 10712 dp.getNameRelativeToCRLIssuer())); 10713 } 10714 10715 if (! dp.getPotentialRevocationReasons().isEmpty()) 10716 { 10717 out(indent + " " + 10718 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_CRL_DP_REASON.get()); 10719 for (final CRLDistributionPointRevocationReason r : 10720 dp.getPotentialRevocationReasons()) 10721 { 10722 out(indent + " " + r.getName()); 10723 } 10724 } 10725 10726 if (dp.getCRLIssuer() != null) 10727 { 10728 out(indent + " " + 10729 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_CRL_DP_CRL_ISSUER. 10730 get()); 10731 printGeneralNames(dp.getCRLIssuer(), 10732 indent + " "); 10733 } 10734 } 10735 } 10736 else if (extension instanceof ExtendedKeyUsageExtension) 10737 { 10738 out(indent + " " + 10739 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_EKU_EXT.get()); 10740 out(indent + " " + 10741 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_OID.get( 10742 extension.getOID().toString())); 10743 out(indent + " " + 10744 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IS_CRITICAL.get( 10745 String.valueOf(extension.isCritical()))); 10746 10747 final ExtendedKeyUsageExtension e = 10748 (ExtendedKeyUsageExtension) extension; 10749 for (final OID oid : e.getKeyPurposeIDs()) 10750 { 10751 final ExtendedKeyUsageID id = ExtendedKeyUsageID.forOID(oid); 10752 if (id == null) 10753 { 10754 out(indent + " " + 10755 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_EKU_ID.get(oid)); 10756 } 10757 else 10758 { 10759 out(indent + " " + 10760 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_EKU_ID.get( 10761 id.getName())); 10762 } 10763 } 10764 } 10765 else if (extension instanceof IssuerAlternativeNameExtension) 10766 { 10767 out(indent + " " + 10768 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IAN_EXT.get()); 10769 out(indent + " " + 10770 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_OID.get( 10771 extension.getOID().toString())); 10772 out(indent + " " + 10773 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IS_CRITICAL.get( 10774 String.valueOf(extension.isCritical()))); 10775 10776 final IssuerAlternativeNameExtension e = 10777 (IssuerAlternativeNameExtension) extension; 10778 printGeneralNames(e.getGeneralNames(), indent + " "); 10779 } 10780 else if (extension instanceof KeyUsageExtension) 10781 { 10782 out(indent + " " + 10783 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_EXT.get()); 10784 out(indent + " " + 10785 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_OID.get( 10786 extension.getOID().toString())); 10787 out(indent + " " + 10788 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IS_CRITICAL.get( 10789 String.valueOf(extension.isCritical()))); 10790 10791 out(indent + " " + 10792 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_USAGES.get()); 10793 final KeyUsageExtension kue = (KeyUsageExtension) extension; 10794 if (kue.isDigitalSignatureBitSet()) 10795 { 10796 out(indent + " " + 10797 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_DS.get()); 10798 } 10799 10800 if (kue.isNonRepudiationBitSet()) 10801 { 10802 out(indent + " " + 10803 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_NR.get()); 10804 } 10805 10806 if (kue.isKeyEnciphermentBitSet()) 10807 { 10808 out(indent + " " + 10809 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_KE.get()); 10810 } 10811 10812 if (kue.isDataEnciphermentBitSet()) 10813 { 10814 out(indent + " " + 10815 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_DE.get()); 10816 } 10817 10818 if (kue.isKeyAgreementBitSet()) 10819 { 10820 out(indent + " " + 10821 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_KA.get()); 10822 } 10823 10824 if (kue.isKeyCertSignBitSet()) 10825 { 10826 out(indent + " " + 10827 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_KCS.get()); 10828 } 10829 10830 if (kue.isCRLSignBitSet()) 10831 { 10832 out(indent + " " + 10833 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_CRL_SIGN.get()); 10834 } 10835 10836 if (kue.isEncipherOnlyBitSet()) 10837 { 10838 out(indent + " " + 10839 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_EO.get()); 10840 } 10841 10842 if (kue.isDecipherOnlyBitSet()) 10843 { 10844 out(indent + " " + 10845 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_KU_DO.get()); 10846 } 10847 } 10848 else if (extension instanceof SubjectAlternativeNameExtension) 10849 { 10850 out(indent + " " + 10851 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_SAN_EXT.get()); 10852 out(indent + " " + 10853 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_OID.get( 10854 extension.getOID().toString())); 10855 out(indent + " " + 10856 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IS_CRITICAL.get( 10857 String.valueOf(extension.isCritical()))); 10858 10859 final SubjectAlternativeNameExtension e = 10860 (SubjectAlternativeNameExtension) extension; 10861 printGeneralNames(e.getGeneralNames(), indent + " "); 10862 } 10863 else if (extension instanceof SubjectKeyIdentifierExtension) 10864 { 10865 out(indent + " " + 10866 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_SKI_EXT.get()); 10867 out(indent + " " + 10868 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_OID.get( 10869 extension.getOID().toString())); 10870 out(indent + " " + 10871 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IS_CRITICAL.get( 10872 String.valueOf(extension.isCritical()))); 10873 10874 final SubjectKeyIdentifierExtension e = 10875 (SubjectKeyIdentifierExtension) extension; 10876 final String idHex = 10877 toColonDelimitedHex(e.getKeyIdentifier().getValue()); 10878 out(indent + " " + 10879 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_SKI_ID.get()); 10880 for (final String line : StaticUtils.wrapLine(idHex, 78)) 10881 { 10882 out(indent + " " + line); 10883 } 10884 } 10885 else 10886 { 10887 out(indent + " " + 10888 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_GENERIC.get()); 10889 out(indent + " " + 10890 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_OID.get( 10891 extension.getOID().toString())); 10892 out(indent + " " + 10893 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_IS_CRITICAL.get( 10894 String.valueOf(extension.isCritical()))); 10895 10896 final String valueHex = toColonDelimitedHex(extension.getValue()); 10897 out(indent + " " + 10898 INFO_MANAGE_CERTS_PRINT_CERT_LABEL_EXT_VALUE.get()); 10899 getOut().print(StaticUtils.toHexPlusASCII(extension.getValue(), 10900 (indent.length() + 15))); 10901 } 10902 } 10903 } 10904 10905 10906 10907 /** 10908 * Prints information about the contents of the provided general names object. 10909 * 10910 * @param generalNames The general names object to print. 10911 * @param indent The string to place at the beginning of each line to 10912 * indent that line. 10913 */ 10914 private void printGeneralNames(@NotNull final GeneralNames generalNames, 10915 @NotNull final String indent) 10916 { 10917 for (final String dnsName : generalNames.getDNSNames()) 10918 { 10919 out(indent + INFO_MANAGE_CERTS_GENERAL_NAMES_LABEL_DNS.get(dnsName)); 10920 } 10921 10922 for (final InetAddress ipAddress : generalNames.getIPAddresses()) 10923 { 10924 out(indent + 10925 INFO_MANAGE_CERTS_GENERAL_NAMES_LABEL_IP.get( 10926 ipAddress.getHostAddress())); 10927 } 10928 10929 for (final String name : generalNames.getRFC822Names()) 10930 { 10931 out(indent + 10932 INFO_MANAGE_CERTS_GENERAL_NAMES_LABEL_RFC_822_NAME.get(name)); 10933 } 10934 10935 for (final DN dn : generalNames.getDirectoryNames()) 10936 { 10937 out(indent + 10938 INFO_MANAGE_CERTS_GENERAL_NAMES_LABEL_DIRECTORY_NAME.get( 10939 String.valueOf(dn))); 10940 } 10941 10942 for (final String uri : generalNames.getUniformResourceIdentifiers()) 10943 { 10944 out(indent + INFO_MANAGE_CERTS_GENERAL_NAMES_LABEL_URI.get(uri)); 10945 } 10946 10947 for (final OID oid : generalNames.getRegisteredIDs()) 10948 { 10949 out(indent + 10950 INFO_MANAGE_CERTS_GENERAL_NAMES_LABEL_REGISTERED_ID.get( 10951 oid.toString())); 10952 } 10953 10954 if (! generalNames.getOtherNames().isEmpty()) 10955 { 10956 out(indent + 10957 INFO_MANAGE_CERTS_GENERAL_NAMES_LABEL_OTHER_NAME_COUNT.get( 10958 generalNames.getOtherNames().size())); 10959 } 10960 10961 if (! generalNames.getX400Addresses().isEmpty()) 10962 { 10963 out(indent + 10964 INFO_MANAGE_CERTS_GENERAL_NAMES_LABEL_X400_ADDR_COUNT.get( 10965 generalNames.getX400Addresses().size())); 10966 } 10967 10968 if (! generalNames.getEDIPartyNames().isEmpty()) 10969 { 10970 out(indent + 10971 INFO_MANAGE_CERTS_GENERAL_NAMES_LABEL_EDI_PARTY_NAME_COUNT.get( 10972 generalNames.getEDIPartyNames().size())); 10973 } 10974 } 10975 10976 10977 10978 /** 10979 * Writes a PEM-encoded representation of the provided encoded certificate to 10980 * the given print stream. 10981 * 10982 * @param printStream The print stream to which the PEM-encoded 10983 * certificate should be written. It must not be 10984 * {@code null}. 10985 * @param encodedCertificate The bytes that comprise the encoded 10986 * certificate. It must not be {@code null}. 10987 */ 10988 private static void writePEMCertificate( 10989 @NotNull final PrintStream printStream, 10990 @NotNull final byte[] encodedCertificate) 10991 { 10992 final String certBase64 = Base64.encode(encodedCertificate); 10993 printStream.println("-----BEGIN CERTIFICATE-----"); 10994 for (final String line : StaticUtils.wrapLine(certBase64, 64)) 10995 { 10996 printStream.println(line); 10997 } 10998 printStream.println("-----END CERTIFICATE-----"); 10999 } 11000 11001 11002 11003 /** 11004 * Writes a PEM-encoded representation of the provided encoded certificate 11005 * signing request to the given print stream. 11006 * 11007 * @param printStream The print stream to which the PEM-encoded certificate 11008 * signing request should be written. It must not be 11009 * {@code null}. 11010 * @param encodedCSR The bytes that comprise the encoded certificate 11011 * signing request. It must not be {@code null}. 11012 */ 11013 private static void writePEMCertificateSigningRequest( 11014 @NotNull final PrintStream printStream, 11015 @NotNull final byte[] encodedCSR) 11016 { 11017 final String certBase64 = Base64.encode(encodedCSR); 11018 printStream.println("-----BEGIN CERTIFICATE REQUEST-----"); 11019 for (final String line : StaticUtils.wrapLine(certBase64, 64)) 11020 { 11021 printStream.println(line); 11022 } 11023 printStream.println("-----END CERTIFICATE REQUEST-----"); 11024 } 11025 11026 11027 11028 /** 11029 * Writes a PEM-encoded representation of the provided encoded private key to 11030 * the given print stream. 11031 * 11032 * @param printStream The print stream to which the PEM-encoded 11033 * private key should be written. It must not be 11034 * {@code null}. 11035 * @param encodedPrivateKey The bytes that comprise the encoded private key. 11036 * It must not be {@code null}. 11037 */ 11038 private static void writePEMPrivateKey( 11039 @NotNull final PrintStream printStream, 11040 @NotNull final byte[] encodedPrivateKey) 11041 { 11042 final String certBase64 = Base64.encode(encodedPrivateKey); 11043 printStream.println("-----BEGIN PRIVATE KEY-----"); 11044 for (final String line : StaticUtils.wrapLine(certBase64, 64)) 11045 { 11046 printStream.println(line); 11047 } 11048 printStream.println("-----END PRIVATE KEY-----"); 11049 } 11050 11051 11052 11053 /** 11054 * Displays the keytool command that can be invoked to produce approximately 11055 * equivalent functionality. 11056 * 11057 * @param keytoolArgs The arguments to provide to the keytool command. 11058 */ 11059 private void displayKeytoolCommand(@NotNull final List<String> keytoolArgs) 11060 { 11061 final StringBuilder buffer = new StringBuilder(); 11062 buffer.append("# keytool"); 11063 11064 boolean lastWasArgName = false; 11065 for (final String arg : keytoolArgs) 11066 { 11067 if (arg.startsWith("-")) 11068 { 11069 buffer.append(' '); 11070 buffer.append(StaticUtils.getCommandLineContinuationString()); 11071 buffer.append(StaticUtils.EOL); 11072 buffer.append("# "); 11073 buffer.append(arg); 11074 lastWasArgName = true; 11075 } 11076 else if (lastWasArgName) 11077 { 11078 buffer.append(' '); 11079 buffer.append(StaticUtils.cleanExampleCommandLineArgument(arg)); 11080 lastWasArgName = false; 11081 } 11082 else 11083 { 11084 buffer.append(' '); 11085 buffer.append(StaticUtils.getCommandLineContinuationString()); 11086 buffer.append(StaticUtils.EOL); 11087 buffer.append("# "); 11088 buffer.append(arg); 11089 lastWasArgName = false; 11090 } 11091 } 11092 11093 out(); 11094 out(INFO_MANAGE_CERTS_APPROXIMATE_KEYTOOL_COMMAND.get()); 11095 out(buffer); 11096 out(); 11097 } 11098 11099 11100 11101 /** 11102 * Retrieves the path to the target key store file. 11103 * 11104 * @return The path to the target key store file, or {@code null} if no 11105 * keystore path was configured. 11106 */ 11107 @Nullable() 11108 private File getKeystorePath() 11109 { 11110 return getKeystorePath("keystore"); 11111 } 11112 11113 11114 11115 /** 11116 * Retrieves the path to the target key store file. 11117 * 11118 * @param keystoreArgumentName The name of the argument used to specify the 11119 * path to the target key store. 11120 * 11121 * @return The path to the target keystore file, or {@code null} if no 11122 * keystore path was configured. 11123 */ 11124 @Nullable() 11125 private File getKeystorePath(@NotNull final String keystoreArgumentName) 11126 { 11127 final FileArgument keystoreArgument = 11128 subCommandParser.getFileArgument(keystoreArgumentName); 11129 if ((keystoreArgument != null) && keystoreArgument.isPresent()) 11130 { 11131 return keystoreArgument.getValue(); 11132 } 11133 11134 final BooleanArgument useJVMDefaultTrustStoreArgument = 11135 subCommandParser.getBooleanArgument("useJVMDefaultTrustStore"); 11136 if ((useJVMDefaultTrustStoreArgument != null) && 11137 useJVMDefaultTrustStoreArgument.isPresent()) 11138 { 11139 return JVM_DEFAULT_CACERTS_FILE; 11140 } 11141 11142 return null; 11143 } 11144 11145 11146 11147 /** 11148 * Retrieves the password needed to access the keystore. 11149 * 11150 * @param keystoreFile The path to the keystore file for which to get the 11151 * password. 11152 * 11153 * @return The password needed to access the keystore, or {@code null} if 11154 * no keystore password was configured. 11155 * 11156 * @throws LDAPException If a problem is encountered while trying to get the 11157 * keystore password. 11158 */ 11159 @Nullable() 11160 private char[] getKeystorePassword(@NotNull final File keystoreFile) 11161 throws LDAPException 11162 { 11163 return getKeystorePassword(keystoreFile, null); 11164 } 11165 11166 11167 11168 /** 11169 * Retrieves the password needed to access the keystore. 11170 * 11171 * @param keystoreFile The path to the keystore file for which to get the 11172 * password. 11173 * @param prefix The prefix string to use for the arguments. This may 11174 * be {@code null} if no prefix is needed. 11175 * 11176 * @return The password needed to access the keystore, or {@code null} if 11177 * no keystore password was configured. 11178 * 11179 * @throws LDAPException If a problem is encountered while trying to get the 11180 * keystore password. 11181 */ 11182 @Nullable() 11183 private char[] getKeystorePassword(@NotNull final File keystoreFile, 11184 @Nullable final String prefix) 11185 throws LDAPException 11186 { 11187 final String prefixDash; 11188 if (prefix == null) 11189 { 11190 prefixDash = ""; 11191 } 11192 else 11193 { 11194 prefixDash = prefix + '-'; 11195 } 11196 11197 final StringArgument keystorePasswordArgument = 11198 subCommandParser.getStringArgument(prefixDash + "keystore-password"); 11199 if ((keystorePasswordArgument != null) && 11200 keystorePasswordArgument.isPresent()) 11201 { 11202 final char[] keystorePWChars = 11203 keystorePasswordArgument.getValue().toCharArray(); 11204 if ((! keystoreFile.exists()) && (keystorePWChars.length < 6)) 11205 { 11206 throw new LDAPException(ResultCode.PARAM_ERROR, 11207 ERR_MANAGE_CERTS_GET_KS_PW_TOO_SHORT.get()); 11208 } 11209 11210 return keystorePWChars; 11211 } 11212 11213 11214 final FileArgument keystorePasswordFileArgument = 11215 subCommandParser.getFileArgument( 11216 prefixDash + "keystore-password-file"); 11217 if ((keystorePasswordFileArgument != null) && 11218 keystorePasswordFileArgument.isPresent()) 11219 { 11220 final File f = keystorePasswordFileArgument.getValue(); 11221 try 11222 { 11223 final char[] passwordChars = getPasswordFileReader().readPassword(f); 11224 if (passwordChars.length < 6) 11225 { 11226 throw new LDAPException(ResultCode.PARAM_ERROR, 11227 ERR_MANAGE_CERTS_GET_KS_PW_TOO_SHORT.get()); 11228 } 11229 return passwordChars; 11230 } 11231 catch (final LDAPException e) 11232 { 11233 Debug.debugException(e); 11234 throw e; 11235 } 11236 catch (final Exception e) 11237 { 11238 Debug.debugException(e); 11239 throw new LDAPException(ResultCode.LOCAL_ERROR, 11240 ERR_MANAGE_CERTS_GET_KS_PW_ERROR_READING_FILE.get( 11241 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 11242 e); 11243 } 11244 } 11245 11246 11247 final BooleanArgument promptArgument = subCommandParser.getBooleanArgument( 11248 "prompt-for-" + prefixDash + "keystore-password"); 11249 if ((promptArgument != null) && promptArgument.isPresent()) 11250 { 11251 out(); 11252 if (keystoreFile.exists() && (! "new".equals(prefix))) 11253 { 11254 // We're only going to prompt once. 11255 if ((prefix != null) && prefix.equals("current")) 11256 { 11257 return promptForPassword( 11258 INFO_MANAGE_CERTS_KEY_KS_PW_EXISTING_CURRENT_PROMPT.get( 11259 keystoreFile.getAbsolutePath()), 11260 false); 11261 } 11262 else 11263 { 11264 return promptForPassword( 11265 INFO_MANAGE_CERTS_KEY_KS_PW_EXISTING_PROMPT.get( 11266 keystoreFile.getAbsolutePath()), 11267 false); 11268 } 11269 } 11270 else 11271 { 11272 // We're creating a new keystore, so we should prompt for the password 11273 // twice to prevent setting the wrong password because of a typo. 11274 while (true) 11275 { 11276 final String prompt1; 11277 if ("new".equals(prefix)) 11278 { 11279 prompt1 = INFO_MANAGE_CERTS_KEY_KS_PW_EXISTING_NEW_PROMPT.get(); 11280 } 11281 else 11282 { 11283 prompt1 = INFO_MANAGE_CERTS_KEY_KS_PW_NEW_PROMPT_1.get( 11284 keystoreFile.getAbsolutePath()); 11285 } 11286 final char[] pwChars = promptForPassword(prompt1, false); 11287 11288 if (pwChars.length < 6) 11289 { 11290 wrapErr(0, WRAP_COLUMN, 11291 ERR_MANAGE_CERTS_GET_KS_PW_TOO_SHORT.get()); 11292 err(); 11293 continue; 11294 } 11295 11296 final char[] confirmChars = promptForPassword( 11297 INFO_MANAGE_CERTS_KEY_KS_PW_NEW_PROMPT_2.get(), true); 11298 11299 if (Arrays.equals(pwChars, confirmChars)) 11300 { 11301 Arrays.fill(confirmChars, '\u0000'); 11302 return pwChars; 11303 } 11304 else 11305 { 11306 wrapErr(0, WRAP_COLUMN, 11307 ERR_MANAGE_CERTS_KEY_KS_PW_PROMPT_MISMATCH.get()); 11308 err(); 11309 } 11310 } 11311 } 11312 } 11313 11314 11315 return null; 11316 } 11317 11318 11319 11320 /** 11321 * Prompts for a password and retrieves the value that the user entered. 11322 * 11323 * @param prompt The prompt to display to the user. 11324 * @param allowEmpty Indicates whether to allow the password to be empty. 11325 * 11326 * @return The password that was read, or an empty array if the user did not 11327 * type a password before pressing ENTER. 11328 * 11329 * @throws LDAPException If a problem is encountered while reading the 11330 * password. 11331 */ 11332 @NotNull() 11333 private char[] promptForPassword(@NotNull final String prompt, 11334 final boolean allowEmpty) 11335 throws LDAPException 11336 { 11337 final Iterator<String> iterator = 11338 StaticUtils.wrapLine(prompt, WRAP_COLUMN).iterator(); 11339 while (iterator.hasNext()) 11340 { 11341 final String line = iterator.next(); 11342 if (iterator.hasNext()) 11343 { 11344 out(line); 11345 } 11346 else 11347 { 11348 getOut().print(line); 11349 } 11350 } 11351 11352 final char[] passwordChars = PasswordReader.readPasswordChars(); 11353 if ((passwordChars.length == 0) && (! allowEmpty)) 11354 { 11355 wrapErr(0, WRAP_COLUMN, 11356 ERR_MANAGE_CERTS_PROMPT_FOR_PW_EMPTY_PW.get()); 11357 err(); 11358 return promptForPassword(prompt, allowEmpty); 11359 } 11360 11361 return passwordChars; 11362 } 11363 11364 11365 11366 /** 11367 * Prompts the user for a yes or no response. 11368 * 11369 * @param prompt The prompt to display to the end user. 11370 * 11371 * @return {@code true} if the user chooses the "yes" response, or 11372 * {@code false} if the user chooses the "no" throws. 11373 * 11374 * @throws LDAPException If a problem is encountered while reading data from 11375 * the client. 11376 */ 11377 private boolean promptForYesNo(@NotNull final String prompt) 11378 throws LDAPException 11379 { 11380 while (true) 11381 { 11382 final List<String> lines = 11383 StaticUtils.wrapLine((prompt + ' '), WRAP_COLUMN); 11384 11385 final Iterator<String> lineIterator = lines.iterator(); 11386 while (lineIterator.hasNext()) 11387 { 11388 final String line = lineIterator.next(); 11389 if (lineIterator.hasNext()) 11390 { 11391 out(line); 11392 } 11393 else 11394 { 11395 getOut().print(line); 11396 } 11397 } 11398 11399 try 11400 { 11401 final String response = readLineFromIn(); 11402 if (response.equalsIgnoreCase("yes") || response.equalsIgnoreCase("y")) 11403 { 11404 return true; 11405 } 11406 else if (response.equalsIgnoreCase("no") || 11407 response.equalsIgnoreCase("n")) 11408 { 11409 return false; 11410 } 11411 else 11412 { 11413 err(); 11414 wrapErr(0, WRAP_COLUMN, 11415 ERR_MANAGE_CERTS_PROMPT_FOR_YES_NO_INVALID_RESPONSE.get()); 11416 err(); 11417 } 11418 } 11419 catch (final Exception e) 11420 { 11421 Debug.debugException(e); 11422 throw new LDAPException(ResultCode.LOCAL_ERROR, 11423 ERR_MANAGE_CERTS_PROMPT_FOR_YES_NO_READ_ERROR.get( 11424 StaticUtils.getExceptionMessage(e)), 11425 e); 11426 } 11427 } 11428 } 11429 11430 11431 11432 /** 11433 * Reads a line of input from standard input. 11434 * 11435 * @return The line read from standard input. 11436 * 11437 * @throws IOException If a problem is encountered while reading from 11438 * standard input. 11439 */ 11440 @NotNull() 11441 private String readLineFromIn() 11442 throws IOException 11443 { 11444 final ByteStringBuffer buffer = new ByteStringBuffer(); 11445 while (true) 11446 { 11447 final int byteRead = in.read(); 11448 if (byteRead < 0) 11449 { 11450 if (buffer.isEmpty()) 11451 { 11452 return null; 11453 } 11454 else 11455 { 11456 return buffer.toString(); 11457 } 11458 } 11459 11460 if (byteRead == '\n') 11461 { 11462 return buffer.toString(); 11463 } 11464 else if (byteRead == '\r') 11465 { 11466 final int nextByteRead = in.read(); 11467 Validator.ensureTrue(((nextByteRead < 0) || (nextByteRead == '\n')), 11468 "ERROR: Read a carriage return from standard input that was " + 11469 "not followed by a new line."); 11470 return buffer.toString(); 11471 } 11472 else 11473 { 11474 buffer.append((byte) (byteRead & 0xFF)); 11475 } 11476 } 11477 } 11478 11479 11480 11481 /** 11482 * Retrieves the password needed to access the private key. 11483 * 11484 * @param keystore The keystore that contains the target private 11485 * key. This must not be {@code null}. 11486 * @param alias The alias of the target private key. This must 11487 * not be {@code null}. 11488 * @param keystorePassword The keystore password to use if no specific 11489 * private key password was provided. 11490 * 11491 * @return The password needed to access the private key, or the provided 11492 * keystore password if no arguments were provided to specify a 11493 * different private key password. 11494 * 11495 * @throws LDAPException If a problem is encountered while trying to get the 11496 * private key password. 11497 */ 11498 @Nullable() 11499 private char[] getPrivateKeyPassword(@NotNull final KeyStore keystore, 11500 @NotNull final String alias, 11501 @Nullable final char[] keystorePassword) 11502 throws LDAPException 11503 { 11504 return getPrivateKeyPassword(keystore, alias, null, keystorePassword); 11505 } 11506 11507 11508 11509 /** 11510 * Retrieves the password needed to access the private key. 11511 * 11512 * @param keystore The keystore that contains the target private 11513 * key. This must not be {@code null}. 11514 * @param alias The alias of the target private key. This must 11515 * not be {@code null}. 11516 * @param prefix The prefix string to use for the arguments. This 11517 * may be {@code null} if no prefix is needed. 11518 * @param keystorePassword The keystore password to use if no specific 11519 * private key password was provided. 11520 * 11521 * @return The password needed to access the private key, or the provided 11522 * keystore password if no arguments were provided to specify a 11523 * different private key password. 11524 * 11525 * @throws LDAPException If a problem is encountered while trying to get the 11526 * private key password. 11527 */ 11528 @Nullable() 11529 private char[] getPrivateKeyPassword(@NotNull final KeyStore keystore, 11530 @NotNull final String alias, 11531 @Nullable final String prefix, 11532 @Nullable final char[] keystorePassword) 11533 throws LDAPException 11534 { 11535 final String prefixDash; 11536 if (prefix == null) 11537 { 11538 prefixDash = ""; 11539 } 11540 else 11541 { 11542 prefixDash = prefix + '-'; 11543 } 11544 11545 final StringArgument privateKeyPasswordArgument = 11546 subCommandParser.getStringArgument( 11547 prefixDash + "private-key-password"); 11548 if ((privateKeyPasswordArgument != null) && 11549 privateKeyPasswordArgument.isPresent()) 11550 { 11551 final char[] pkPasswordChars = 11552 privateKeyPasswordArgument.getValue().toCharArray(); 11553 if ((pkPasswordChars.length < 6) && 11554 (! (hasCertificateAlias(keystore, alias) || 11555 hasKeyAlias(keystore, alias)))) 11556 { 11557 throw new LDAPException(ResultCode.PARAM_ERROR, 11558 ERR_MANAGE_CERTS_GET_PK_PW_TOO_SHORT.get()); 11559 } 11560 11561 return pkPasswordChars; 11562 } 11563 11564 11565 final FileArgument privateKeyPasswordFileArgument = 11566 subCommandParser.getFileArgument( 11567 prefixDash + "private-key-password-file"); 11568 if ((privateKeyPasswordFileArgument != null) && 11569 privateKeyPasswordFileArgument.isPresent()) 11570 { 11571 final File f = privateKeyPasswordFileArgument.getValue(); 11572 try 11573 { 11574 final char[] passwordChars = getPasswordFileReader().readPassword(f); 11575 if (passwordChars.length < 6) 11576 { 11577 throw new LDAPException(ResultCode.PARAM_ERROR, 11578 ERR_MANAGE_CERTS_GET_PK_PW_EMPTY_FILE.get(f.getAbsolutePath())); 11579 } 11580 11581 return passwordChars; 11582 } 11583 catch (final LDAPException e) 11584 { 11585 Debug.debugException(e); 11586 throw e; 11587 } 11588 catch (final Exception e) 11589 { 11590 Debug.debugException(e); 11591 throw new LDAPException(ResultCode.LOCAL_ERROR, 11592 ERR_MANAGE_CERTS_GET_PK_PW_ERROR_READING_FILE.get( 11593 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 11594 e); 11595 } 11596 } 11597 11598 11599 final BooleanArgument promptArgument = 11600 subCommandParser.getBooleanArgument( 11601 "prompt-for-" + prefixDash + "private-key-password"); 11602 if ((promptArgument != null) && promptArgument.isPresent()) 11603 { 11604 out(); 11605 11606 try 11607 { 11608 if ((hasKeyAlias(keystore, alias) || 11609 hasCertificateAlias(keystore, alias)) && 11610 (! "new".equals(prefix)) && (! "destination".equals(prefix))) 11611 { 11612 // This means that the private key already exists, so we just need to 11613 // prompt once. 11614 final String prompt; 11615 if ("current".equals(prefix)) 11616 { 11617 prompt = 11618 INFO_MANAGE_CERTS_GET_PK_PW_CURRENT_PROMPT.get(alias); 11619 } 11620 else 11621 { 11622 prompt = 11623 INFO_MANAGE_CERTS_GET_PK_PW_EXISTING_PROMPT.get(alias); 11624 } 11625 11626 return promptForPassword(prompt, false); 11627 } 11628 else 11629 { 11630 // This means that we'll be creating a new private key, so we need to 11631 // prompt twice. 11632 while (true) 11633 { 11634 final String prompt; 11635 if ("new".equals(prefix)) 11636 { 11637 prompt = INFO_MANAGE_CERTS_GET_PK_PW_NEW_PROMPT.get(); 11638 } 11639 else 11640 { 11641 prompt = INFO_MANAGE_CERTS_GET_PK_PW_NEW_PROMPT_1.get(alias); 11642 } 11643 11644 final char[] pwChars = promptForPassword(prompt, false); 11645 if (pwChars.length < 6) 11646 { 11647 wrapErr(0, WRAP_COLUMN, 11648 ERR_MANAGE_CERTS_GET_PK_PW_TOO_SHORT.get()); 11649 err(); 11650 continue; 11651 } 11652 11653 final char[] confirmChars = promptForPassword( 11654 INFO_MANAGE_CERTS_GET_PK_PW_NEW_PROMPT_2.get(), true); 11655 11656 if (Arrays.equals(pwChars, confirmChars)) 11657 { 11658 Arrays.fill(confirmChars, '\u0000'); 11659 return pwChars; 11660 } 11661 else 11662 { 11663 wrapErr(0, WRAP_COLUMN, 11664 ERR_MANAGE_CERTS_GET_PK_PW_PROMPT_MISMATCH.get()); 11665 err(); 11666 } 11667 } 11668 } 11669 } 11670 catch (final LDAPException le) 11671 { 11672 Debug.debugException(le); 11673 throw le; 11674 } 11675 catch (final Exception e) 11676 { 11677 Debug.debugException(e); 11678 throw new LDAPException(ResultCode.LOCAL_ERROR, 11679 ERR_MANAGE_CERTS_GET_PK_PW_PROMPT_ERROR.get(alias, 11680 StaticUtils.getExceptionMessage(e)), 11681 e); 11682 } 11683 } 11684 11685 11686 return keystorePassword; 11687 } 11688 11689 11690 11691 /** 11692 * Infers the keystore type from the provided keystore file. 11693 * 11694 * @param keystorePath The path to the file to examine. 11695 * 11696 * @return The keystore type inferred from the provided keystore file. 11697 * 11698 * @throws LDAPException If a problem is encountered while trying to infer 11699 * the keystore type. 11700 */ 11701 @NotNull() 11702 private String inferKeystoreType(@NotNull final File keystorePath) 11703 throws LDAPException 11704 { 11705 return inferKeystoreType(keystorePath, null); 11706 } 11707 11708 11709 11710 /** 11711 * Infers the keystore type from the provided keystore file. 11712 * 11713 * @param keystorePath The path to the file to examine. 11714 * @param prefix The prefix string to use for the arguments. This 11715 * may be {@code null} if no prefix is needed. 11716 * 11717 * @return The keystore type inferred from the provided keystore file. 11718 * 11719 * @throws LDAPException If a problem is encountered while trying to infer 11720 * the keystore type. 11721 */ 11722 @NotNull() 11723 private String inferKeystoreType(@NotNull final File keystorePath, 11724 @Nullable final String prefix) 11725 throws LDAPException 11726 { 11727 // If the keystore type argument was specified, then use its value. 11728 final StringArgument keystoreTypeArgument; 11729 if (prefix == null) 11730 { 11731 keystoreTypeArgument = 11732 subCommandParser.getStringArgument("keystore-type"); 11733 } 11734 else 11735 { 11736 keystoreTypeArgument = 11737 subCommandParser.getStringArgument(prefix + "-keystore-type"); 11738 } 11739 11740 if ((keystoreTypeArgument != null) && keystoreTypeArgument.isPresent()) 11741 { 11742 final String ktaValue = keystoreTypeArgument.getValue(); 11743 if (ktaValue.equalsIgnoreCase("PKCS11") || 11744 ktaValue.equalsIgnoreCase("PKCS 11") || 11745 ktaValue.equalsIgnoreCase("PKCS#11") || 11746 ktaValue.equalsIgnoreCase("PKCS #11")) 11747 { 11748 return CryptoHelper.KEY_STORE_TYPE_PKCS_11; 11749 } 11750 else if (ktaValue.equalsIgnoreCase("PKCS12") || 11751 ktaValue.equalsIgnoreCase("PKCS 12") || 11752 ktaValue.equalsIgnoreCase("PKCS#12") || 11753 ktaValue.equalsIgnoreCase("PKCS #12")) 11754 { 11755 return CryptoHelper.KEY_STORE_TYPE_PKCS_12; 11756 } 11757 else if (ktaValue.equalsIgnoreCase(BCFKS_KEYSTORE_TYPE)) 11758 { 11759 return BCFKS_KEYSTORE_TYPE; 11760 } 11761 else 11762 { 11763 return CryptoHelper.KEY_STORE_TYPE_JKS; 11764 } 11765 } 11766 11767 11768 // If we've gotten here, then the keystore type was not explicitly specified 11769 // so we will need to infer it. If the LDAP SDK is running in FIPS mode, 11770 // then we'll always use the BCFKS key store type. 11771 if (CryptoHelper.usingFIPSMode()) 11772 { 11773 return BouncyCastleFIPSHelper.FIPS_KEY_STORE_TYPE; 11774 } 11775 11776 11777 // If the key store file doesn't exist, then we must be creating it. Use 11778 // the default key store type. 11779 if (! keystorePath.exists()) 11780 { 11781 return DEFAULT_KEYSTORE_TYPE; 11782 } 11783 11784 11785 try 11786 { 11787 return CryptoHelper.inferKeyStoreType(keystorePath); 11788 } 11789 catch (final Exception e) 11790 { 11791 Debug.debugException(e); 11792 throw new LDAPException(ResultCode.PARAM_ERROR, e.getMessage(), e); 11793 } 11794 } 11795 11796 11797 11798 /** 11799 * Retrieves a user-friendly representation of the provided keystore type. 11800 * 11801 * @param keystoreType The keystore type for which to get the user-friendly 11802 * name. 11803 * 11804 * @return "JKS" if the provided keystore type is for a JKS keystore, 11805 * "PKCS #12" if the provided keystore type is for a PKCS #12 11806 * keystore, or the provided string if it is for some other keystore 11807 * type. 11808 */ 11809 @NotNull() 11810 static String getUserFriendlyKeystoreType(@NotNull final String keystoreType) 11811 { 11812 if (keystoreType.equalsIgnoreCase("JKS")) 11813 { 11814 return "JKS"; 11815 } 11816 else if (keystoreType.equalsIgnoreCase("PKCS11") || 11817 keystoreType.equalsIgnoreCase("PKCS 11") || 11818 keystoreType.equalsIgnoreCase("PKCS#11") || 11819 keystoreType.equalsIgnoreCase("PKCS #11")) 11820 { 11821 return "PKCS #11"; 11822 } 11823 else if (keystoreType.equalsIgnoreCase("PKCS12") || 11824 keystoreType.equalsIgnoreCase("PKCS 12") || 11825 keystoreType.equalsIgnoreCase("PKCS#12") || 11826 keystoreType.equalsIgnoreCase("PKCS #12")) 11827 { 11828 return "PKCS #12"; 11829 } 11830 else if (keystoreType.equalsIgnoreCase(BCFKS_KEYSTORE_TYPE)) 11831 { 11832 return BCFKS_KEYSTORE_TYPE; 11833 } 11834 else 11835 { 11836 return keystoreType; 11837 } 11838 } 11839 11840 11841 11842 /** 11843 * Gets access to a keystore based on information included in command-line 11844 * arguments. 11845 * 11846 * @param keystoreType The keystore type for the keystore to access. 11847 * @param keystorePath The path to the keystore file. 11848 * @param keystorePassword The password to use to access the keystore. 11849 * 11850 * @return The configured keystore instance. 11851 * 11852 * @throws LDAPException If it is not possible to access the keystore. 11853 */ 11854 @NotNull() 11855 static KeyStore getKeystore(@NotNull final String keystoreType, 11856 @NotNull final File keystorePath, 11857 @Nullable final char[] keystorePassword) 11858 throws LDAPException 11859 { 11860 // Instantiate a keystore instance of the desired keystore type. 11861 final KeyStore keystore; 11862 try 11863 { 11864 if (keystoreType.equals(CryptoHelper.KEY_STORE_TYPE_PKCS_11)) 11865 { 11866 // NOTE: For PKCS #11 key store types, the key store path will be 11867 // treated as the path to the provider configuration file. 11868 final Provider pkcs11Provider = PKCS11KeyManager.getProvider(null, 11869 keystorePath, keystoreType, true); 11870 keystore = CryptoHelper.getKeyStore(keystoreType, pkcs11Provider); 11871 } 11872 else if (keystoreType.equals(BCFKS_KEYSTORE_TYPE)) 11873 { 11874 keystore = CryptoHelper.getKeyStore(keystoreType, 11875 BouncyCastleFIPSHelper.getBouncyCastleFIPSProvider()); 11876 } 11877 else 11878 { 11879 keystore = CryptoHelper.getKeyStore(keystoreType); 11880 } 11881 } 11882 catch (final Exception e) 11883 { 11884 Debug.debugException(e); 11885 throw new LDAPException(ResultCode.LOCAL_ERROR, 11886 ERR_MANAGE_CERTS_CANNOT_INSTANTIATE_KS_TYPE.get(keystoreType, 11887 StaticUtils.getExceptionMessage(e)), 11888 e); 11889 } 11890 11891 11892 // Get an input stream that may be used to access the keystore. 11893 final InputStream inputStream; 11894 try 11895 { 11896 if (keystorePath.exists() && 11897 (! keystoreType.equals(CryptoHelper.KEY_STORE_TYPE_PKCS_11))) 11898 { 11899 inputStream = new FileInputStream(keystorePath); 11900 } 11901 else 11902 { 11903 inputStream = null; 11904 } 11905 } 11906 catch (final Exception e) 11907 { 11908 Debug.debugException(e); 11909 throw new LDAPException(ResultCode.LOCAL_ERROR, 11910 ERR_MANAGE_CERTS_CANNOT_OPEN_KS_FILE_FOR_READING.get( 11911 keystorePath.getAbsolutePath(), 11912 StaticUtils.getExceptionMessage(e)), 11913 e); 11914 } 11915 11916 try 11917 { 11918 keystore.load(inputStream, keystorePassword); 11919 } 11920 catch (final Exception e) 11921 { 11922 Debug.debugException(e); 11923 final Throwable cause = e.getCause(); 11924 if ((e instanceof IOException) && (cause != null) && 11925 (cause instanceof UnrecoverableKeyException) && 11926 (keystorePassword != null)) 11927 { 11928 throw new LDAPException(ResultCode.PARAM_ERROR, 11929 ERR_MANAGE_CERTS_CANNOT_LOAD_KS_WRONG_PW.get( 11930 keystorePath.getAbsolutePath()), 11931 e); 11932 } 11933 else 11934 { 11935 throw new LDAPException(ResultCode.PARAM_ERROR, 11936 ERR_MANAGE_CERTS_ERROR_CANNOT_LOAD_KS.get( 11937 keystorePath.getAbsolutePath(), 11938 StaticUtils.getExceptionMessage(e)), 11939 e); 11940 } 11941 } 11942 finally 11943 { 11944 try 11945 { 11946 if (inputStream != null) 11947 { 11948 inputStream.close(); 11949 } 11950 } 11951 catch (final Exception e) 11952 { 11953 Debug.debugException(e); 11954 } 11955 } 11956 11957 return keystore; 11958 } 11959 11960 11961 11962 /** 11963 * Reads all of the certificates contained in the specified file. The file 11964 * must exist and may contain zero or more certificates that are either all in 11965 * PEM format or all in DER format. 11966 * 11967 * @param f The path to the certificate file to read. It must not be 11968 * {@code null}. 11969 * 11970 * @return A list of the certificates read from the specified file. 11971 * 11972 * @throws LDAPException If a problem is encountered while reading 11973 * certificates from the specified file. 11974 */ 11975 @NotNull() 11976 public static List<X509Certificate> readCertificatesFromFile( 11977 @NotNull final File f) 11978 throws LDAPException 11979 { 11980 // Read the first byte of the file to see if it contains DER-formatted data, 11981 // which we can determine by seeing if the first byte is 0x30. 11982 try (BufferedInputStream inputStream = 11983 new BufferedInputStream(new FileInputStream(f))) 11984 { 11985 inputStream.mark(1); 11986 final int firstByte = inputStream.read(); 11987 11988 if (firstByte < 0) 11989 { 11990 // This means that the file is empty. 11991 return Collections.emptyList(); 11992 } 11993 else 11994 { 11995 inputStream.reset(); 11996 } 11997 11998 final ArrayList<X509Certificate> certList = new ArrayList<>(5); 11999 if ((firstByte & 0xFF) == 0x30) 12000 { 12001 // It is a DER-encoded file. Read ASN.1 elements and decode them as 12002 // X.509 certificates. 12003 while (true) 12004 { 12005 final ASN1Element certElement; 12006 try 12007 { 12008 certElement = ASN1Element.readFrom(inputStream); 12009 } 12010 catch (final Exception e) 12011 { 12012 Debug.debugException(e); 12013 throw new LDAPException(ResultCode.LOCAL_ERROR, 12014 ERR_MANAGE_CERTS_READ_CERTS_FROM_FILE_DER_NOT_VALID_ASN1.get( 12015 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 12016 e); 12017 } 12018 12019 if (certElement == null) 12020 { 12021 // We've reached the end of the input stream. 12022 return certList; 12023 } 12024 12025 try 12026 { 12027 certList.add(new X509Certificate(certElement.encode())); 12028 } 12029 catch (final CertException e) 12030 { 12031 Debug.debugException(e); 12032 throw new LDAPException(ResultCode.PARAM_ERROR, 12033 ERR_MANAGE_CERTS_READ_CERTS_FROM_FILE_DER_NOT_VALID_CERT.get( 12034 f.getAbsolutePath(), e.getMessage()), 12035 e); 12036 } 12037 } 12038 } 12039 else 12040 { 12041 try (BufferedReader reader = 12042 new BufferedReader(new InputStreamReader(inputStream))) 12043 { 12044 boolean inCert = false; 12045 final StringBuilder buffer = new StringBuilder(); 12046 while (true) 12047 { 12048 String line = reader.readLine(); 12049 if (line == null) 12050 { 12051 if (inCert) 12052 { 12053 throw new LDAPException(ResultCode.PARAM_ERROR, 12054 ERR_MANAGE_CERTS_READ_CERTS_FROM_FILE_EOF_WITHOUT_END.get( 12055 f.getAbsolutePath())); 12056 } 12057 12058 return certList; 12059 } 12060 12061 line = line.trim(); 12062 if (line.isEmpty() || line.startsWith("#")) 12063 { 12064 continue; 12065 } 12066 12067 if (line.equals("-----BEGIN CERTIFICATE-----")) 12068 { 12069 if (inCert) 12070 { 12071 throw new LDAPException(ResultCode.PARAM_ERROR, 12072 ERR_MANAGE_CERTS_READ_CERTS_FROM_FILE_MULTIPLE_BEGIN.get( 12073 f.getAbsolutePath())); 12074 } 12075 else 12076 { 12077 inCert = true; 12078 } 12079 } 12080 else if (line.equals("-----END CERTIFICATE-----")) 12081 { 12082 if (! inCert) 12083 { 12084 throw new LDAPException(ResultCode.PARAM_ERROR, 12085 ERR_MANAGE_CERTS_READ_CERTS_FROM_FILE_END_WITHOUT_BEGIN. 12086 get(f.getAbsolutePath())); 12087 } 12088 12089 inCert = false; 12090 final byte[] certBytes; 12091 try 12092 { 12093 certBytes = Base64.decode(buffer.toString()); 12094 } 12095 catch (final Exception e) 12096 { 12097 Debug.debugException(e); 12098 throw new LDAPException(ResultCode.PARAM_ERROR, 12099 ERR_MANAGE_CERTS_READ_CERTS_FROM_FILE_PEM_CERT_NOT_BASE64. 12100 get(f.getAbsolutePath(), 12101 StaticUtils.getExceptionMessage(e)), 12102 e); 12103 } 12104 12105 try 12106 { 12107 certList.add(new X509Certificate(certBytes)); 12108 } 12109 catch (final CertException e) 12110 { 12111 Debug.debugException(e); 12112 throw new LDAPException(ResultCode.PARAM_ERROR, 12113 ERR_MANAGE_CERTS_READ_CERTS_FROM_FILE_PEM_CERT_NOT_CERT. 12114 get(f.getAbsolutePath(), e.getMessage()), 12115 e); 12116 } 12117 12118 buffer.setLength(0); 12119 } 12120 else if (inCert) 12121 { 12122 buffer.append(line); 12123 } 12124 else 12125 { 12126 throw new LDAPException(ResultCode.PARAM_ERROR, 12127 ERR_MANAGE_CERTS_READ_CERTS_FROM_FILE_DATA_WITHOUT_BEGIN.get( 12128 f.getAbsolutePath())); 12129 } 12130 } 12131 } 12132 } 12133 } 12134 catch (final LDAPException le) 12135 { 12136 Debug.debugException(le); 12137 throw le; 12138 } 12139 catch (final Exception e) 12140 { 12141 Debug.debugException(e); 12142 throw new LDAPException(ResultCode.LOCAL_ERROR, 12143 ERR_MANAGE_CERTS_READ_CERTS_FROM_FILE_READ_ERROR.get( 12144 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 12145 e); 12146 } 12147 } 12148 12149 12150 12151 /** 12152 * Reads a private key from the specified file. The file must exist and must 12153 * contain exactly one PEM-encoded or DER-encoded PKCS #8 private key. 12154 * 12155 * @param f The path to the private key file to read. It must not be 12156 * {@code null}. 12157 * 12158 * @return The private key read from the file. 12159 * 12160 * @throws LDAPException If a problem is encountered while reading the 12161 * private key. 12162 */ 12163 @NotNull() 12164 static PKCS8PrivateKey readPrivateKeyFromFile(@NotNull final File f) 12165 throws LDAPException 12166 { 12167 // Read the first byte of the file to see if it contains DER-formatted data, 12168 // which we can determine by seeing if the first byte is 0x30. 12169 try (BufferedInputStream inputStream = 12170 new BufferedInputStream(new FileInputStream(f))) 12171 { 12172 inputStream.mark(1); 12173 final int firstByte = inputStream.read(); 12174 12175 if (firstByte < 0) 12176 { 12177 // This means that the file is empty. 12178 throw new LDAPException(ResultCode.PARAM_ERROR, 12179 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_EMPTY_FILE.get( 12180 f.getAbsolutePath())); 12181 } 12182 else 12183 { 12184 inputStream.reset(); 12185 } 12186 12187 PKCS8PrivateKey privateKey = null; 12188 if ((firstByte & 0xFF) == 0x30) 12189 { 12190 // It is a DER-encoded file. Read an ASN.1 element and decode it as a 12191 // certificate. 12192 while (true) 12193 { 12194 final ASN1Element pkElement; 12195 try 12196 { 12197 pkElement = ASN1Element.readFrom(inputStream); 12198 } 12199 catch (final Exception e) 12200 { 12201 Debug.debugException(e); 12202 throw new LDAPException(ResultCode.LOCAL_ERROR, 12203 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_DER_NOT_VALID_ASN1.get( 12204 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 12205 e); 12206 } 12207 12208 if (pkElement == null) 12209 { 12210 // We've reached the end of the input stream. 12211 if (privateKey == null) 12212 { 12213 throw new LDAPException(ResultCode.PARAM_ERROR, 12214 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_EMPTY_FILE.get( 12215 f.getAbsolutePath())); 12216 } 12217 else 12218 { 12219 return privateKey; 12220 } 12221 } 12222 else if (privateKey == null) 12223 { 12224 try 12225 { 12226 privateKey = new PKCS8PrivateKey(pkElement.encode()); 12227 } 12228 catch (final Exception e) 12229 { 12230 Debug.debugException(e); 12231 throw new LDAPException(ResultCode.PARAM_ERROR, 12232 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_DER_NOT_VALID_PK.get( 12233 f.getAbsolutePath(), e.getMessage()), 12234 e); 12235 } 12236 } 12237 else 12238 { 12239 throw new LDAPException(ResultCode.PARAM_ERROR, 12240 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_MULTIPLE_KEYS.get( 12241 f.getAbsolutePath())); 12242 } 12243 } 12244 } 12245 else 12246 { 12247 try (BufferedReader reader = 12248 new BufferedReader(new InputStreamReader(inputStream))) 12249 { 12250 boolean inKey = false; 12251 boolean isRSAKey = false; 12252 final StringBuilder buffer = new StringBuilder(); 12253 while (true) 12254 { 12255 String line = reader.readLine(); 12256 if (line == null) 12257 { 12258 if (inKey) 12259 { 12260 throw new LDAPException(ResultCode.PARAM_ERROR, 12261 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_EOF_WITHOUT_END.get( 12262 f.getAbsolutePath())); 12263 } 12264 12265 if (privateKey == null) 12266 { 12267 throw new LDAPException(ResultCode.PARAM_ERROR, 12268 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_EMPTY_FILE.get( 12269 f.getAbsolutePath())); 12270 } 12271 else 12272 { 12273 return privateKey; 12274 } 12275 } 12276 12277 line = line.trim(); 12278 if (line.isEmpty() || line.startsWith("#")) 12279 { 12280 continue; 12281 } 12282 12283 if (line.equals("-----BEGIN PRIVATE KEY-----") || 12284 line.equals("-----BEGIN RSA PRIVATE KEY-----")) 12285 { 12286 if (inKey) 12287 { 12288 throw new LDAPException(ResultCode.PARAM_ERROR, 12289 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_MULTIPLE_BEGIN.get( 12290 f.getAbsolutePath())); 12291 } 12292 else if (privateKey != null) 12293 { 12294 throw new LDAPException(ResultCode.PARAM_ERROR, 12295 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_MULTIPLE_KEYS.get( 12296 f.getAbsolutePath())); 12297 } 12298 else 12299 { 12300 inKey = true; 12301 if (line.equals("-----BEGIN RSA PRIVATE KEY-----")) 12302 { 12303 isRSAKey = true; 12304 } 12305 } 12306 } 12307 else if (line.equals("-----END PRIVATE KEY-----") || 12308 line.equals("-----END RSA PRIVATE KEY-----")) 12309 { 12310 if (! inKey) 12311 { 12312 throw new LDAPException(ResultCode.PARAM_ERROR, 12313 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_END_WITHOUT_BEGIN.get( 12314 f.getAbsolutePath())); 12315 } 12316 12317 inKey = false; 12318 byte[] pkBytes; 12319 try 12320 { 12321 pkBytes = Base64.decode(buffer.toString()); 12322 } 12323 catch (final Exception e) 12324 { 12325 Debug.debugException(e); 12326 throw new LDAPException(ResultCode.PARAM_ERROR, 12327 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_PEM_PK_NOT_BASE64.get( 12328 f.getAbsolutePath(), 12329 StaticUtils.getExceptionMessage(e)), 12330 e); 12331 } 12332 12333 if (isRSAKey) 12334 { 12335 pkBytes = PKCS8PrivateKey.wrapRSAPrivateKey(pkBytes); 12336 } 12337 12338 try 12339 { 12340 privateKey = new PKCS8PrivateKey(pkBytes); 12341 } 12342 catch (final CertException e) 12343 { 12344 Debug.debugException(e); 12345 throw new LDAPException(ResultCode.PARAM_ERROR, 12346 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_PEM_PK_NOT_PK.get( 12347 f.getAbsolutePath(), e.getMessage()), 12348 e); 12349 } 12350 12351 buffer.setLength(0); 12352 } 12353 else if (inKey) 12354 { 12355 buffer.append(line); 12356 } 12357 else 12358 { 12359 throw new LDAPException(ResultCode.PARAM_ERROR, 12360 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_DATA_WITHOUT_BEGIN.get( 12361 f.getAbsolutePath())); 12362 } 12363 } 12364 } 12365 } 12366 } 12367 catch (final LDAPException le) 12368 { 12369 Debug.debugException(le); 12370 throw le; 12371 } 12372 catch (final Exception e) 12373 { 12374 Debug.debugException(e); 12375 throw new LDAPException(ResultCode.LOCAL_ERROR, 12376 ERR_MANAGE_CERTS_READ_PK_FROM_FILE_READ_ERROR.get( 12377 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 12378 e); 12379 } 12380 } 12381 12382 12383 12384 /** 12385 * Reads a certificate signing request from the specified file. The file must 12386 * exist and must contain exactly one PEM-encoded or DER-encoded PKCS #10 12387 * certificate signing request. 12388 * 12389 * @param f The path to the private key file to read. It must not be 12390 * {@code null}. 12391 * 12392 * @return The certificate signing request read from the file. 12393 * 12394 * @throws LDAPException If a problem is encountered while reading the 12395 * certificate signing request. 12396 */ 12397 @NotNull() 12398 public static PKCS10CertificateSigningRequest 12399 readCertificateSigningRequestFromFile( 12400 @NotNull final File f) 12401 throws LDAPException 12402 { 12403 // Read the first byte of the file to see if it contains DER-formatted data, 12404 // which we can determine by seeing if the first byte is 0x30. 12405 try (BufferedInputStream inputStream = 12406 new BufferedInputStream(new FileInputStream(f))) 12407 { 12408 inputStream.mark(1); 12409 final int firstByte = inputStream.read(); 12410 12411 if (firstByte < 0) 12412 { 12413 // This means that the file is empty. 12414 throw new LDAPException(ResultCode.PARAM_ERROR, 12415 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_EMPTY_FILE.get( 12416 f.getAbsolutePath())); 12417 } 12418 else 12419 { 12420 inputStream.reset(); 12421 } 12422 12423 PKCS10CertificateSigningRequest csr = null; 12424 if ((firstByte & 0xFF) == 0x30) 12425 { 12426 // It is a DER-encoded file. Read an ASN.1 element and decode it as a 12427 // certificate. 12428 while (true) 12429 { 12430 final ASN1Element csrElement; 12431 try 12432 { 12433 csrElement = ASN1Element.readFrom(inputStream); 12434 } 12435 catch (final Exception e) 12436 { 12437 Debug.debugException(e); 12438 throw new LDAPException(ResultCode.LOCAL_ERROR, 12439 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_DER_NOT_VALID_ASN1.get( 12440 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 12441 e); 12442 } 12443 12444 if (csrElement == null) 12445 { 12446 // We've reached the end of the input stream. 12447 if (csr == null) 12448 { 12449 throw new LDAPException(ResultCode.PARAM_ERROR, 12450 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_EMPTY_FILE.get( 12451 f.getAbsolutePath())); 12452 } 12453 else 12454 { 12455 return csr; 12456 } 12457 } 12458 else if (csr == null) 12459 { 12460 try 12461 { 12462 csr = new PKCS10CertificateSigningRequest(csrElement.encode()); 12463 } 12464 catch (final Exception e) 12465 { 12466 Debug.debugException(e); 12467 throw new LDAPException(ResultCode.PARAM_ERROR, 12468 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_DER_NOT_VALID_CSR.get( 12469 f.getAbsolutePath(), e.getMessage()), 12470 e); 12471 } 12472 } 12473 else 12474 { 12475 throw new LDAPException(ResultCode.PARAM_ERROR, 12476 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_MULTIPLE_CSRS.get( 12477 f.getAbsolutePath())); 12478 } 12479 } 12480 } 12481 else 12482 { 12483 try (BufferedReader reader = 12484 new BufferedReader(new InputStreamReader(inputStream))) 12485 { 12486 boolean inCSR = false; 12487 final StringBuilder buffer = new StringBuilder(); 12488 while (true) 12489 { 12490 String line = reader.readLine(); 12491 if (line == null) 12492 { 12493 if (inCSR) 12494 { 12495 throw new LDAPException(ResultCode.PARAM_ERROR, 12496 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_EOF_WITHOUT_END.get( 12497 f.getAbsolutePath())); 12498 } 12499 12500 if (csr == null) 12501 { 12502 throw new LDAPException(ResultCode.PARAM_ERROR, 12503 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_EMPTY_FILE.get( 12504 f.getAbsolutePath())); 12505 } 12506 else 12507 { 12508 return csr; 12509 } 12510 } 12511 12512 line = line.trim(); 12513 if (line.isEmpty() || line.startsWith("#")) 12514 { 12515 continue; 12516 } 12517 12518 if (line.equals("-----BEGIN CERTIFICATE REQUEST-----") || 12519 line.equals("-----BEGIN NEW CERTIFICATE REQUEST-----")) 12520 { 12521 if (inCSR) 12522 { 12523 throw new LDAPException(ResultCode.PARAM_ERROR, 12524 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_MULTIPLE_BEGIN.get( 12525 f.getAbsolutePath())); 12526 } 12527 else if (csr != null) 12528 { 12529 throw new LDAPException(ResultCode.PARAM_ERROR, 12530 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_MULTIPLE_CSRS.get( 12531 f.getAbsolutePath())); 12532 } 12533 else 12534 { 12535 inCSR = true; 12536 } 12537 } 12538 else if (line.equals("-----END CERTIFICATE REQUEST-----") || 12539 line.equals("-----END NEW CERTIFICATE REQUEST-----")) 12540 { 12541 if (! inCSR) 12542 { 12543 throw new LDAPException(ResultCode.PARAM_ERROR, 12544 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_END_WITHOUT_BEGIN.get( 12545 f.getAbsolutePath())); 12546 } 12547 12548 inCSR = false; 12549 final byte[] csrBytes; 12550 try 12551 { 12552 csrBytes = Base64.decode(buffer.toString()); 12553 } 12554 catch (final Exception e) 12555 { 12556 Debug.debugException(e); 12557 throw new LDAPException(ResultCode.PARAM_ERROR, 12558 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_PEM_CSR_NOT_BASE64.get( 12559 f.getAbsolutePath(), 12560 StaticUtils.getExceptionMessage(e)), 12561 e); 12562 } 12563 12564 try 12565 { 12566 csr = new PKCS10CertificateSigningRequest(csrBytes); 12567 } 12568 catch (final CertException e) 12569 { 12570 Debug.debugException(e); 12571 throw new LDAPException(ResultCode.PARAM_ERROR, 12572 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_PEM_CSR_NOT_CSR.get( 12573 f.getAbsolutePath(), e.getMessage()), 12574 e); 12575 } 12576 12577 buffer.setLength(0); 12578 } 12579 else if (inCSR) 12580 { 12581 buffer.append(line); 12582 } 12583 else 12584 { 12585 throw new LDAPException(ResultCode.PARAM_ERROR, 12586 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_DATA_WITHOUT_BEGIN.get( 12587 f.getAbsolutePath())); 12588 } 12589 } 12590 } 12591 } 12592 } 12593 catch (final LDAPException le) 12594 { 12595 Debug.debugException(le); 12596 throw le; 12597 } 12598 catch (final Exception e) 12599 { 12600 Debug.debugException(e); 12601 throw new LDAPException(ResultCode.LOCAL_ERROR, 12602 ERR_MANAGE_CERTS_READ_CSR_FROM_FILE_READ_ERROR.get( 12603 f.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), 12604 e); 12605 } 12606 } 12607 12608 12609 12610 /** 12611 * Retrieves a colon-delimited hexadecimal representation of the contents of 12612 * the provided byte array. 12613 * 12614 * @param bytes The byte array for which to get the hexadecimal 12615 * representation. It must not be {@code null}. 12616 * 12617 * @return A colon-delimited hexadecimal representation of the contents of 12618 * the provided byte array. 12619 */ 12620 @NotNull() 12621 private static String toColonDelimitedHex(@NotNull final byte... bytes) 12622 { 12623 final StringBuilder buffer = new StringBuilder(bytes.length * 3); 12624 StaticUtils.toHex(bytes, ":", buffer); 12625 return buffer.toString(); 12626 } 12627 12628 12629 12630 /** 12631 * Retrieves a formatted representation of the provided date in a 12632 * human-readable format that includes an offset from the current time. 12633 * 12634 * @param d The date to format. It must not be {@code null}. 12635 * 12636 * @return A formatted representation of the provided date. 12637 */ 12638 @NotNull() 12639 private static String formatDateAndTime(@NotNull final Date d) 12640 { 12641 // Example: Sunday, January 1, 2017 12642 final String dateFormatString = "EEEE, MMMM d, yyyy"; 12643 final String formattedDate = 12644 new SimpleDateFormat(dateFormatString).format(d); 12645 12646 // Example: 12:34:56 AM CDT 12647 final String timeFormatString = "hh:mm:ss aa z"; 12648 final String formattedTime = 12649 new SimpleDateFormat(timeFormatString).format(d); 12650 12651 final long providedTime = d.getTime(); 12652 final long currentTime = System.currentTimeMillis(); 12653 if (providedTime > currentTime) 12654 { 12655 final long secondsInFuture = ((providedTime - currentTime) / 1000L); 12656 final String durationInFuture = 12657 StaticUtils.secondsToHumanReadableDuration(secondsInFuture); 12658 return INFO_MANAGE_CERTS_FORMAT_DATE_AND_TIME_IN_FUTURE.get(formattedDate, 12659 formattedTime, durationInFuture); 12660 } 12661 else 12662 { 12663 final long secondsInPast = ((currentTime - providedTime) / 1000L); 12664 final String durationInPast = 12665 StaticUtils.secondsToHumanReadableDuration(secondsInPast); 12666 return INFO_MANAGE_CERTS_FORMAT_DATE_AND_TIME_IN_PAST.get(formattedDate, 12667 formattedTime, durationInPast); 12668 } 12669 } 12670 12671 12672 12673 /** 12674 * Retrieves a formatted representation of the provided date in a format 12675 * suitable for use as the validity start time value provided to the keytool 12676 * command. 12677 * 12678 * @param d The date to format. It must not be {@code null}. 12679 * 12680 * @return A formatted representation of the provided date. 12681 */ 12682 @NotNull() 12683 private static String formatValidityStartTime(@NotNull final Date d) 12684 { 12685 // Example: 2017/01/01 01:23:45 12686 final String dateFormatString = "yyyy'/'MM'/'dd HH':'mm':'ss"; 12687 return new SimpleDateFormat(dateFormatString).format(d); 12688 } 12689 12690 12691 12692 /** 12693 * Retrieves the certificate chain for the specified certificate from the 12694 * given keystore. If any issuer certificate is not in the provided keystore, 12695 * then the JVM-default trust store will be checked to see if it can be found 12696 * there. 12697 * 12698 * @param alias The alias of the certificate for which to get the 12699 * certificate chain. This must not be 12700 * {@code null}. 12701 * @param keystore The keystore from which to get the certificate 12702 * chain. This must not be {@code null}. 12703 * @param missingIssuerRef A reference that will be updated with the DN of a 12704 * missing issuer certificate, if any certificate in 12705 * the chain cannot be located. This must not be 12706 * {@code null}. 12707 * 12708 * @return The certificate chain for the specified certificate, or an empty 12709 * array if no certificate exists with the specified alias. 12710 * 12711 * @throws LDAPException If a problem is encountered while getting the 12712 * certificate chain. 12713 */ 12714 @NotNull() 12715 private static X509Certificate[] getCertificateChain( 12716 @NotNull final String alias, 12717 @NotNull final KeyStore keystore, 12718 @NotNull final AtomicReference<DN> missingIssuerRef) 12719 throws LDAPException 12720 { 12721 try 12722 { 12723 // First, see if the keystore will give us the certificate chain. This 12724 // will only happen if the alias references an entry that includes the 12725 // private key, but it will save us a lot of work. 12726 final Certificate[] chain = keystore.getCertificateChain(alias); 12727 if ((chain != null) && (chain.length > 0)) 12728 { 12729 final X509Certificate[] x509Chain = new X509Certificate[chain.length]; 12730 for (int i=0; i < chain.length; i++) 12731 { 12732 x509Chain[i] = new X509Certificate(chain[i].getEncoded()); 12733 } 12734 return x509Chain; 12735 } 12736 12737 12738 // We couldn't get the keystore to give us the chain, but see if we can 12739 // get a certificate with the specified alias. 12740 final Certificate endCert = keystore.getCertificate(alias); 12741 if (endCert == null) 12742 { 12743 // This means there isn't any certificate with the specified alias. 12744 // Return an empty chain. 12745 return new X509Certificate[0]; 12746 } 12747 12748 final ArrayList<X509Certificate> chainList = new ArrayList<>(5); 12749 X509Certificate certificate = new X509Certificate(endCert.getEncoded()); 12750 chainList.add(certificate); 12751 12752 final AtomicReference<KeyStore> jvmDefaultTrustStoreRef = 12753 new AtomicReference<>(); 12754 while (true) 12755 { 12756 final X509Certificate issuerCertificate = 12757 getIssuerCertificate(certificate, keystore, 12758 jvmDefaultTrustStoreRef, missingIssuerRef); 12759 if (issuerCertificate == null) 12760 { 12761 break; 12762 } 12763 12764 chainList.add(issuerCertificate); 12765 certificate = issuerCertificate; 12766 } 12767 12768 final X509Certificate[] x509Chain = new X509Certificate[chainList.size()]; 12769 return chainList.toArray(x509Chain); 12770 } 12771 catch (final Exception e) 12772 { 12773 Debug.debugException(e); 12774 throw new LDAPException(ResultCode.LOCAL_ERROR, 12775 ERR_MANAGE_CERTS_GET_CHAIN_ERROR.get(alias, 12776 StaticUtils.getExceptionMessage(e)), 12777 e); 12778 } 12779 } 12780 12781 12782 12783 /** 12784 * Attempts to retrieve the issuer certificate for the provided certificate 12785 * from the given keystore or the JVM-default trust store. 12786 * 12787 * @param certificate The certificate for which to retrieve the 12788 * issuer certificate. 12789 * @param keystore The keystore in which to look for the 12790 * issuer certificate. 12791 * @param jvmDefaultTrustStoreRef A reference that will be used to hold the 12792 * JVM-default trust store if it is obtained 12793 * in the process of retrieving the issuer 12794 * certificate. 12795 * @param missingIssuerRef A reference that will be updated with the 12796 * DN of a missing issuer certificate, if any 12797 * certificate in the chain cannot be 12798 * located. This must not be {@code null}. 12799 * 12800 * @return The issuer certificate for the provided certificate, or 12801 * {@code null} if the issuer certificate could not be retrieved. 12802 * 12803 * @throws Exception If a problem is encountered while trying to retrieve 12804 * the issuer certificate. 12805 */ 12806 @Nullable() 12807 private static X509Certificate getIssuerCertificate( 12808 @NotNull final X509Certificate certificate, 12809 @NotNull final KeyStore keystore, 12810 @NotNull final AtomicReference<KeyStore> jvmDefaultTrustStoreRef, 12811 @NotNull final AtomicReference<DN> missingIssuerRef) 12812 throws Exception 12813 { 12814 final DN subjectDN = certificate.getSubjectDN(); 12815 final DN issuerDN = certificate.getIssuerDN(); 12816 if (subjectDN.equals(issuerDN)) 12817 { 12818 // This means that the certificate is self-signed, so there is no issuer. 12819 return null; 12820 } 12821 12822 12823 // See if we can find the issuer certificate in the provided keystore. 12824 X509Certificate issuerCertificate = getIssuerCertificate(certificate, 12825 keystore); 12826 if (issuerCertificate != null) 12827 { 12828 return issuerCertificate; 12829 } 12830 12831 12832 // See if we can get the JVM-default trust store. 12833 KeyStore jvmDefaultTrustStore = jvmDefaultTrustStoreRef.get(); 12834 if (jvmDefaultTrustStore == null) 12835 { 12836 if (JVM_DEFAULT_CACERTS_FILE == null) 12837 { 12838 missingIssuerRef.set(issuerDN); 12839 return null; 12840 } 12841 12842 final String[] keystoreTypes = 12843 { 12844 CryptoHelper.KEY_STORE_TYPE_JKS, 12845 CryptoHelper.KEY_STORE_TYPE_PKCS_12, 12846 BouncyCastleFIPSHelper.FIPS_KEY_STORE_TYPE 12847 }; 12848 12849 for (final String keystoreType : keystoreTypes) 12850 { 12851 final KeyStore ks = CryptoHelper.getKeyStore(keystoreType); 12852 try (FileInputStream inputStream = 12853 new FileInputStream(JVM_DEFAULT_CACERTS_FILE)) 12854 { 12855 ks.load(inputStream, null); 12856 jvmDefaultTrustStore = ks; 12857 jvmDefaultTrustStoreRef.set(jvmDefaultTrustStore); 12858 break; 12859 } 12860 catch (final Exception e) 12861 { 12862 Debug.debugException(e); 12863 } 12864 } 12865 } 12866 12867 if (jvmDefaultTrustStore != null) 12868 { 12869 issuerCertificate = getIssuerCertificate(certificate, 12870 jvmDefaultTrustStore); 12871 } 12872 12873 if (issuerCertificate == null) 12874 { 12875 missingIssuerRef.set(issuerDN); 12876 } 12877 12878 return issuerCertificate; 12879 } 12880 12881 12882 12883 /** 12884 * Attempts to retrieve the issuer certificate for the provided certificate 12885 * from the given keystore. 12886 * 12887 * @param certificate The certificate for which to retrieve the issuer 12888 * certificate. 12889 * @param keystore The keystore in which to look for the issuer 12890 * certificate. 12891 * 12892 * @return The issuer certificate for the provided certificate, or 12893 * {@code null} if the issuer certificate could not be retrieved. 12894 * 12895 * @throws Exception If a problem is encountered while trying to retrieve 12896 * the issuer certificate. 12897 */ 12898 @Nullable() 12899 private static X509Certificate getIssuerCertificate( 12900 @NotNull final X509Certificate certificate, 12901 @NotNull final KeyStore keystore) 12902 throws Exception 12903 { 12904 final Enumeration<String> aliases = keystore.aliases(); 12905 while (aliases.hasMoreElements()) 12906 { 12907 final String alias = aliases.nextElement(); 12908 12909 Certificate[] certs = null; 12910 if (hasCertificateAlias(keystore, alias)) 12911 { 12912 final Certificate c = keystore.getCertificate(alias); 12913 if (c == null) 12914 { 12915 continue; 12916 } 12917 12918 certs = new Certificate[] { c }; 12919 } 12920 else if (hasKeyAlias(keystore, alias)) 12921 { 12922 certs = keystore.getCertificateChain(alias); 12923 } 12924 12925 if (certs != null) 12926 { 12927 for (final Certificate c : certs) 12928 { 12929 final X509Certificate xc = new X509Certificate(c.getEncoded()); 12930 if (xc.isIssuerFor(certificate)) 12931 { 12932 return xc; 12933 } 12934 } 12935 } 12936 } 12937 12938 return null; 12939 } 12940 12941 12942 12943 /** 12944 * Retrieves the authority key identifier value for the provided certificate, 12945 * if present. 12946 * 12947 * @param c The certificate for which to retrieve the authority key 12948 * identifier. 12949 * 12950 * @return The authority key identifier value for the provided certificate, 12951 * or {@code null} if the certificate does not have an authority 12952 * key identifier. 12953 */ 12954 @Nullable() 12955 private static byte[] getAuthorityKeyIdentifier( 12956 @NotNull final X509Certificate c) 12957 { 12958 for (final X509CertificateExtension extension : c.getExtensions()) 12959 { 12960 if (extension instanceof AuthorityKeyIdentifierExtension) 12961 { 12962 final AuthorityKeyIdentifierExtension e = 12963 (AuthorityKeyIdentifierExtension) extension; 12964 if (e.getKeyIdentifier() != null) 12965 { 12966 return e.getKeyIdentifier().getValue(); 12967 } 12968 } 12969 } 12970 12971 return null; 12972 } 12973 12974 12975 12976 /** 12977 * Writes the provided keystore to the specified file. If the keystore file 12978 * already exists, a new temporary file will be created, the old file renamed 12979 * out of the way, the new file renamed into place, and the old file deleted. 12980 * If the keystore file does not exist, then it will simply be created in the 12981 * correct place. 12982 * 12983 * @param keystore The keystore to be written. 12984 * @param keystorePath The path to the keystore file to be written. 12985 * @param keystorePassword The password to use for the keystore. 12986 * 12987 * @throws LDAPException If a problem is encountered while writing the 12988 * keystore. 12989 */ 12990 static void writeKeystore(@NotNull final KeyStore keystore, 12991 @NotNull final File keystorePath, 12992 @Nullable final char[] keystorePassword) 12993 throws LDAPException 12994 { 12995 // If the key store type is PKCS #11, then we don't need to worry about a 12996 // key store file. 12997 if (keystore.getType().equals(CryptoHelper.KEY_STORE_TYPE_PKCS_11)) 12998 { 12999 try 13000 { 13001 keystore.store(null); 13002 return; 13003 } 13004 catch (final Exception e) 13005 { 13006 Debug.debugException(e); 13007 throw new LDAPException(ResultCode.LOCAL_ERROR, 13008 ERR_MANAGE_CERTS_PKCS11_WRITE_ERROR.get( 13009 StaticUtils.getExceptionMessage(e)), 13010 e); 13011 } 13012 } 13013 13014 13015 File copyOfExistingKeystore = null; 13016 final String timestamp = 13017 StaticUtils.encodeGeneralizedTime(System.currentTimeMillis()); 13018 if (keystorePath.exists()) 13019 { 13020 copyOfExistingKeystore = new File(keystorePath.getAbsolutePath() + 13021 ".backup-" + timestamp); 13022 try 13023 { 13024 Files.copy(keystorePath.toPath(), copyOfExistingKeystore.toPath()); 13025 } 13026 catch (final Exception e) 13027 { 13028 Debug.debugException(e); 13029 throw new LDAPException(ResultCode.LOCAL_ERROR, 13030 ERR_MANAGE_CERTS_WRITE_KS_ERROR_COPYING_EXISTING_KS.get( 13031 keystorePath.getAbsolutePath(), 13032 copyOfExistingKeystore.getAbsolutePath(), 13033 StaticUtils.getExceptionMessage(e)), 13034 e); 13035 } 13036 } 13037 13038 try (FileOutputStream outputStream = new FileOutputStream(keystorePath)) 13039 { 13040 keystore.store(outputStream, keystorePassword); 13041 } 13042 catch (final Exception e) 13043 { 13044 Debug.debugException(e); 13045 if (copyOfExistingKeystore == null) 13046 { 13047 throw new LDAPException(ResultCode.LOCAL_ERROR, 13048 ERR_MANAGE_CERTS_WRITE_KS_ERROR_WRITING_NEW_KS.get( 13049 keystorePath.getAbsolutePath(), 13050 StaticUtils.getExceptionMessage(e)), 13051 e); 13052 } 13053 else 13054 { 13055 throw new LDAPException(ResultCode.LOCAL_ERROR, 13056 ERR_MANAGE_CERTS_WRITE_KS_ERROR_OVERWRITING_KS.get( 13057 keystorePath.getAbsolutePath(), 13058 StaticUtils.getExceptionMessage(e), 13059 copyOfExistingKeystore.getAbsolutePath()), 13060 e); 13061 } 13062 } 13063 13064 if (copyOfExistingKeystore != null) 13065 { 13066 try 13067 { 13068 Files.delete(copyOfExistingKeystore.toPath()); 13069 } 13070 catch (final Exception e) 13071 { 13072 Debug.debugException(e); 13073 throw new LDAPException(ResultCode.LOCAL_ERROR, 13074 ERR_MANAGE_CERTS_WRITE_KS_ERROR_DELETING_KS_BACKUP.get( 13075 copyOfExistingKeystore.getAbsolutePath(), 13076 keystorePath.getAbsolutePath(), 13077 StaticUtils.getExceptionMessage(e)), 13078 e); 13079 } 13080 } 13081 } 13082 13083 13084 13085 /** 13086 * Indicates whether the provided keystore has a certificate entry with the 13087 * specified alias. 13088 * 13089 * @param keystore The keystore to examine. 13090 * @param alias The alias for which to make the determination. 13091 * 13092 * @return {@code true} if the keystore has a certificate entry with the 13093 * specified alias, or {@code false} if the alias doesn't exist or 13094 * is associated with some other type of entry (like a key). 13095 */ 13096 private static boolean hasCertificateAlias(@NotNull final KeyStore keystore, 13097 @NotNull final String alias) 13098 { 13099 try 13100 { 13101 return keystore.isCertificateEntry(alias); 13102 } 13103 catch (final Exception e) 13104 { 13105 // This should never happen. If it does, then we'll assume the alias 13106 // doesn't exist or isn't associated with a certificate. 13107 Debug.debugException(e); 13108 return false; 13109 } 13110 } 13111 13112 13113 13114 /** 13115 * Indicates whether the provided keystore has a key entry with the specified 13116 * alias. 13117 * 13118 * @param keystore The keystore to examine. 13119 * @param alias The alias for which to make the determination. 13120 * 13121 * @return {@code true} if the keystore has a key entry with the specified 13122 * alias, or {@code false} if the alias doesn't exist or is 13123 * associated with some other type of entry (like a certificate). 13124 */ 13125 private static boolean hasKeyAlias(@NotNull final KeyStore keystore, 13126 @NotNull final String alias) 13127 { 13128 try 13129 { 13130 return keystore.isKeyEntry(alias); 13131 } 13132 catch (final Exception e) 13133 { 13134 // This should never happen. If it does, then we'll assume the alias 13135 // doesn't exist or isn't associated with a key. 13136 Debug.debugException(e); 13137 return false; 13138 } 13139 } 13140 13141 13142 13143 /** 13144 * Adds arguments for each of the provided extensions to the given list. 13145 * 13146 * @param keytoolArguments The list to which the extension arguments should 13147 * be added. 13148 * @param basicConstraints The basic constraints extension to include. It 13149 * may be {@code null} if this extension should not 13150 * be included. 13151 * @param keyUsage The key usage extension to include. It may be 13152 * {@code null} if this extension should not be 13153 * included. 13154 * @param extendedKeyUsage The extended key usage extension to include. It 13155 * may be {@code null} if this extension should not 13156 * be included. 13157 * @param sanValues The list of subject alternative name values to 13158 * include. It must not be {@code null} but may be 13159 * empty. 13160 * @param ianValues The list of issuer alternative name values to 13161 * include. It must not be {@code null} but may be 13162 * empty. 13163 * @param genericExtensions The list of generic extensions to include. It 13164 * must not be {@code null} but may be empty. 13165 */ 13166 private static void addExtensionArguments( 13167 @NotNull final List<String> keytoolArguments, 13168 @Nullable final BasicConstraintsExtension basicConstraints, 13169 @Nullable final KeyUsageExtension keyUsage, 13170 @Nullable final ExtendedKeyUsageExtension extendedKeyUsage, 13171 @NotNull final Set<String> sanValues, 13172 @NotNull final Set<String> ianValues, 13173 @NotNull final List<X509CertificateExtension> genericExtensions) 13174 { 13175 if (basicConstraints != null) 13176 { 13177 final StringBuilder basicConstraintsValue = new StringBuilder(); 13178 basicConstraintsValue.append("ca:"); 13179 basicConstraintsValue.append(basicConstraints.isCA()); 13180 13181 if (basicConstraints.getPathLengthConstraint() != null) 13182 { 13183 basicConstraintsValue.append(",pathlen:"); 13184 basicConstraintsValue.append( 13185 basicConstraints.getPathLengthConstraint()); 13186 } 13187 13188 keytoolArguments.add("-ext"); 13189 keytoolArguments.add("BasicConstraints=" + basicConstraintsValue); 13190 } 13191 13192 if (keyUsage != null) 13193 { 13194 final StringBuilder keyUsageValue = new StringBuilder(); 13195 if (keyUsage.isDigitalSignatureBitSet()) 13196 { 13197 commaAppend(keyUsageValue, "digitalSignature"); 13198 } 13199 13200 if (keyUsage.isNonRepudiationBitSet()) 13201 { 13202 commaAppend(keyUsageValue, "nonRepudiation"); 13203 } 13204 13205 if (keyUsage.isKeyEnciphermentBitSet()) 13206 { 13207 commaAppend(keyUsageValue, "keyEncipherment"); 13208 } 13209 13210 if (keyUsage.isDataEnciphermentBitSet()) 13211 { 13212 commaAppend(keyUsageValue, "dataEncipherment"); 13213 } 13214 13215 if (keyUsage.isKeyAgreementBitSet()) 13216 { 13217 commaAppend(keyUsageValue, "keyAgreement"); 13218 } 13219 13220 if (keyUsage.isKeyCertSignBitSet()) 13221 { 13222 commaAppend(keyUsageValue, "keyCertSign"); 13223 } 13224 13225 if (keyUsage.isCRLSignBitSet()) 13226 { 13227 commaAppend(keyUsageValue, "cRLSign"); 13228 } 13229 13230 if (keyUsage.isEncipherOnlyBitSet()) 13231 { 13232 commaAppend(keyUsageValue, "encipherOnly"); 13233 } 13234 13235 if (keyUsage.isEncipherOnlyBitSet()) 13236 { 13237 commaAppend(keyUsageValue, "decipherOnly"); 13238 } 13239 13240 keytoolArguments.add("-ext"); 13241 keytoolArguments.add("KeyUsage=" + keyUsageValue); 13242 } 13243 13244 if (extendedKeyUsage != null) 13245 { 13246 final StringBuilder extendedKeyUsageValue = new StringBuilder(); 13247 for (final OID oid : extendedKeyUsage.getKeyPurposeIDs()) 13248 { 13249 final ExtendedKeyUsageID id = ExtendedKeyUsageID.forOID(oid); 13250 if (id == null) 13251 { 13252 commaAppend(extendedKeyUsageValue, oid.toString()); 13253 } 13254 else 13255 { 13256 switch (id) 13257 { 13258 case TLS_SERVER_AUTHENTICATION: 13259 commaAppend(extendedKeyUsageValue, "serverAuth"); 13260 break; 13261 case TLS_CLIENT_AUTHENTICATION: 13262 commaAppend(extendedKeyUsageValue, "clientAuth"); 13263 break; 13264 case CODE_SIGNING: 13265 commaAppend(extendedKeyUsageValue, "codeSigning"); 13266 break; 13267 case EMAIL_PROTECTION: 13268 commaAppend(extendedKeyUsageValue, "emailProtection"); 13269 break; 13270 case TIME_STAMPING: 13271 commaAppend(extendedKeyUsageValue, "timeStamping"); 13272 break; 13273 case OCSP_SIGNING: 13274 commaAppend(extendedKeyUsageValue, "OCSPSigning"); 13275 break; 13276 default: 13277 // This should never happen. 13278 commaAppend(extendedKeyUsageValue, id.getOID().toString()); 13279 break; 13280 } 13281 } 13282 } 13283 13284 keytoolArguments.add("-ext"); 13285 keytoolArguments.add("ExtendedKeyUsage=" + extendedKeyUsageValue); 13286 } 13287 13288 if (! sanValues.isEmpty()) 13289 { 13290 final StringBuilder subjectAltNameValue = new StringBuilder(); 13291 for (final String sanValue : sanValues) 13292 { 13293 commaAppend(subjectAltNameValue, sanValue); 13294 } 13295 13296 keytoolArguments.add("-ext"); 13297 keytoolArguments.add("SAN=" + subjectAltNameValue); 13298 } 13299 13300 if (! ianValues.isEmpty()) 13301 { 13302 final StringBuilder issuerAltNameValue = new StringBuilder(); 13303 for (final String ianValue : ianValues) 13304 { 13305 commaAppend(issuerAltNameValue, ianValue); 13306 } 13307 13308 keytoolArguments.add("-ext"); 13309 keytoolArguments.add("IAN=" + issuerAltNameValue); 13310 } 13311 13312 for (final X509CertificateExtension e : genericExtensions) 13313 { 13314 keytoolArguments.add("-ext"); 13315 if (e.isCritical()) 13316 { 13317 keytoolArguments.add(e.getOID().toString() + ":critical=" + 13318 toColonDelimitedHex(e.getValue())); 13319 } 13320 else 13321 { 13322 keytoolArguments.add(e.getOID().toString() + '=' + 13323 toColonDelimitedHex(e.getValue())); 13324 } 13325 } 13326 } 13327 13328 13329 13330 /** 13331 * Appends the provided value to the given buffer. If the buffer is not 13332 * empty, the new value will be preceded by a comma. There will not be any 13333 * spaces on either side of the comma. 13334 * 13335 * @param buffer The buffer to which the value should be appended. 13336 * @param value The value to append to the buffer. 13337 */ 13338 private static void commaAppend(@NotNull final StringBuilder buffer, 13339 @NotNull final String value) 13340 { 13341 if (buffer.length() > 0) 13342 { 13343 buffer.append(','); 13344 } 13345 13346 buffer.append(value); 13347 } 13348 13349 13350 13351 /** 13352 * Retrieves a set of information that may be used to generate example usage 13353 * information. Each element in the returned map should consist of a map 13354 * between an example set of arguments and a string that describes the 13355 * behavior of the tool when invoked with that set of arguments. 13356 * 13357 * @return A set of information that may be used to generate example usage 13358 * information. It may be {@code null} or empty if no example usage 13359 * information is available. 13360 */ 13361 @Override() 13362 @NotNull() 13363 public LinkedHashMap<String[],String> getExampleUsages() 13364 { 13365 final String keystorePath = getPlatformSpecificPath("config", "keystore"); 13366 final String keystorePWPath = 13367 getPlatformSpecificPath("config", "keystore.pin"); 13368 final String privateKeyPWPath = 13369 getPlatformSpecificPath("config", "server-cert-private-key.pin"); 13370 final String exportCertOutputFile = 13371 getPlatformSpecificPath("server-cert.crt"); 13372 final String exportKeyOutputFile = 13373 getPlatformSpecificPath("server-cert.private-key"); 13374 final String genCSROutputFile = getPlatformSpecificPath("server-cert.csr"); 13375 final String truststorePath = 13376 getPlatformSpecificPath("config", "truststore"); 13377 final String truststorePWPath = 13378 getPlatformSpecificPath("config", "truststore.pin"); 13379 13380 final LinkedHashMap<String[],String> examples = 13381 new LinkedHashMap<>(StaticUtils.computeMapCapacity(20)); 13382 13383 examples.put( 13384 new String[] 13385 { 13386 "list-certificates", 13387 "--keystore", keystorePath, 13388 "--keystore-password-file", keystorePWPath, 13389 "--verbose", 13390 "--display-keytool-command" 13391 }, 13392 INFO_MANAGE_CERTS_EXAMPLE_LIST_1.get(keystorePath)); 13393 13394 examples.put( 13395 new String[] 13396 { 13397 "export-certificate", 13398 "--keystore", keystorePath, 13399 "--keystore-password-file", keystorePWPath, 13400 "--alias", "server-cert", 13401 "--output-file", exportCertOutputFile, 13402 "--output-format", "PEM", 13403 "--verbose", 13404 "--display-keytool-command" 13405 }, 13406 INFO_MANAGE_CERTS_EXAMPLE_EXPORT_CERT_1.get(keystorePath, 13407 exportCertOutputFile)); 13408 13409 examples.put( 13410 new String[] 13411 { 13412 "export-private-key", 13413 "--keystore", keystorePath, 13414 "--keystore-password-file", keystorePWPath, 13415 "--private-key-password-file", privateKeyPWPath, 13416 "--alias", "server-cert", 13417 "--output-file", exportKeyOutputFile, 13418 "--output-format", "PEM", 13419 "--verbose", 13420 "--display-keytool-command" 13421 }, 13422 INFO_MANAGE_CERTS_EXAMPLE_EXPORT_KEY_1.get(keystorePath, 13423 exportKeyOutputFile)); 13424 13425 examples.put( 13426 new String[] 13427 { 13428 "import-certificate", 13429 "--keystore", keystorePath, 13430 "--keystore-type", "JKS", 13431 "--keystore-password-file", keystorePWPath, 13432 "--alias", "server-cert", 13433 "--certificate-file", exportCertOutputFile, 13434 "--private-key-file", exportKeyOutputFile, 13435 "--display-keytool-command" 13436 }, 13437 INFO_MANAGE_CERTS_EXAMPLE_IMPORT_1.get(exportCertOutputFile, 13438 exportKeyOutputFile, keystorePath)); 13439 13440 examples.put( 13441 new String[] 13442 { 13443 "delete-certificate", 13444 "--keystore", keystorePath, 13445 "--keystore-password-file", keystorePWPath, 13446 "--alias", "server-cert" 13447 }, 13448 INFO_MANAGE_CERTS_EXAMPLE_DELETE_1.get(keystorePath)); 13449 13450 examples.put( 13451 new String[] 13452 { 13453 "generate-self-signed-certificate", 13454 "--keystore", keystorePath, 13455 "--keystore-type", "PKCS12", 13456 "--keystore-password-file", keystorePWPath, 13457 "--alias", "ca-cert", 13458 "--subject-dn", "CN=Example Authority,O=Example Corporation,C=US", 13459 "--days-valid", "7300", 13460 "--validity-start-time", "20170101000000", 13461 "--key-algorithm", "RSA", 13462 "--key-size-bits", "4096", 13463 "--signature-algorithm", "SHA256withRSA", 13464 "--basic-constraints-is-ca", "true", 13465 "--key-usage", "key-cert-sign", 13466 "--key-usage", "crl-sign", 13467 "--display-keytool-command" 13468 }, 13469 INFO_MANAGE_CERTS_EXAMPLE_GEN_CERT_1.get(keystorePath)); 13470 13471 examples.put( 13472 new String[] 13473 { 13474 "generate-certificate-signing-request", 13475 "--keystore", keystorePath, 13476 "--keystore-type", "PKCS12", 13477 "--keystore-password-file", keystorePWPath, 13478 "--output-file", genCSROutputFile, 13479 "--alias", "server-cert", 13480 "--subject-dn", "CN=ldap.example.com,O=Example Corporation,C=US", 13481 "--key-algorithm", "EC", 13482 "--key-size-bits", "256", 13483 "--signature-algorithm", "SHA256withECDSA", 13484 "--subject-alternative-name-dns", "ldap1.example.com", 13485 "--subject-alternative-name-dns", "ldap2.example.com", 13486 "--extended-key-usage", "server-auth", 13487 "--extended-key-usage", "client-auth", 13488 "--display-keytool-command" 13489 }, 13490 INFO_MANAGE_CERTS_EXAMPLE_GEN_CSR_1.get(keystorePath, 13491 genCSROutputFile)); 13492 13493 examples.put( 13494 new String[] 13495 { 13496 "generate-certificate-signing-request", 13497 "--keystore", keystorePath, 13498 "--keystore-password-file", keystorePWPath, 13499 "--alias", "server-cert", 13500 "--use-existing-key-pair", 13501 "--inherit-extensions", 13502 "--display-keytool-command" 13503 }, 13504 INFO_MANAGE_CERTS_EXAMPLE_GEN_CSR_2.get(keystorePath)); 13505 13506 examples.put( 13507 new String[] 13508 { 13509 "sign-certificate-signing-request", 13510 "--keystore", keystorePath, 13511 "--keystore-password-file", keystorePWPath, 13512 "--request-input-file", genCSROutputFile, 13513 "--certificate-output-file", exportCertOutputFile, 13514 "--alias", "ca-cert", 13515 "--days-valid", "730", 13516 "--include-requested-extensions", 13517 "--display-keytool-command" 13518 }, 13519 INFO_MANAGE_CERTS_EXAMPLE_SIGN_CERT_1.get(keystorePath, 13520 genCSROutputFile, exportCertOutputFile)); 13521 13522 examples.put( 13523 new String[] 13524 { 13525 "change-certificate-alias", 13526 "--keystore", keystorePath, 13527 "--keystore-password-file", keystorePWPath, 13528 "--current-alias", "server-cert", 13529 "--new-alias", "server-certificate", 13530 "--display-keytool-command" 13531 }, 13532 INFO_MANAGE_CERTS_EXAMPLE_CHANGE_ALIAS_1.get(keystorePath, 13533 genCSROutputFile, exportCertOutputFile)); 13534 13535 examples.put( 13536 new String[] 13537 { 13538 "change-keystore-password", 13539 "--keystore", getPlatformSpecificPath("config", "keystore"), 13540 "--current-keystore-password-file", 13541 getPlatformSpecificPath("config", "current.pin"), 13542 "--new-keystore-password-file", 13543 getPlatformSpecificPath("config", "new.pin"), 13544 "--display-keytool-command" 13545 }, 13546 INFO_MANAGE_CERTS_SC_CHANGE_KS_PW_EXAMPLE_1.get( 13547 getPlatformSpecificPath("config", "keystore"), 13548 getPlatformSpecificPath("config", "current.pin"), 13549 getPlatformSpecificPath("config", "new.pin"))); 13550 13551 examples.put( 13552 new String[] 13553 { 13554 "retrieve-server-certificate", 13555 "--hostname", "ds.example.com", 13556 "--port", "636" 13557 }, 13558 INFO_MANAGE_CERTS_SC_RETRIEVE_CERT_EXAMPLE_1.get( 13559 getPlatformSpecificPath("config", "truststore"))); 13560 13561 examples.put( 13562 new String[] 13563 { 13564 "copy-keystore", 13565 "--source-keystore", 13566 getPlatformSpecificPath("config", "keystore.jks"), 13567 "--source-keystore-password-file", 13568 getPlatformSpecificPath("config", "keystore.pin"), 13569 "--source-keystore-type", "JKS", 13570 "--destination-keystore", 13571 getPlatformSpecificPath("config", "keystore.p12"), 13572 "--destination-keystore-password-file", 13573 getPlatformSpecificPath("config", "keystore.pin"), 13574 "--destination-keystore-type", "PKCS12" 13575 }, 13576 INFO_MANAGE_CERTS_SC_COPY_KS_EXAMPLE_1.get("keystore.jks", 13577 "keystore.p12")); 13578 13579 examples.put( 13580 new String[] 13581 { 13582 "trust-server-certificate", 13583 "--hostname", "ldap.example.com", 13584 "--port", "636", 13585 "--keystore", truststorePath, 13586 "--keystore-password-file", truststorePWPath, 13587 "--alias", "ldap.example.com:636" 13588 }, 13589 INFO_MANAGE_CERTS_EXAMPLE_TRUST_SERVER_1.get(truststorePath)); 13590 13591 examples.put( 13592 new String[] 13593 { 13594 "check-certificate-usability", 13595 "--keystore", keystorePath, 13596 "--keystore-password-file", keystorePWPath, 13597 "--alias", "server-cert" 13598 }, 13599 INFO_MANAGE_CERTS_EXAMPLE_CHECK_USABILITY_1.get(keystorePath)); 13600 13601 examples.put( 13602 new String[] 13603 { 13604 "display-certificate-file", 13605 "--certificate-file", exportCertOutputFile, 13606 "--verbose", 13607 "--display-keytool-command" 13608 }, 13609 INFO_MANAGE_CERTS_EXAMPLE_DISPLAY_CERT_1.get(keystorePath)); 13610 13611 examples.put( 13612 new String[] 13613 { 13614 "display-certificate-signing-request-file", 13615 "--certificate-signing-request-file", genCSROutputFile, 13616 "--display-keytool-command" 13617 }, 13618 INFO_MANAGE_CERTS_EXAMPLE_DISPLAY_CSR_1.get(keystorePath)); 13619 13620 examples.put( 13621 new String[] 13622 { 13623 "--help-subcommands" 13624 }, 13625 INFO_MANAGE_CERTS_EXAMPLE_HELP_SUBCOMMANDS_1.get(keystorePath)); 13626 13627 return examples; 13628 } 13629}