Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

APPSERV-149 Add Command to Generate Self-Signed Certificate #4694

Merged
merged 9 commits into from
Jun 5, 2020

Conversation

Pandrex247
Copy link
Member

@Pandrex247 Pandrex247 commented Jun 2, 2020

Description

Adds a CLI command for generating a self-signed certificate and storing in a target instance's or listener's key and trust stores.

SYNOPSIS
generate-self-signed-certificate [--help]
[--domain_name domain-name] [--domaindir domain-dir]
[--target instance-name] [--listener listener-name]
[alternativenames (type:value)[;type:value]*]
--distinguishedname
alias

DESCRIPTION
The generate-self-signed-certificate subcommand generates a self-
signed certificate using the provided distinguished name, alias, and
any provided alternative names. This certificate is then placed in
the key and trust store of the target instance or listener.

   If the instance or listener is configured to use the default key and
   trust store, the command will instead synchronise the instance with
   the DAS (under the assumption the certificate has been added to the
   default key and trust store of the DAS), since any certificates added
   to the instance stores would be lost upon next synchronisation.

OPTIONS
--help, -?
Displays the help text for the subcommand.

   --domain_name
       The unique name of the domain you want to start. This operand is
       optional, defaulting to domain1 if not provided.

   --domaindir
       The domain root directory, which contains the directory of the
       target domain. If specified, the path must be accessible in the
       file system. The default location of the domain root directory
       is as-install/domains.

   --target
       The name of the instance to add the generated certificate to the
       key and trust store of. Defaults to server (the DAS).

   --listener
       The name of the HTTP or IIOP listener to add the generated
       certificate to the key and trust store of. Only applicable if
       the listener has a key or trust store different to that of the
       instance itself.

   --alternativenames, --altnames
       The subject alternative names to add to the generated certificate.
       Takes the form of a semi-colon separated list of type:value. If no
       type is given, it is assumed to be DNS.

OPERANDS
--distinguishedname, --dn
The distinguished name to use when generating the certificate.

   alias
       The alias to use when generating the certificate and storing it
       in the key and trust stores. If the alias already exists in the
       key store, the command will fail. If the alias already exists in
       the trust store, this trusted certificate will be overwritten.

EXAMPLES
Example 1, Creating a Self-Signed Certificate for the DAS

       This example creates a self-signed certificate for the DAS.

           asadmin> generate-self-signed-certificate --dn "CN=test.payara.fish" test_cert1

   Example 2, Created a Self-Signed Certificate for a Listener

       This example creates a self-signed certificate with alternative
       names for the http-listner-2 listener of an instance named Guppy1.

           asadmin> generate-self-signed-certificate --dn "CN=test.payara.fish"
           --listener http-listener-2
           --alternativenames "test2.payara.fish;DNS:test3.payara.fish,IP:127.0.0.1,EMAIL:[email protected]"
           --target Guppy1
           test_cert2

Testing

New tests

Unit test that ensures that alternatives names are added to the keytool command in the expected format.

Testing Performed

  • Add cert to default DAS using default key and trust stores
  • Add cert to default DAS using custom key store and default trust store
  • Add cert to default DAS using custom trust store and default key store
  • Add cert to default DAS using custom key store and custom trust store
  • Add cert to non-default DAS using default key and trust stores
  • Add cert to non-default DAS using custom key store and custom trust store
  • Add cert to default DAS using default key and trust stores in non-default domaindir
  • Add cert to instance using default key and trust stores - should reject and attempt to sync with DAS
  • Add cert to instance using custom key and default trust stores - should reject and attempt to sync with DAS, warning user to manually add cert to key store
  • Add cert to instance using default key and custom trust stores - should reject and attempt to sync with DAS, warning user to manually add cert to trust store
  • Add cert to instance using custom key and custom trust stores - should generate certificate and place in key and trust store
  • Add cert to default DAS using default key and trust stores when cert already exists - should reject
  • Add cert to default DAS using default key and trust stores when cert already exists only in key store - should reject
  • Add cert to default DAS using default key and trust stores when cert already exists only in trust store - should add cert to key store and override cert in trust store.
  • Add cert to default DAS http2-listener using default key and trust stores - should add cert to key and trust stores if not already present
  • Add cert to default DAS http2-listener using custom key and trust stores - should add cert to key and trust stores if not already present
  • Add cert to default DAS http2-listener using custom key and default trust stores - should add cert to key and trust stores if not already present
  • Add cert to instance http2-listener using custom key and default trust stores - should reject and attempt to sync with DAS, warning user to manually add cert to key store
  • Add cert to default DAS using default key and trust stores with changed master password
  • Add cert to default DAS http2-listener using custom key and trust stores with stores protected by a different password to the master (store passwords set using set command)
  • Add cert to default DAS http2-listener using different custom key and trust stores with stores protected by a different passwords to the master (store passwords set using set command)
  • Add cert to default DAS http2-listener using custom key and trust stores with stores protected by a password alias (store passwords set using set command)

Testing Environment

Windows 10, JDK 8.

Notes for Reviewers

HTTP and IIOP listeners do not automatically reload any changes to their configuration, which includes changes to a configured key store or certificate. You do not need to restart the server to refresh the configuration however, you can simply restart the listener by disabling and re-enabling it.

Also note listeners are lazy loaded.

I'd appreciate it if you also redid all (or at least some) of my manual tests, or any scenarios I've missed.

To build please specify the BuildExtras profile and manually copy-pasta the Jar from appserver/extras/certificate-management/ into the payara5/glassfish/lib/asadmin directory.

@Pandrex247
Copy link
Member Author

Jenkins test please

@jbee jbee self-requested a review June 4, 2020 12:13
Copy link
Contributor

@jbee jbee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't say I can reason much about the process or its details. Managed to find two NPE issues. Otherwise only some minor style comments.

import org.junit.Assert;
import org.junit.Test;

public class GenerateSelfSignedCertificateCommandTest extends CertificateManagementUtils {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extending the util has a bit of a taste. I'd prefer using static method imports to use the util methods without qualified access.

truststorePassword = CertificateManagementUtils.getPasswordFromListener(parser, listener, "trust-store-password");
}

if (keystorePassword != null || keystorePassword.length > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing suggests that this should be if (keystorePassword != null && keystorePassword.length > 0) {

for (Map<String, String> listenerAttributes : parser.getProtocolAttributes()) {
if (listenerAttributes.get("name").equals(listener)) {
// Get the keystore from the listener if it has a custom one
password = listenerAttributes.get(attribute).toCharArray();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes a NPE when listenerAttributes does not have a password attribute which I apparently managed to create as test case. I suspect the same applies to the assignment in 312.

@Pandrex247
Copy link
Member Author

Jenkins test please

@Pandrex247 Pandrex247 merged commit 4e865c4 into payara:master Jun 5, 2020
@Pandrex247 Pandrex247 deleted the APPSERV-149 branch March 29, 2022 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants