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