You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@nifi.apache.org by brosander <gi...@git.apache.org> on 2016/07/20 20:56:05 UTC

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

GitHub user brosander opened a pull request:

    https://github.com/apache/nifi/pull/695

    NIFI-2193 - Command line SSL config utility as well as certificate au\u2026

    \u2026thority client/server

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/brosander/nifi NIFI-2193-pr

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/nifi/pull/695.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #695
    
----
commit 496f4f9cdc3cfee43e34684814c72f674261940d
Author: Bryan Rosander <br...@gmail.com>
Date:   2016-07-06T20:56:08Z

    NIFI-2193 - Command line SSL config utility as well as certificate authority client/server

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72655092
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    +        keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase, certificates);
    +    }
    +
    +    public KeyStore createKeyStore(String keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException {
    +        KeyStore keyStore;
    +        if (PKCS12.equals(keyStoreType)) {
    +            keyStore = KeyStore.getInstance(keyStoreType, BouncyCastleProvider.PROVIDER_NAME);
    +        } else {
    +            keyStore = KeyStore.getInstance(keyStoreType);
    +        }
    +        keyStore.load(null, null);
    +        return keyStore;
    +    }
    +
    +    public X509Certificate generateSelfSignedX509Certificate(KeyPair keyPair, String dn) throws CertificateException {
    +        return CertificateUtils.generateSelfSignedX509Certificate(keyPair, dn, signingAlgorithm, days);
    +    }
    +
    +    public X509Certificate generateIssuedCertificate(String dn, PublicKey publicKey, X509Certificate issuer, KeyPair issuerKeyPair) throws CertificateException {
    +        return CertificateUtils.generateIssuedCertificate(dn, publicKey, issuer, issuerKeyPair, signingAlgorithm, days);
    +    }
    +
    +    public JcaPKCS10CertificationRequest generateCertificationRequest(String requestedDn, KeyPair keyPair) throws OperatorCreationException {
    +        JcaPKCS10CertificationRequestBuilder jcaPKCS10CertificationRequestBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Principal(requestedDn), keyPair.getPublic());
    +        JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(signingAlgorithm);
    +        return new JcaPKCS10CertificationRequest(jcaPKCS10CertificationRequestBuilder.build(jcaContentSignerBuilder.build(keyPair.getPrivate())));
    +    }
    +
    +    public X509Certificate signCsr(JcaPKCS10CertificationRequest certificationRequest, X509Certificate issuer, KeyPair issuerKeyPair) throws InvalidKeySpecException, EACException,
    --- End diff --
    
    Can these exceptions be collapsed into a couple "families" -- IO exception vs. crypto exception? The specific failures are probably not important to the caller.  


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73189115
  
    --- Diff: nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/CertificateUtilsTest.groovy ---
    @@ -53,6 +54,21 @@ import java.security.SignatureException
     import java.security.cert.Certificate
     import java.security.cert.CertificateException
     import java.security.cert.X509Certificate
    +import java.util.concurrent.TimeUnit
    +
    +import static org.junit.Assert.assertEquals
    --- End diff --
    
    Is this a bug? Why are the same two static methods imported 5-8 times each?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72468924
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    --- End diff --
    
    Transitive from org.apache.nifi:nifi-security-utils:jar:1.0.0-SNAPSHOT:compile


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72460515
  
    --- Diff: nifi-assembly/pom.xml ---
    @@ -363,147 +363,6 @@ language governing permissions and limitations under the License. -->
             </dependency>
         </dependencies>
     
    -    <properties>
    --- End diff --
    
    I just built it and there was no "nifi.properties" bundled in the assembly.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    I am merging this for the beta release tomorrow. There are still some rough edges, and those are being captured in [NIFI-2476](https://issues.apache.org/jira/browse/NIFI-2476). The documentation for using the tools here is temporarily provided in the original Jira [NIFI-2193](https://issues.apache.org/jira/browse/NIFI-2193) until it can be properly reviewed and merged into the User Guide and Admin Guide [NIFI-2477](https://issues.apache.org/jira/browse/NIFI-2477). 
    
    I will run contrib-check, rebase, squash, and merge. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73194331
  
    --- Diff: nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/CertificateUtilsTest.groovy ---
    @@ -53,6 +54,21 @@ import java.security.SignatureException
     import java.security.cert.Certificate
     import java.security.cert.CertificateException
     import java.security.cert.X509Certificate
    +import java.util.concurrent.TimeUnit
    +
    +import static org.junit.Assert.assertEquals
    --- End diff --
    
    maybe auto import fail? will fix


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73270563
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    +
    +    private String token;
    +    private String configJson;
    +    private boolean onlyUseConfigJson;
    +    private int port;
    +    private String dn;
    +
    +    public BaseCertificateAuthorityCommandLine(String header) {
    +        super(header);
    +        addOptionWithArg("t", TOKEN_ARG, "The token to use to prevent MITM (required and must be same as one used by CA)");
    +        addOptionWithArg("f", CONFIG_JSON_ARG, "The place to write configuration info", DEFAULT_CONFIG_JSON);
    +        addOptionNoArg("F", USE_CONFIG_JSON_ARG, "Flag specifying that all configuration is read from " + CONFIG_JSON_ARG + " to facilitate automated use (otherwise "
    +                + CONFIG_JSON_ARG + " will only be written to.");
    +        addOptionWithArg("p", PORT_ARG, "The port to use to communicate with the Certificate Authority", TlsConfig.DEFAULT_PORT);
    +        addOptionWithArg("D", DN_ARG, "The dn to use for the certificate", TlsConfig.calcDefaultDn(TlsConfig.DEFAULT_HOSTNAME));
    --- End diff --
    
    Also same message for both client and server, will change to abstract method here and override


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73256427
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    --- End diff --
    
    The absolute path is often very long (when running from inside the built location, it is at least 114 characters). 
    
    Example:
    
    ```bash
    -f,--configJson <arg>                     The place to write configuration info (default:
                                               /Users/alopresto/Workspace/nifi/nifi-toolkit/nifi-toolkit-assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT/config.json)
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73255485
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLine.java ---
    @@ -0,0 +1,125 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service.client;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.service.BaseCertificateAuthorityCommandLine;
    +import org.apache.nifi.toolkit.tls.util.InputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +
    +import java.io.File;
    +import java.io.FileInputStream;
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +public class TlsCertificateAuthorityClientCommandLine extends BaseCertificateAuthorityCommandLine {
    +    public static final String DESCRIPTION = "Generates a private key and gets it signed by the certificate authority.";
    +    public static final String PKCS_12 = "PKCS12";
    +    public static final String CERTIFICATE_DIRECTORY = "certificateDirectory";
    +    public static final String DEFAULT_CERTIFICATE_DIRECTORY = ".";
    +    public static final String SAME_KEY_AND_KEY_STORE_PASSWORD_ARG = "sameKeyAndKeyStorePassword";
    +
    +    private final InputStreamFactory inputStreamFactory;
    +
    +    private String certificateDirectory;
    +    private boolean sameKeyAndKeyStorePassword;
    +
    +    public TlsCertificateAuthorityClientCommandLine() {
    +        this(FileInputStream::new);
    +    }
    +
    +    public TlsCertificateAuthorityClientCommandLine(InputStreamFactory inputStreamFactory) {
    +        super(DESCRIPTION);
    +        this.inputStreamFactory = inputStreamFactory;
    +        addOptionWithArg("C", CERTIFICATE_DIRECTORY, "The file to write the CA certificate to", DEFAULT_CERTIFICATE_DIRECTORY);
    +        addOptionNoArg("S", SAME_KEY_AND_KEY_STORE_PASSWORD_ARG, "When generating passwords, use the same one for KeyStore and Key");
    +    }
    +
    +    public static void main(String[] args) throws Exception {
    +        TlsHelper.addBouncyCastleProvider();
    +        TlsCertificateAuthorityClientCommandLine tlsCertificateAuthorityClientCommandLine = new TlsCertificateAuthorityClientCommandLine();
    +        try {
    +            tlsCertificateAuthorityClientCommandLine.parse(args);
    +        } catch (CommandLineParseException e) {
    +            System.exit(e.getExitCode());
    +        }
    +        new TlsCertificateAuthorityClient().generateCertificateAndGetItSigned(tlsCertificateAuthorityClientCommandLine.createClientConfig(),
    +                tlsCertificateAuthorityClientCommandLine.getCertificateDirectory(), tlsCertificateAuthorityClientCommandLine.getConfigJson(),
    +                tlsCertificateAuthorityClientCommandLine.sameKeyAndKeyStorePassword());
    +        System.exit(ExitCode.SUCCESS.ordinal());
    +    }
    +
    +    @Override
    +    protected boolean shouldAddDaysArg() {
    +        return false;
    +    }
    +
    +    @Override
    +    protected boolean shouldAddSigningAlgorithmArg() {
    +        return false;
    +    }
    +
    +    @Override
    +    protected String getKeyStoreTypeDefault() {
    +        return PKCS_12;
    +    }
    +
    +    @Override
    +    protected CommandLine doParse(String[] args) throws CommandLineParseException {
    +        CommandLine commandLine = super.doParse(args);
    +        certificateDirectory = commandLine.getOptionValue(CERTIFICATE_DIRECTORY, DEFAULT_CERTIFICATE_DIRECTORY);
    +        sameKeyAndKeyStorePassword = commandLine.hasOption(SAME_KEY_AND_KEY_STORE_PASSWORD_ARG);
    +        return commandLine;
    +    }
    +
    +    public boolean sameKeyAndKeyStorePassword() {
    +        return sameKeyAndKeyStorePassword;
    +    }
    +
    +    public String getCertificateDirectory() {
    +        return certificateDirectory;
    +    }
    +
    +    public TlsClientConfig createClientConfig() throws IOException {
    +        if (onlyUseConfigJson()) {
    +            try (InputStream inputStream = inputStreamFactory.create(new File(getConfigJson()))) {
    +                TlsClientConfig tlsClientConfig = new ObjectMapper().readValue(inputStream, TlsClientConfig.class);
    +                tlsClientConfig.initDefaults();
    +                return tlsClientConfig;
    +            }
    +        } else {
    +            TlsClientConfig tlsClientConfig = new TlsClientConfig();
    +            tlsClientConfig.setCaHostname(getCertificateAuthorityHostname());
    +            tlsClientConfig.setDn(getDn());
    +            tlsClientConfig.setToken(getToken());
    +            tlsClientConfig.setPort(getPort());
    +            tlsClientConfig.setKeyStore(KEYSTORE + getKeyStoreType().toLowerCase());
    +            tlsClientConfig.setKeyStoreType(getKeyStoreType());
    +            tlsClientConfig.setTrustStore(TRUSTSTORE + getKeyStoreType().toLowerCase());
    --- End diff --
    
    This gets the default keystore type (`PKCS12`) to use for the truststore as well. The truststore rarely ever needs to be `PKCS12` as there is no private key information in it. I am not sure why the default (even for keystores) is not `JKS`?
    
    Example:
    
    ```bash
    hw12203:...assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT (pr695) alopresto
    \U0001f513 113s @ 16:01:50 $ ./bin/tls-toolkit.sh client -D CN=client.nifi.apache.org -t shorttoken
    log4j:WARN No appenders could be found for logger (org.apache.http.client.protocol.RequestAddCookies).
    log4j:WARN Please initialize the log4j system properly.
    log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    hw12203:...assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT (pr695) alopresto
    \U0001f513 43s @ 16:02:33 $ tl
    .
    ...
    \u251c\u2500\u2500 [ 520]  config.json
    \u251c\u2500\u2500 [3.3K]  keystore.pkcs12
    ...
    \u251c\u2500\u2500 [2.1K]  nifi-ca-keystore.jks
    \u251c\u2500\u2500 [1.1K]  nifi-cert
    \u251c\u2500\u2500 [1.2K]  rootCert.crt
    \u251c\u2500\u2500 [1.6K]  rootCert.key
    \u2514\u2500\u2500 [1.1K]  truststore.pkcs12
    
    3 directories, 36 files
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/nifi/pull/695


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72485755
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    --- End diff --
    
    @JPercivall I would think the LICENSE and NOTICE files for an assembly should contain needed info for any/all artifacts that make their way into the distribution.  If that's not the case, I can remove.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    @alopresto I think I've incorporated your feedback, please let me know if you see anything else that needs addressing before the beta, otherwise I agree that as people use it, we'll get more information on what could/should be improved


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    Ok I will build locally, smoke test, run contrib check, and if all pass, rebase/squash and merge into `master`. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72714290
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateSigningRequestPerformer.java ---
    @@ -0,0 +1,144 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.IOUtils;
    +import org.apache.commons.io.input.BoundedInputStream;
    +import org.apache.http.HttpHost;
    +import org.apache.http.client.methods.CloseableHttpResponse;
    +import org.apache.http.client.methods.HttpPost;
    +import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
    +import org.apache.http.entity.ByteArrayEntity;
    +import org.apache.http.impl.client.CloseableHttpClient;
    +import org.apache.http.impl.client.HttpClientBuilder;
    +import org.apache.http.ssl.SSLContextBuilder;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Response;
    +
    +import java.io.IOException;
    +import java.nio.charset.StandardCharsets;
    +import java.security.KeyPair;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.cert.X509Certificate;
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.function.Supplier;
    +
    +public class TlsCertificateSigningRequestPerformer {
    +    public static final String RECEIVED_RESPONSE_CODE = "Received response code ";
    +    public static final String EXPECTED_ONE_CERTIFICATE = "Expected one certificate";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_HMAC = "Expected response to contain hmac";
    +    public static final String UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE = "Unexpected hmac received, possible man in the middle";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE = "Expected response to contain certificate";
    +    private final Supplier<HttpClientBuilder> httpClientBuilderSupplier;
    +    private final String caHostname;
    +    private final String dn;
    +    private final String token;
    +    private final int port;
    +    private final TlsHelper tlsHelper;
    +
    +    public TlsCertificateSigningRequestPerformer(TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(HttpClientBuilder::create, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    --- End diff --
    
    I don't see any external invocations of the two constructors that pass the `Supplier<HttpClientBuilder>` argument. I'm all for dependency injection, but is this something that needs to be provided externally?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882313
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityClientSocketFactory.java ---
    @@ -0,0 +1,77 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.http.HttpHost;
    +import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    +import org.apache.http.protocol.HttpContext;
    +import org.bouncycastle.asn1.x500.style.BCStyle;
    +import org.bouncycastle.asn1.x500.style.IETFUtils;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
    +
    +import javax.net.ssl.SSLContext;
    +import javax.net.ssl.SSLSocket;
    +import java.io.IOException;
    +import java.net.InetSocketAddress;
    +import java.net.Socket;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +/**
    + * Socket Factory validates that it is talking to a RootCa claiming to have the given hostname.  It adds the certificate
    + * to a list for later validation against the payload's hmac
    + */
    +public class TlsCertificateAuthorityClientSocketFactory extends SSLConnectionSocketFactory {
    +    private final String caHostname;
    +    private final List<X509Certificate> certificates;
    +
    +    public TlsCertificateAuthorityClientSocketFactory(SSLContext sslContext, String caHostname, List<X509Certificate> certificates) {
    +        super(sslContext);
    +        this.caHostname = caHostname;
    +        this.certificates = certificates;
    +    }
    +
    +    @Override
    +    public synchronized Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress,
    +                                             InetSocketAddress localAddress, HttpContext context) throws IOException {
    +        Socket result = super.connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, context);
    +        if (!SSLSocket.class.isInstance(result)) {
    +            throw new IOException("Expected tls socket");
    +        }
    +        SSLSocket sslSocket = (SSLSocket) result;
    +        java.security.cert.Certificate[] peerCertificateChain = sslSocket.getSession().getPeerCertificates();
    +        if (peerCertificateChain.length != 1) {
    +            throw new IOException("Expected root ca cert");
    +        }
    +        if (!X509Certificate.class.isInstance(peerCertificateChain[0])) {
    +            throw new IOException("Expected root ca cert in X509 format");
    +        }
    +        String cn;
    +        try {
    +            X509Certificate certificate = (X509Certificate) peerCertificateChain[0];
    +            cn = IETFUtils.valueToString(new JcaX509CertificateHolder(certificate).getSubject().getRDNs(BCStyle.CN)[0].getFirst().getValue());
    --- End diff --
    
    I'm not really interested in the whole dn, only the cn to let the client check the the CA at least claims to be the right one.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72470842
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/pom.xml ---
    @@ -0,0 +1,89 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
    +license agreements. See the NOTICE file distributed with this work for additional
    +information regarding copyright ownership. The ASF licenses this file to
    +You under the Apache License, Version 2.0 (the "License"); you may not use
    +this file except in compliance with the License. You may obtain a copy of
    +the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
    +by applicable law or agreed to in writing, software distributed under the
    +License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
    +OF ANY KIND, either express or implied. See the License for the specific
    +language governing permissions and limitations under the License. -->
    +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    +    <modelVersion>4.0.0</modelVersion>
    +    <parent>
    +        <groupId>org.apache.nifi</groupId>
    +        <artifactId>nifi-toolkit</artifactId>
    +        <version>1.0.0-SNAPSHOT</version>
    +    </parent>
    +    <artifactId>nifi-toolkit-assembly</artifactId>
    +    <packaging>pom</packaging>
    +    <description>This is the assembly Apache NiFi Toolkit</description>
    +    <build>
    +        <plugins>
    +            <plugin>
    +                <groupId>org.apache.rat</groupId>
    +                <artifactId>apache-rat-plugin</artifactId>
    +                <configuration>
    +                    <excludes combine.children="append">
    +                        <exclude>src/main/resources/conf/config-client.json</exclude>
    +                        <exclude>src/main/resources/conf/config-server.json</exclude>
    +                    </excludes>
    +                </configuration>
    +            </plugin>
    +            <plugin>
    +                <artifactId>maven-assembly-plugin</artifactId>
    +                <configuration>
    +                    <finalName>nifi-toolkit-${project.version}</finalName>
    +                </configuration>
    +                <executions>
    +                    <execution>
    +                        <id>make shared resource</id>
    +                        <goals>
    +                            <goal>single</goal>
    +                        </goals>
    +                        <phase>package</phase>
    +                        <configuration>
    +                            <archiverConfig>
    +                                <defaultDirectoryMode>0755</defaultDirectoryMode>
    +                                <directoryMode>0755</directoryMode>
    +                                <fileMode>0644</fileMode>
    +                            </archiverConfig>
    +                            <descriptors>
    +                                <descriptor>src/main/assembly/dependencies.xml</descriptor>
    +                            </descriptors>
    +                            <tarLongFileMode>posix</tarLongFileMode>
    +                        </configuration>
    +                    </execution>
    +                </executions>
    +            </plugin>
    +        </plugins>
    +    </build>
    +    <dependencies>
    +        <dependency>
    +            <groupId>org.apache.nifi</groupId>
    +            <artifactId>nifi-toolkit-tls</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.slf4j</groupId>
    +            <artifactId>slf4j-api</artifactId>
    +            <scope>compile</scope>
    +            <version>1.7.12</version>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.eclipse.jetty</groupId>
    +            <artifactId>jetty-server</artifactId>
    +            <scope>compile</scope>
    +        </dependency>
    +        <dependency>
    +            <groupId>javax.servlet</groupId>
    +            <artifactId>javax.servlet-api</artifactId>
    +            <scope>compile</scope>
    +        </dependency>
    +        <dependency>
    +            <groupId>commons-io</groupId>
    +            <artifactId>commons-io</artifactId>
    --- End diff --
    
    If I remove it, it the assembly doesn't honor the 2.5 version from nifi-toolkit-tls, instead pulling in version 2.4.
    
    I'm mainly using it for its BoundedReader functionality (to prevent a malicious client from sending an arbitrarily large payload) which isn't available until 2.5.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72466834
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    +    The following NOTICE information applies:
    +      Apache Commons Logging
    +      Copyright 2003-2014 The Apache Software Foundation
    +
    +  (ASLv2) Apache HttpComponents
    +    The following NOTICE information applies:
    +      Apache HttpClient
    +      Copyright 1999-2015 The Apache Software Foundation
    +
    +      Apache HttpCore
    +      Copyright 2005-2015 The Apache Software Foundation
    +
    +      This project contains annotations derived from JCIP-ANNOTATIONS
    +      Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
    +
    +  (ASLv2) Jackson JSON processor
    +    The following NOTICE information applies:
    +      # Jackson JSON processor
    +
    +      Jackson is a high-performance, Free/Open Source JSON processing library.
    +      It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
    +      been in development since 2007.
    +      It is currently developed by a community of developers, as well as supported
    +      commercially by FasterXML.com.
    +
    +      ## Licensing
    +
    +      Jackson core and extension components may licensed under different licenses.
    +      To find the details that apply to this artifact see the accompanying LICENSE file.
    +      For more information, including possible other licensing options, contact
    +      FasterXML.com (http://fasterxml.com).
    +
    +      ## Credits
    +
    +      A list of contributors may be found from CREDITS file, which is included
    +      in some artifacts (usually source distributions); but is always available
    +      from the source code management (SCM) system project uses.
    +
    +  (ASLv2) Jetty
    +    The following NOTICE information applies:
    +       Jetty Web Container
    +       Copyright 1995-2015 Mort Bay Consulting Pty Ltd.
    +
    +  (ASLv2) Apache log4j
    +    The following NOTICE information applies:
    +      Apache log4j
    +      Copyright 2007 The Apache Software Foundation
    +
    +===========================================
    +MIT License
    +===========================================
    +
    +  (MIT) Bouncy Castle
    --- End diff --
    
    I believe this can be removed. Looking at the nifi-assembly LICENSE/NOTICE, there are many MIT licensed deps in the LICENSE file but nothing in the NOTICE about them. Is there a somewhere that suggested different?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72313026
  
    --- Diff: nifi-assembly/pom.xml ---
    @@ -363,147 +363,6 @@ language governing permissions and limitations under the License. -->
             </dependency>
         </dependencies>
     
    -    <properties>
    --- End diff --
    
    Why are all of these properties being removed from the assembly pom?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72468172
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/pom.xml ---
    @@ -0,0 +1,115 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!--
    +  Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You under the Apache License, Version 2.0
    +  (the "License"); you may not use this file except in compliance with
    +  the License.  You may obtain a copy of the License at
    +      http://www.apache.org/licenses/LICENSE-2.0
    +  Unless required by applicable law or agreed to in writing, software
    +  distributed under the License is distributed on an "AS IS" BASIS,
    +  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +  See the License for the specific language governing permissions and
    +  limitations under the License.
    +-->
    +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    +    <modelVersion>4.0.0</modelVersion>
    +    <parent>
    +        <groupId>org.apache.nifi</groupId>
    +        <artifactId>nifi-toolkit</artifactId>
    +        <version>1.0.0-SNAPSHOT</version>
    +    </parent>
    +    <artifactId>nifi-toolkit-tls</artifactId>
    +    <description>Tooling to make tls configuration easier</description>
    +    <dependencies>
    +        <dependency>
    +            <groupId>org.apache.nifi</groupId>
    +            <artifactId>nifi-properties</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.apache.nifi</groupId>
    +            <artifactId>nifi-security-utils</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.slf4j</groupId>
    +            <artifactId>slf4j-api</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.slf4j</groupId>
    +            <artifactId>slf4j-log4j12</artifactId>
    +            <version>1.7.12</version>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.bouncycastle</groupId>
    +            <artifactId>bcpkix-jdk15on</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.bouncycastle</groupId>
    +            <artifactId>bcprov-jdk15on</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>commons-cli</groupId>
    +            <artifactId>commons-cli</artifactId>
    +            <version>1.3.1</version>
    +        </dependency>
    +        <dependency>
    +            <groupId>commons-io</groupId>
    +            <artifactId>commons-io</artifactId>
    +            <version>2.5</version>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.eclipse.jetty</groupId>
    +            <artifactId>jetty-server</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>com.fasterxml.jackson.core</groupId>
    +            <artifactId>jackson-databind</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.apache.httpcomponents</groupId>
    +            <artifactId>httpclient</artifactId>
    +            <version>4.5.2</version>
    +        </dependency>
    +    </dependencies>
    +    <build>
    +        <plugins>
    +            <plugin>
    +                <groupId>org.apache.maven.plugins</groupId>
    +                <artifactId>maven-dependency-plugin</artifactId>
    +                <executions>
    +                    <execution>
    +                        <id>unpack</id>
    +                        <phase>process-resources</phase>
    +                        <goals>
    +                            <goal>unpack</goal>
    +                        </goals>
    +                        <configuration>
    +                            <artifactItems>
    +                                <artifactItem>
    +                                    <groupId>org.apache.nifi</groupId>
    +                                    <artifactId>nifi-resources</artifactId>
    +                                    <type>zip</type>
    +                                    <classifier>resources</classifier>
    +                                    <overWrite>true</overWrite>
    +                                    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    +                                    <includes>**/nifi.properties</includes>
    +                                </artifactItem>
    +                            </artifactItems>
    +                        </configuration>
    +                    </execution>
    +                </executions>
    --- End diff --
    
    @JPercivall It pulls in the nifi.properties from the nifi-resources project so that we have a reasonable default template embedded in the jar.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72723879
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordUtil.java ---
    @@ -0,0 +1,34 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import java.math.BigInteger;
    +import java.security.SecureRandom;
    +
    +public class PasswordUtil {
    +    private final SecureRandom secureRandom;
    +
    +    public PasswordUtil(SecureRandom secureRandom) {
    +        this.secureRandom = secureRandom;
    +    }
    +
    +    public String generatePassword() {
    +        // [see http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string#answer-41156]
    +        return new BigInteger(1024, secureRandom).toString(36);
    --- End diff --
    
    I appreciate the *strong* entropy here, but 1024 bits in base 36 &asymp; 198 characters. Something that provides more than 128 bits is sufficient here; 256 will be more than enough for a number of years. I might have commented off-hand about the base earlier, but base 32 makes sense because it uses a "round" number of bits  ( `2^5 = 32` ) to fully express its alphabet, while base 36 (`0-9a-f`) needs 6 ( `2^6 = 64` ) but wastes a number of those bits. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882158
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateSigningRequestPerformer.java ---
    @@ -0,0 +1,144 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.IOUtils;
    +import org.apache.commons.io.input.BoundedInputStream;
    +import org.apache.http.HttpHost;
    +import org.apache.http.client.methods.CloseableHttpResponse;
    +import org.apache.http.client.methods.HttpPost;
    +import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
    +import org.apache.http.entity.ByteArrayEntity;
    +import org.apache.http.impl.client.CloseableHttpClient;
    +import org.apache.http.impl.client.HttpClientBuilder;
    +import org.apache.http.ssl.SSLContextBuilder;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Response;
    +
    +import java.io.IOException;
    +import java.nio.charset.StandardCharsets;
    +import java.security.KeyPair;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.cert.X509Certificate;
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.function.Supplier;
    +
    +public class TlsCertificateSigningRequestPerformer {
    +    public static final String RECEIVED_RESPONSE_CODE = "Received response code ";
    +    public static final String EXPECTED_ONE_CERTIFICATE = "Expected one certificate";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_HMAC = "Expected response to contain hmac";
    +    public static final String UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE = "Unexpected hmac received, possible man in the middle";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE = "Expected response to contain certificate";
    +    private final Supplier<HttpClientBuilder> httpClientBuilderSupplier;
    +    private final String caHostname;
    +    private final String dn;
    +    private final String token;
    +    private final int port;
    +    private final TlsHelper tlsHelper;
    +
    +    public TlsCertificateSigningRequestPerformer(TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(HttpClientBuilder::create, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(httpClientBuilderSupplier, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, String caHostname, String dn, String token, int port, TlsHelper tlsHelper) {
    +        this.httpClientBuilderSupplier = httpClientBuilderSupplier;
    +        this.caHostname = caHostname;
    +        this.dn = dn;
    +        this.token = token;
    +        this.port = port;
    +        this.tlsHelper = tlsHelper;
    +    }
    +
    +    public static String getDn(String hostname) {
    +        return "CN=" + hostname + ",OU=NIFI";
    +    }
    +
    +    /**
    +     * Submits a CSR to the Certificate authority, checks the resulting hmac, and returns the chain if everything succeeds
    +     *
    +     * @param objectMapper for serialization
    +     * @param keyPair      the keypair to generate the csr for
    +     * @throws IOException if there is a problem during the process
    +     * @returnd the resulting certificate chain
    +     */
    +    public X509Certificate[] perform(ObjectMapper objectMapper, KeyPair keyPair) throws IOException {
    +        try {
    +            List<X509Certificate> certificates = new ArrayList<>();
    +
    +            HttpClientBuilder httpClientBuilder = httpClientBuilderSupplier.get();
    +            SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
    +
    +            // We will be validating that we are talking to the correct host once we get the response's hmac of the token and public key of the ca
    +            sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
    +            httpClientBuilder.setSSLSocketFactory(new TlsCertificateAuthorityClientSocketFactory(sslContextBuilder.build(), caHostname, certificates));
    +
    +            String jsonResponseString;
    +            int responseCode;
    +            try (CloseableHttpClient client = httpClientBuilder.build()) {
    +                JcaPKCS10CertificationRequest request = tlsHelper.generateCertificationRequest(dn, keyPair);
    +                TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(tlsHelper.calculateHMac(token, request.getPublicKey()),
    +                        tlsHelper.pemEncodeJcaObject(request));
    +
    +                HttpPost httpPost = new HttpPost();
    +                httpPost.setEntity(new ByteArrayEntity(objectMapper.writeValueAsBytes(tlsCertificateAuthorityRequest)));
    +
    +                try (CloseableHttpResponse response = client.execute(new HttpHost(caHostname, port, "https"), httpPost)) {
    +                    jsonResponseString = IOUtils.toString(new BoundedInputStream(response.getEntity().getContent(), 1024 * 1024), StandardCharsets.UTF_8);
    +                    responseCode = response.getStatusLine().getStatusCode();
    +                }
    +            }
    +
    +            if (responseCode != Response.SC_OK) {
    +                throw new IOException(RECEIVED_RESPONSE_CODE + responseCode + " with payload " + jsonResponseString);
    +            }
    +
    +            if (certificates.size() != 1) {
    +                throw new IOException(EXPECTED_ONE_CERTIFICATE);
    +            }
    +
    +            TlsCertificateAuthorityResponse tlsCertificateAuthorityResponse = objectMapper.readValue(jsonResponseString, TlsCertificateAuthorityResponse.class);
    +            if (!tlsCertificateAuthorityResponse.hasHmac()) {
    +                throw new IOException(EXPECTED_RESPONSE_TO_CONTAIN_HMAC);
    +            }
    +
    +            X509Certificate caCertificate = certificates.get(0);
    +            if (!tlsHelper.checkHMac(tlsCertificateAuthorityResponse.getHmac(), token, caCertificate.getPublicKey())) {
    --- End diff --
    
    On further analysis, we need to parse and extract the cert in order to calculate the hmac


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72469932
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    +    The following NOTICE information applies:
    +      Apache Commons Logging
    +      Copyright 2003-2014 The Apache Software Foundation
    +
    +  (ASLv2) Apache HttpComponents
    +    The following NOTICE information applies:
    +      Apache HttpClient
    +      Copyright 1999-2015 The Apache Software Foundation
    +
    +      Apache HttpCore
    +      Copyright 2005-2015 The Apache Software Foundation
    +
    +      This project contains annotations derived from JCIP-ANNOTATIONS
    +      Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
    +
    +  (ASLv2) Jackson JSON processor
    +    The following NOTICE information applies:
    +      # Jackson JSON processor
    +
    +      Jackson is a high-performance, Free/Open Source JSON processing library.
    +      It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
    +      been in development since 2007.
    +      It is currently developed by a community of developers, as well as supported
    +      commercially by FasterXML.com.
    +
    +      ## Licensing
    +
    +      Jackson core and extension components may licensed under different licenses.
    +      To find the details that apply to this artifact see the accompanying LICENSE file.
    +      For more information, including possible other licensing options, contact
    +      FasterXML.com (http://fasterxml.com).
    +
    +      ## Credits
    +
    +      A list of contributors may be found from CREDITS file, which is included
    +      in some artifacts (usually source distributions); but is always available
    +      from the source code management (SCM) system project uses.
    +
    +  (ASLv2) Jetty
    +    The following NOTICE information applies:
    +       Jetty Web Container
    +       Copyright 1995-2015 Mort Bay Consulting Pty Ltd.
    +
    +  (ASLv2) Apache log4j
    +    The following NOTICE information applies:
    +      Apache log4j
    +      Copyright 2007 The Apache Software Foundation
    +
    +===========================================
    +MIT License
    +===========================================
    +
    +  (MIT) Bouncy Castle
    --- End diff --
    
    will do


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72713958
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityServiceHandler.java ---
    @@ -0,0 +1,97 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.input.BoundedReader;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Request;
    +import org.eclipse.jetty.server.Response;
    +import org.eclipse.jetty.server.handler.AbstractHandler;
    +
    +import javax.servlet.ServletException;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
    +import java.io.IOException;
    +import java.security.KeyPair;
    +import java.security.cert.X509Certificate;
    +
    +/**
    + * Jetty service handler that validates the hmac of a CSR and issues a certificate if it checks out
    + */
    +public class TlsCertificateAuthorityServiceHandler extends AbstractHandler {
    +    public static final String CSR_FIELD_MUST_BE_SET = "csr field must be set";
    +    public static final String HMAC_FIELD_MUST_BE_SET = "hmac field must be set";
    +    public static final String FORBIDDEN = "forbidden";
    +    private final TlsHelper tlsHelper;
    +    private final String token;
    +    private final X509Certificate caCert;
    +    private final KeyPair keyPair;
    +    private final ObjectMapper objectMapper;
    +
    +    public TlsCertificateAuthorityServiceHandler(TlsHelper tlsHelper, String token, X509Certificate caCert, KeyPair keyPair, ObjectMapper objectMapper) {
    +        this.tlsHelper = tlsHelper;
    +        this.token = token;
    +        this.caCert = caCert;
    +        this.keyPair = keyPair;
    +        this.objectMapper = objectMapper;
    +    }
    +
    +    @Override
    +    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    +        try {
    +            TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = objectMapper.readValue(new BoundedReader(request.getReader(), 1024 * 1024), TlsCertificateAuthorityRequest.class);
    +
    +            if (!tlsCertificateAuthorityRequest.hasCsr()) {
    +                writeResponse(objectMapper, response, new TlsCertificateAuthorityResponse(CSR_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
    +                return;
    +            }
    +
    +            if (!tlsCertificateAuthorityRequest.hasHmac()) {
    +                writeResponse(objectMapper, response, new TlsCertificateAuthorityResponse(HMAC_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
    +                return;
    +            }
    +
    +            JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = tlsHelper.parseCsr(tlsCertificateAuthorityRequest.getCsr());
    +
    +            if (tlsHelper.checkHMac(tlsCertificateAuthorityRequest.getHmac(), token, jcaPKCS10CertificationRequest.getPublicKey())) {
    --- End diff --
    
    I understand this is an internal convenience method, but possibly split out the logic of generating the local HMAC from the token and public key with the comparison of the provided and calculated HMAC values to make explicit what is being compared. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72468676
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/pom.xml ---
    @@ -0,0 +1,89 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
    +license agreements. See the NOTICE file distributed with this work for additional
    +information regarding copyright ownership. The ASF licenses this file to
    +You under the Apache License, Version 2.0 (the "License"); you may not use
    +this file except in compliance with the License. You may obtain a copy of
    +the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
    +by applicable law or agreed to in writing, software distributed under the
    +License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
    +OF ANY KIND, either express or implied. See the License for the specific
    +language governing permissions and limitations under the License. -->
    +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    +    <modelVersion>4.0.0</modelVersion>
    +    <parent>
    +        <groupId>org.apache.nifi</groupId>
    +        <artifactId>nifi-toolkit</artifactId>
    +        <version>1.0.0-SNAPSHOT</version>
    +    </parent>
    +    <artifactId>nifi-toolkit-assembly</artifactId>
    +    <packaging>pom</packaging>
    +    <description>This is the assembly Apache NiFi Toolkit</description>
    +    <build>
    +        <plugins>
    +            <plugin>
    +                <groupId>org.apache.rat</groupId>
    +                <artifactId>apache-rat-plugin</artifactId>
    +                <configuration>
    +                    <excludes combine.children="append">
    +                        <exclude>src/main/resources/conf/config-client.json</exclude>
    +                        <exclude>src/main/resources/conf/config-server.json</exclude>
    +                    </excludes>
    +                </configuration>
    +            </plugin>
    +            <plugin>
    +                <artifactId>maven-assembly-plugin</artifactId>
    +                <configuration>
    +                    <finalName>nifi-toolkit-${project.version}</finalName>
    +                </configuration>
    +                <executions>
    +                    <execution>
    +                        <id>make shared resource</id>
    +                        <goals>
    +                            <goal>single</goal>
    +                        </goals>
    +                        <phase>package</phase>
    +                        <configuration>
    +                            <archiverConfig>
    +                                <defaultDirectoryMode>0755</defaultDirectoryMode>
    +                                <directoryMode>0755</directoryMode>
    +                                <fileMode>0644</fileMode>
    +                            </archiverConfig>
    +                            <descriptors>
    +                                <descriptor>src/main/assembly/dependencies.xml</descriptor>
    +                            </descriptors>
    +                            <tarLongFileMode>posix</tarLongFileMode>
    +                        </configuration>
    +                    </execution>
    +                </executions>
    +            </plugin>
    +        </plugins>
    +    </build>
    +    <dependencies>
    +        <dependency>
    +            <groupId>org.apache.nifi</groupId>
    +            <artifactId>nifi-toolkit-tls</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.slf4j</groupId>
    +            <artifactId>slf4j-api</artifactId>
    +            <scope>compile</scope>
    +            <version>1.7.12</version>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.eclipse.jetty</groupId>
    +            <artifactId>jetty-server</artifactId>
    +            <scope>compile</scope>
    +        </dependency>
    +        <dependency>
    +            <groupId>javax.servlet</groupId>
    +            <artifactId>javax.servlet-api</artifactId>
    +            <scope>compile</scope>
    +        </dependency>
    +        <dependency>
    +            <groupId>commons-io</groupId>
    +            <artifactId>commons-io</artifactId>
    --- End diff --
    
    It was being marked provided before, I can dig in more


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72741115
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateSigningRequestPerformer.java ---
    @@ -0,0 +1,144 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.IOUtils;
    +import org.apache.commons.io.input.BoundedInputStream;
    +import org.apache.http.HttpHost;
    +import org.apache.http.client.methods.CloseableHttpResponse;
    +import org.apache.http.client.methods.HttpPost;
    +import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
    +import org.apache.http.entity.ByteArrayEntity;
    +import org.apache.http.impl.client.CloseableHttpClient;
    +import org.apache.http.impl.client.HttpClientBuilder;
    +import org.apache.http.ssl.SSLContextBuilder;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Response;
    +
    +import java.io.IOException;
    +import java.nio.charset.StandardCharsets;
    +import java.security.KeyPair;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.cert.X509Certificate;
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.function.Supplier;
    +
    +public class TlsCertificateSigningRequestPerformer {
    +    public static final String RECEIVED_RESPONSE_CODE = "Received response code ";
    +    public static final String EXPECTED_ONE_CERTIFICATE = "Expected one certificate";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_HMAC = "Expected response to contain hmac";
    +    public static final String UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE = "Unexpected hmac received, possible man in the middle";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE = "Expected response to contain certificate";
    +    private final Supplier<HttpClientBuilder> httpClientBuilderSupplier;
    +    private final String caHostname;
    +    private final String dn;
    +    private final String token;
    +    private final int port;
    +    private final TlsHelper tlsHelper;
    +
    +    public TlsCertificateSigningRequestPerformer(TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(HttpClientBuilder::create, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(httpClientBuilderSupplier, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, String caHostname, String dn, String token, int port, TlsHelper tlsHelper) {
    +        this.httpClientBuilderSupplier = httpClientBuilderSupplier;
    +        this.caHostname = caHostname;
    +        this.dn = dn;
    +        this.token = token;
    +        this.port = port;
    +        this.tlsHelper = tlsHelper;
    +    }
    +
    +    public static String getDn(String hostname) {
    +        return "CN=" + hostname + ",OU=NIFI";
    +    }
    +
    +    /**
    +     * Submits a CSR to the Certificate authority, checks the resulting hmac, and returns the chain if everything succeeds
    +     *
    +     * @param objectMapper for serialization
    +     * @param keyPair      the keypair to generate the csr for
    +     * @throws IOException if there is a problem during the process
    +     * @returnd the resulting certificate chain
    +     */
    +    public X509Certificate[] perform(ObjectMapper objectMapper, KeyPair keyPair) throws IOException {
    +        try {
    +            List<X509Certificate> certificates = new ArrayList<>();
    +
    +            HttpClientBuilder httpClientBuilder = httpClientBuilderSupplier.get();
    +            SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
    +
    +            // We will be validating that we are talking to the correct host once we get the response's hmac of the token and public key of the ca
    +            sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
    +            httpClientBuilder.setSSLSocketFactory(new TlsCertificateAuthorityClientSocketFactory(sslContextBuilder.build(), caHostname, certificates));
    +
    +            String jsonResponseString;
    +            int responseCode;
    +            try (CloseableHttpClient client = httpClientBuilder.build()) {
    +                JcaPKCS10CertificationRequest request = tlsHelper.generateCertificationRequest(dn, keyPair);
    +                TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(tlsHelper.calculateHMac(token, request.getPublicKey()),
    +                        tlsHelper.pemEncodeJcaObject(request));
    +
    +                HttpPost httpPost = new HttpPost();
    +                httpPost.setEntity(new ByteArrayEntity(objectMapper.writeValueAsBytes(tlsCertificateAuthorityRequest)));
    +
    +                try (CloseableHttpResponse response = client.execute(new HttpHost(caHostname, port, "https"), httpPost)) {
    +                    jsonResponseString = IOUtils.toString(new BoundedInputStream(response.getEntity().getContent(), 1024 * 1024), StandardCharsets.UTF_8);
    +                    responseCode = response.getStatusLine().getStatusCode();
    +                }
    +            }
    +
    +            if (responseCode != Response.SC_OK) {
    +                throw new IOException(RECEIVED_RESPONSE_CODE + responseCode + " with payload " + jsonResponseString);
    --- End diff --
    
    We should be very careful and evaluate all possible responses from the server to ensure that something sensitive is not accidentally exposed through an exception being printed in a log if there is an error condition. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73262290
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.standalone;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
    +import org.apache.nifi.toolkit.tls.util.PasswordUtil;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +import java.io.FileInputStream;
    +import java.io.IOException;
    +import java.util.ArrayList;
    +import java.util.Arrays;
    +import java.util.Collections;
    +import java.util.List;
    +import java.util.stream.Collectors;
    +import java.util.stream.IntStream;
    +
    +public class TlsToolkitStandaloneCommandLine extends BaseCommandLine {
    +    public static final String OUTPUT_DIRECTORY_ARG = "outputDirectory";
    +    public static final String NIFI_PROPERTIES_FILE_ARG = "nifiPropertiesFile";
    +    public static final String KEY_STORE_PASSWORD_ARG = "keyStorePassword";
    +    public static final String TRUST_STORE_PASSWORD_ARG = "trustStorePassword";
    +    public static final String KEY_PASSWORD_ARG = "keyPassword";
    +    public static final String SAME_KEY_AND_KEY_STORE_PASSWORD_ARG = "sameKeyAndKeyStorePassword";
    +    public static final String HOSTNAMES_ARG = "hostnames";
    +    public static final String HTTPS_PORT_ARG = "httpsPort";
    +
    +    public static final String DEFAULT_OUTPUT_DIRECTORY = new File(".").getAbsolutePath();
    +
    +    public static final String DESCRIPTION = "Creates certificates and config files for nifi cluster.";
    +
    +    private final PasswordUtil passwordUtil;
    +    private File baseDir;
    +    private List<String> hostnames;
    +    private String httpsPort;
    +    private NiFiPropertiesWriterFactory niFiPropertiesWriterFactory;
    +    private List<String> keyStorePasswords;
    +    private List<String> keyPasswords;
    +    private List<String> trustStorePasswords;
    +
    +    public TlsToolkitStandaloneCommandLine() {
    +        this(new PasswordUtil());
    +    }
    +
    +    protected TlsToolkitStandaloneCommandLine(PasswordUtil passwordUtil) {
    +        super(DESCRIPTION);
    +        this.passwordUtil = passwordUtil;
    +        addOptionWithArg("o", OUTPUT_DIRECTORY_ARG, "The directory to output keystores, truststore, config files.", DEFAULT_OUTPUT_DIRECTORY);
    +        addOptionWithArg("n", HOSTNAMES_ARG, "Comma separated list of hostnames.", TlsConfig.DEFAULT_HOSTNAME);
    --- End diff --
    
    @alopresto good point, I'd left blank because it will use the machine's hostname if blank but your way is definitely better in the ssl case


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72551830
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    +        keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase, certificates);
    +    }
    +
    +    public KeyStore createKeyStore(String keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException {
    +        KeyStore keyStore;
    +        if (PKCS12.equals(keyStoreType)) {
    --- End diff --
    
    I was having issues importing into firefox, I'll try again without that bit


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73258286
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsClientManager.java ---
    @@ -0,0 +1,116 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.manager;
    +
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.manager.writer.ConfigurationWriter;
    +import org.apache.nifi.toolkit.tls.util.InputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.PasswordUtil;
    +import org.apache.nifi.util.StringUtils;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import java.io.File;
    +import java.io.FileInputStream;
    +import java.io.IOException;
    +import java.io.OutputStream;
    +import java.io.OutputStreamWriter;
    +import java.security.GeneralSecurityException;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.UnrecoverableEntryException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.util.ArrayList;
    +import java.util.Collections;
    +import java.util.HashSet;
    +import java.util.List;
    +import java.util.Set;
    +
    +public class TlsClientManager extends BaseTlsManager {
    +    private final TlsClientConfig tlsClientConfig;
    +    private final KeyStore trustStore;
    +    private final List<ConfigurationWriter<TlsClientConfig>> configurationWriters;
    +    private final Set<String> certificateAliases;
    +    private File certificateAuthorityDirectory;
    +
    +    public TlsClientManager(TlsClientConfig tlsClientConfig) throws GeneralSecurityException, IOException {
    +        this(tlsClientConfig, new PasswordUtil(), FileInputStream::new);
    +    }
    +
    +    public TlsClientManager(TlsClientConfig tlsClientConfig, PasswordUtil passwordUtil, InputStreamFactory inputStreamFactory) throws GeneralSecurityException, IOException {
    +        super(tlsClientConfig, passwordUtil, inputStreamFactory);
    +        this.trustStore = loadKeystore(tlsClientConfig.getTrustStore(), tlsClientConfig.getTrustStoreType(), tlsClientConfig.getTrustStorePassword());
    +        this.tlsClientConfig = tlsClientConfig;
    +        this.configurationWriters = new ArrayList<>();
    +        this.certificateAliases = new HashSet<>();
    +    }
    +
    +    public void setCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
    +        trustStore.setCertificateEntry(alias, cert);
    +        certificateAliases.add(alias);
    +    }
    +
    +    public void setCertificateAuthorityDirectory(File certificateAuthorityDirectory) {
    +        this.certificateAuthorityDirectory = certificateAuthorityDirectory;
    +    }
    +
    +    @Override
    +    public void write(OutputStreamFactory outputStreamFactory) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException {
    +        super.write(outputStreamFactory);
    +
    +        String trustStorePassword = tlsClientConfig.getTrustStorePassword();
    +        if (StringUtils.isEmpty(trustStorePassword)) {
    +            trustStorePassword = getPasswordUtil().generatePassword();
    +            tlsClientConfig.setTrustStorePassword(trustStorePassword);
    +        }
    +
    +        try (OutputStream outputStream = outputStreamFactory.create(new File(tlsClientConfig.getTrustStore()))) {
    +            trustStore.store(outputStream, trustStorePassword.toCharArray());
    +        }
    +
    +        for (ConfigurationWriter<TlsClientConfig> configurationWriter : configurationWriters) {
    +            configurationWriter.write(tlsClientConfig);
    +        }
    +
    +        if (certificateAuthorityDirectory != null) {
    --- End diff --
    
    Why write out all trusted certificates to individual files?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72469418
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    +    The following NOTICE information applies:
    +      Apache Commons Logging
    +      Copyright 2003-2014 The Apache Software Foundation
    +
    +  (ASLv2) Apache HttpComponents
    +    The following NOTICE information applies:
    +      Apache HttpClient
    +      Copyright 1999-2015 The Apache Software Foundation
    +
    +      Apache HttpCore
    +      Copyright 2005-2015 The Apache Software Foundation
    +
    +      This project contains annotations derived from JCIP-ANNOTATIONS
    +      Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
    +
    +  (ASLv2) Jackson JSON processor
    +    The following NOTICE information applies:
    +      # Jackson JSON processor
    +
    +      Jackson is a high-performance, Free/Open Source JSON processing library.
    +      It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
    +      been in development since 2007.
    +      It is currently developed by a community of developers, as well as supported
    +      commercially by FasterXML.com.
    +
    +      ## Licensing
    +
    +      Jackson core and extension components may licensed under different licenses.
    +      To find the details that apply to this artifact see the accompanying LICENSE file.
    +      For more information, including possible other licensing options, contact
    +      FasterXML.com (http://fasterxml.com).
    +
    +      ## Credits
    +
    +      A list of contributors may be found from CREDITS file, which is included
    +      in some artifacts (usually source distributions); but is always available
    +      from the source code management (SCM) system project uses.
    +
    +  (ASLv2) Jetty
    +    The following NOTICE information applies:
    +       Jetty Web Container
    +       Copyright 1995-2015 Mort Bay Consulting Pty Ltd.
    +
    +  (ASLv2) Apache log4j
    --- End diff --
    
    I can add it


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73251864
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java ---
    @@ -0,0 +1,101 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.standalone;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.manager.TlsCertificateAuthorityManager;
    +import org.apache.nifi.toolkit.tls.manager.TlsClientManager;
    +import org.apache.nifi.toolkit.tls.manager.writer.NifiPropertiesTlsClientConfigWriter;
    +import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import java.io.File;
    +import java.io.FileOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStreamWriter;
    +import java.security.GeneralSecurityException;
    +import java.security.KeyPair;
    +import java.security.KeyStore;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +public class TlsToolkitStandalone {
    +    public static final String NIFI_KEY = "nifi-key";
    +    public static final String NIFI_CERT = "nifi-cert";
    +    public static final String ROOT_CERT_PRIVATE_KEY = "rootCert.key";
    +    public static final String ROOT_CERT_CRT = "rootCert.crt";
    +    public static final String NIFI_PROPERTIES = "nifi.properties";
    +
    +    private final OutputStreamFactory outputStreamFactory;
    +
    +    public TlsToolkitStandalone() {
    +        this(FileOutputStream::new);
    +    }
    +
    +    public TlsToolkitStandalone(OutputStreamFactory outputStreamFactory) {
    +        this.outputStreamFactory = outputStreamFactory;
    +    }
    +
    +    public void createNifiKeystoresAndTrustStores(File baseDir, TlsConfig tlsConfig, NiFiPropertiesWriterFactory niFiPropertiesWriterFactory, List<String> hostnames, List<String> keyStorePasswords,
    +                                                  List<String> keyPasswords, List<String> trustStorePasswords, String httpsPort) throws GeneralSecurityException, IOException {
    +        String signingAlgorithm = tlsConfig.getSigningAlgorithm();
    +        int days = tlsConfig.getDays();
    +        String keyPairAlgorithm = tlsConfig.getKeyPairAlgorithm();
    +        int keySize = tlsConfig.getKeySize();
    +        TlsCertificateAuthorityManager tlsCertificateAuthorityManager = new TlsCertificateAuthorityManager(tlsConfig);
    +        KeyStore.PrivateKeyEntry privateKeyEntry = tlsCertificateAuthorityManager.getOrGenerateCertificateAuthority();
    +        X509Certificate certificate = (X509Certificate) privateKeyEntry.getCertificateChain()[0];
    +        KeyPair caKeyPair = new KeyPair(certificate.getPublicKey(), privateKeyEntry.getPrivateKey());
    +
    +        try (PemWriter pemWriter = new PemWriter(new OutputStreamWriter(outputStreamFactory.create(new File(baseDir, ROOT_CERT_CRT))))) {
    +            pemWriter.writeObject(new JcaMiscPEMGenerator(certificate));
    +        }
    +
    +        try (PemWriter pemWriter = new PemWriter(new OutputStreamWriter(outputStreamFactory.create(new File(baseDir, ROOT_CERT_PRIVATE_KEY))))) {
    +            pemWriter.writeObject(new JcaMiscPEMGenerator(caKeyPair));
    +        }
    +
    +        for (int i = 0; i < hostnames.size(); i++) {
    +            String hostname = hostnames.get(i);
    +            File hostDir = new File(baseDir, hostname);
    +
    +            if (!hostDir.mkdirs()) {
    --- End diff --
    
    If the directory already exists, this will return `false` and throw an exception. Check if the directory exists and either log a warning before clearing it, or skip generating that hostname's directory. 
    
    Example:
    
    ```bash
    hw12203:...assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT (pr695) alopresto
    \U0001f513 355s @ 15:34:06 $ ./bin/tls-toolkit.sh standalone -n host1, host2
    hw12203:...assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT (pr695) alopresto
    \U0001f513 15s @ 15:34:22 $ tree
    .
    \u251c\u2500\u2500 host1
    \u2502�� \u251c\u2500\u2500 keystore.jks
    \u2502�� \u251c\u2500\u2500 nifi.properties
    \u2502�� \u2514\u2500\u2500 truststore.jks
    \u251c\u2500\u2500 localhost
    \u2502�� \u251c\u2500\u2500 keystore.jks
    \u2502�� \u251c\u2500\u2500 nifi.properties
    \u2502�� \u2514\u2500\u2500 truststore.jks
    \u251c\u2500\u2500 rootCert.crt
    \u2514\u2500\u2500 rootCert.key
    
    5 directories, 37 files
    hw12203:...assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT (pr695) alopresto
    \U0001f513 65s @ 15:35:31 $ ./bin/tls-toolkit.sh standalone -n host1,host2
    Error creating generating tls configuration. (Unable to make directory: /Users/alopresto/Workspace/nifi/nifi-toolkit/nifi-toolkit-assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT/./host1)
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72478817
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    --- End diff --
    
    It's my understanding that you don't need to put LICENSE and NOTICE information for transitive dependencies (except for deps we created in this project like nifi-security-utils). I believe what is needed is to look at the deps you have and just see what license they have. For strong licenses, like ASLv2 http components uses, you only need to add any NOTICE information that the dep lists. You already have the NOTICE information for httpcomponents so you don't need to pass any other transitive licensing/notice. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72462023
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    --- End diff --
    
    I don't see where this is brought in as a dependency.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73272523
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java ---
    @@ -0,0 +1,101 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.standalone;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.manager.TlsCertificateAuthorityManager;
    +import org.apache.nifi.toolkit.tls.manager.TlsClientManager;
    +import org.apache.nifi.toolkit.tls.manager.writer.NifiPropertiesTlsClientConfigWriter;
    +import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import java.io.File;
    +import java.io.FileOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStreamWriter;
    +import java.security.GeneralSecurityException;
    +import java.security.KeyPair;
    +import java.security.KeyStore;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +public class TlsToolkitStandalone {
    +    public static final String NIFI_KEY = "nifi-key";
    --- End diff --
    
    adding .key


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    Running the client script multiple times in the same directory silently overwrites the same keystore file. It should warn the user and fail, or require a force flag to overwrite. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882057
  
    --- Diff: nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/CertificateUtilsTest.groovy ---
    @@ -116,53 +132,7 @@ class CertificateUtilsTest extends GroovyTestCase {
         private
         static X509Certificate generateCertificate(String dn) throws IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, OperatorCreationException {
             KeyPair keyPair = generateKeyPair();
    -        return generateCertificate(dn, keyPair);
    -    }
    -
    -    /**
    -     * Generates a signed certificate with a specific keypair.
    -     *
    -     * @param dn the DN
    -     * @param keyPair the public key will be included in the certificate and the the private key is used to sign the certificate
    -     * @return the certificate
    -     * @throws IOException
    -     * @throws NoSuchAlgorithmException
    -     * @throws CertificateException
    -     * @throws NoSuchProviderException
    -     * @throws SignatureException
    -     * @throws InvalidKeyException
    -     * @throws OperatorCreationException
    -     */
    -    private
    -    static X509Certificate generateCertificate(String dn, KeyPair keyPair) throws IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, OperatorCreationException {
    -        PrivateKey privateKey = keyPair.getPrivate();
    -        ContentSigner sigGen = new JcaContentSignerBuilder(SIGNATURE_ALGORITHM).setProvider(PROVIDER).build(privateKey);
    -        SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
    -        Date startDate = new Date(YESTERDAY);
    -        Date endDate = new Date(ONE_YEAR_FROM_NOW);
    -
    -        X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(
    -                new X500Name(dn),
    -                BigInteger.valueOf(System.currentTimeMillis()),
    -                startDate, endDate,
    -                new X500Name(dn),
    -                subPubKeyInfo);
    -
    -        // Set certificate extensions
    -        // (1) digitalSignature extension
    -        certBuilder.addExtension(X509Extension.keyUsage, true,
    -                new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment | KeyUsage.keyAgreement));
    -
    -        // (2) extendedKeyUsage extension
    -        Vector<KeyPurposeId> ekUsages = new Vector<>();
    -        ekUsages.add(KeyPurposeId.id_kp_clientAuth);
    -        ekUsages.add(KeyPurposeId.id_kp_serverAuth);
    -        certBuilder.addExtension(X509Extension.extendedKeyUsage, false, new ExtendedKeyUsage(ekUsages));
    -
    -        // Sign the certificate
    -        X509CertificateHolder certificateHolder = certBuilder.build(sigGen);
    -        return new JcaX509CertificateConverter().setProvider(PROVIDER)
    -                .getCertificate(certificateHolder);
    +        return CertificateUtils.generateSelfSignedX509Certificate(keyPair, dn, SIGNATURE_ALGORITHM, 365);
    --- End diff --
    
    Upping default valid duration to 3 years


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72470264
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    +    The following NOTICE information applies:
    +      Apache Commons Logging
    +      Copyright 2003-2014 The Apache Software Foundation
    +
    +  (ASLv2) Apache HttpComponents
    +    The following NOTICE information applies:
    +      Apache HttpClient
    +      Copyright 1999-2015 The Apache Software Foundation
    +
    +      Apache HttpCore
    +      Copyright 2005-2015 The Apache Software Foundation
    +
    +      This project contains annotations derived from JCIP-ANNOTATIONS
    +      Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
    +
    +  (ASLv2) Jackson JSON processor
    +    The following NOTICE information applies:
    +      # Jackson JSON processor
    +
    +      Jackson is a high-performance, Free/Open Source JSON processing library.
    +      It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
    +      been in development since 2007.
    +      It is currently developed by a community of developers, as well as supported
    +      commercially by FasterXML.com.
    +
    +      ## Licensing
    +
    +      Jackson core and extension components may licensed under different licenses.
    +      To find the details that apply to this artifact see the accompanying LICENSE file.
    +      For more information, including possible other licensing options, contact
    +      FasterXML.com (http://fasterxml.com).
    +
    +      ## Credits
    +
    +      A list of contributors may be found from CREDITS file, which is included
    +      in some artifacts (usually source distributions); but is always available
    +      from the source code management (SCM) system project uses.
    +
    +  (ASLv2) Jetty
    +    The following NOTICE information applies:
    +       Jetty Web Container
    +       Copyright 1995-2015 Mort Bay Consulting Pty Ltd.
    +
    +  (ASLv2) Apache log4j
    --- End diff --
    
    @JPercivall it looks like slf4j is MIT licensed based on that link (so it shouldn't need a NOTICE entry as per below comment), I am using the log4j bindings which pull in log4j transitively


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73270811
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    +
    +    private String token;
    +    private String configJson;
    +    private boolean onlyUseConfigJson;
    +    private int port;
    +    private String dn;
    +
    +    public BaseCertificateAuthorityCommandLine(String header) {
    +        super(header);
    +        addOptionWithArg("t", TOKEN_ARG, "The token to use to prevent MITM (required and must be same as one used by CA)");
    --- End diff --
    
    This is a common parent class for both client and server, I can add distinct messages by making it an abstract method


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73271149
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    +
    +    private String token;
    +    private String configJson;
    +    private boolean onlyUseConfigJson;
    +    private int port;
    +    private String dn;
    +
    +    public BaseCertificateAuthorityCommandLine(String header) {
    +        super(header);
    +        addOptionWithArg("t", TOKEN_ARG, "The token to use to prevent MITM (required and must be same as one used by CA)");
    +        addOptionWithArg("f", CONFIG_JSON_ARG, "The place to write configuration info", DEFAULT_CONFIG_JSON);
    +        addOptionNoArg("F", USE_CONFIG_JSON_ARG, "Flag specifying that all configuration is read from " + CONFIG_JSON_ARG + " to facilitate automated use (otherwise "
    +                + CONFIG_JSON_ARG + " will only be written to.");
    +        addOptionWithArg("p", PORT_ARG, "The port to use to communicate with the Certificate Authority", TlsConfig.DEFAULT_PORT);
    +        addOptionWithArg("D", DN_ARG, "The dn to use for the certificate", TlsConfig.calcDefaultDn(TlsConfig.DEFAULT_HOSTNAME));
    +    }
    +
    +    @Override
    +    protected CommandLine doParse(String[] args) throws CommandLineParseException {
    +        CommandLine commandLine = super.doParse(args);
    +
    +        token = commandLine.getOptionValue(TOKEN_ARG);
    +        onlyUseConfigJson = commandLine.hasOption(USE_CONFIG_JSON_ARG);
    +        if (StringUtils.isEmpty(token) && !onlyUseConfigJson) {
    +            printUsageAndThrow(TOKEN_ARG + " argument must not be empty unless " + USE_CONFIG_JSON_ARG + " set", ExitCode.ERROR_TOKEN_ARG_EMPTY);
    +        }
    +        configJson = commandLine.getOptionValue(CONFIG_JSON_ARG, DEFAULT_CONFIG_JSON);
    +        port = getIntValue(commandLine, PORT_ARG, TlsConfig.DEFAULT_PORT);
    +        dn = commandLine.getOptionValue(DN_ARG, TlsConfig.calcDefaultDn(getCertificateAuthorityHostname()));
    --- End diff --
    
    Usage:
    The dn to use for the CA certificate (default: CN=localhost,OU=NIFI)
    
    is there an implication that you can specify just a hostname for DN?
    
    Trying to clarify by changing default to say CA_HOSTNAME and HOSTNAME for CA and client respectively, this shouldn't be mandatory


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72655223
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    +        keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase, certificates);
    +    }
    +
    +    public KeyStore createKeyStore(String keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException {
    +        KeyStore keyStore;
    +        if (PKCS12.equals(keyStoreType)) {
    +            keyStore = KeyStore.getInstance(keyStoreType, BouncyCastleProvider.PROVIDER_NAME);
    +        } else {
    +            keyStore = KeyStore.getInstance(keyStoreType);
    +        }
    +        keyStore.load(null, null);
    +        return keyStore;
    +    }
    +
    +    public X509Certificate generateSelfSignedX509Certificate(KeyPair keyPair, String dn) throws CertificateException {
    +        return CertificateUtils.generateSelfSignedX509Certificate(keyPair, dn, signingAlgorithm, days);
    +    }
    +
    +    public X509Certificate generateIssuedCertificate(String dn, PublicKey publicKey, X509Certificate issuer, KeyPair issuerKeyPair) throws CertificateException {
    +        return CertificateUtils.generateIssuedCertificate(dn, publicKey, issuer, issuerKeyPair, signingAlgorithm, days);
    +    }
    +
    +    public JcaPKCS10CertificationRequest generateCertificationRequest(String requestedDn, KeyPair keyPair) throws OperatorCreationException {
    +        JcaPKCS10CertificationRequestBuilder jcaPKCS10CertificationRequestBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Principal(requestedDn), keyPair.getPublic());
    +        JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(signingAlgorithm);
    +        return new JcaPKCS10CertificationRequest(jcaPKCS10CertificationRequestBuilder.build(jcaContentSignerBuilder.build(keyPair.getPrivate())));
    +    }
    +
    +    public X509Certificate signCsr(JcaPKCS10CertificationRequest certificationRequest, X509Certificate issuer, KeyPair issuerKeyPair) throws InvalidKeySpecException, EACException,
    +            CertificateException, NoSuchAlgorithmException, IOException, SignatureException, NoSuchProviderException, InvalidKeyException, OperatorCreationException, CRMFException {
    +        return generateIssuedCertificate(certificationRequest.getSubject().toString(), certificationRequest.getPublicKey(), issuer, issuerKeyPair);
    +    }
    +
    +    public boolean checkHMac(byte[] hmac, String token, PublicKey publicKey) throws CRMFException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
    --- End diff --
    
    Same comment -- reduce the breadth of exception classes thrown by a public method. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73265781
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    +
    +    private String token;
    +    private String configJson;
    +    private boolean onlyUseConfigJson;
    +    private int port;
    +    private String dn;
    +
    +    public BaseCertificateAuthorityCommandLine(String header) {
    +        super(header);
    +        addOptionWithArg("t", TOKEN_ARG, "The token to use to prevent MITM (required and must be same as one used by CA)");
    +        addOptionWithArg("f", CONFIG_JSON_ARG, "The place to write configuration info", DEFAULT_CONFIG_JSON);
    +        addOptionNoArg("F", USE_CONFIG_JSON_ARG, "Flag specifying that all configuration is read from " + CONFIG_JSON_ARG + " to facilitate automated use (otherwise "
    +                + CONFIG_JSON_ARG + " will only be written to.");
    +        addOptionWithArg("p", PORT_ARG, "The port to use to communicate with the Certificate Authority", TlsConfig.DEFAULT_PORT);
    --- End diff --
    
    message is generic because it's being used by both client and server, I can add specific messages for both though


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73256120
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    +
    +    private String token;
    +    private String configJson;
    +    private boolean onlyUseConfigJson;
    +    private int port;
    +    private String dn;
    +
    +    public BaseCertificateAuthorityCommandLine(String header) {
    +        super(header);
    +        addOptionWithArg("t", TOKEN_ARG, "The token to use to prevent MITM (required and must be same as one used by CA)");
    +        addOptionWithArg("f", CONFIG_JSON_ARG, "The place to write configuration info", DEFAULT_CONFIG_JSON);
    +        addOptionNoArg("F", USE_CONFIG_JSON_ARG, "Flag specifying that all configuration is read from " + CONFIG_JSON_ARG + " to facilitate automated use (otherwise "
    +                + CONFIG_JSON_ARG + " will only be written to.");
    +        addOptionWithArg("p", PORT_ARG, "The port to use to communicate with the Certificate Authority", TlsConfig.DEFAULT_PORT);
    +        addOptionWithArg("D", DN_ARG, "The dn to use for the certificate", TlsConfig.calcDefaultDn(TlsConfig.DEFAULT_HOSTNAME));
    --- End diff --
    
    This is ambiguous -- is it the DN of the certificate authority certificate?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73257442
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    +
    +    private String token;
    +    private String configJson;
    +    private boolean onlyUseConfigJson;
    +    private int port;
    +    private String dn;
    +
    +    public BaseCertificateAuthorityCommandLine(String header) {
    +        super(header);
    +        addOptionWithArg("t", TOKEN_ARG, "The token to use to prevent MITM (required and must be same as one used by CA)");
    +        addOptionWithArg("f", CONFIG_JSON_ARG, "The place to write configuration info", DEFAULT_CONFIG_JSON);
    +        addOptionNoArg("F", USE_CONFIG_JSON_ARG, "Flag specifying that all configuration is read from " + CONFIG_JSON_ARG + " to facilitate automated use (otherwise "
    +                + CONFIG_JSON_ARG + " will only be written to.");
    +        addOptionWithArg("p", PORT_ARG, "The port to use to communicate with the Certificate Authority", TlsConfig.DEFAULT_PORT);
    +        addOptionWithArg("D", DN_ARG, "The dn to use for the certificate", TlsConfig.calcDefaultDn(TlsConfig.DEFAULT_HOSTNAME));
    +    }
    +
    +    @Override
    +    protected CommandLine doParse(String[] args) throws CommandLineParseException {
    +        CommandLine commandLine = super.doParse(args);
    +
    +        token = commandLine.getOptionValue(TOKEN_ARG);
    +        onlyUseConfigJson = commandLine.hasOption(USE_CONFIG_JSON_ARG);
    +        if (StringUtils.isEmpty(token) && !onlyUseConfigJson) {
    +            printUsageAndThrow(TOKEN_ARG + " argument must not be empty unless " + USE_CONFIG_JSON_ARG + " set", ExitCode.ERROR_TOKEN_ARG_EMPTY);
    +        }
    +        configJson = commandLine.getOptionValue(CONFIG_JSON_ARG, DEFAULT_CONFIG_JSON);
    +        port = getIntValue(commandLine, PORT_ARG, TlsConfig.DEFAULT_PORT);
    +        dn = commandLine.getOptionValue(DN_ARG, TlsConfig.calcDefaultDn(getCertificateAuthorityHostname()));
    --- End diff --
    
    If the user enters only the hostname here (as is the format for the CA hostname), the tool throws an exception. 
    
    Example:
    
    ```bash
    hw12203:...assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT (pr695) alopresto
    \U0001f513 166s @ 15:58:03 $ ./bin/tls-toolkit.sh server -c rootca.nifi.apache.org -D client.nifi.apache.org -t shorttoken
    java.lang.reflect.InvocationTargetException
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:498)
    	at org.apache.nifi.toolkit.tls.TlsToolkitMain.doMain(TlsToolkitMain.java:89)
    	at org.apache.nifi.toolkit.tls.TlsToolkitMain.main(TlsToolkitMain.java:46)
    Caused by: java.lang.IllegalArgumentException: badly formatted directory string
    	at org.bouncycastle.asn1.x500.style.IETFUtils.rDNsFromString(Unknown Source)
    	at org.bouncycastle.asn1.x500.style.BCStyle.fromString(Unknown Source)
    	at org.bouncycastle.asn1.x500.X500Name.<init>(Unknown Source)
    	at org.bouncycastle.asn1.x500.X500Name.<init>(Unknown Source)
    	at org.apache.nifi.security.util.CertificateUtils.generateSelfSignedX509Certificate(CertificateUtils.java:370)
    	at org.apache.nifi.toolkit.tls.manager.TlsCertificateAuthorityManager.getOrGenerateCertificateAuthority(TlsCertificateAuthorityManager.java:41)
    	at org.apache.nifi.toolkit.tls.service.server.TlsCertificateAuthorityService.start(TlsCertificateAuthorityService.java:86)
    	at org.apache.nifi.toolkit.tls.service.server.TlsCertificateAuthorityServiceCommandLine.main(TlsCertificateAuthorityServiceCommandLine.java:56)
    	... 6 more
    Service server error: badly formatted directory string
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    Hey @brosander, just went through the license/notice and deps, most of it looks good for the new assembly but I had a few comments. I really like this new functionality hopefully it will help make secure clusters even more approachable.
    
    @alopresto, could you review this? It is very heavily security focused and I feel you're the best person to do a code/functional review.



---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72455337
  
    --- Diff: nifi-assembly/pom.xml ---
    @@ -363,147 +363,6 @@ language governing permissions and limitations under the License. -->
             </dependency>
         </dependencies>
     
    -    <properties>
    --- End diff --
    
    Why does the toolkit need an entire nifi.properties?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72740653
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityClientSocketFactory.java ---
    @@ -0,0 +1,77 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.http.HttpHost;
    +import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    +import org.apache.http.protocol.HttpContext;
    +import org.bouncycastle.asn1.x500.style.BCStyle;
    +import org.bouncycastle.asn1.x500.style.IETFUtils;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
    +
    +import javax.net.ssl.SSLContext;
    +import javax.net.ssl.SSLSocket;
    +import java.io.IOException;
    +import java.net.InetSocketAddress;
    +import java.net.Socket;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +/**
    + * Socket Factory validates that it is talking to a RootCa claiming to have the given hostname.  It adds the certificate
    + * to a list for later validation against the payload's hmac
    + */
    +public class TlsCertificateAuthorityClientSocketFactory extends SSLConnectionSocketFactory {
    +    private final String caHostname;
    +    private final List<X509Certificate> certificates;
    +
    +    public TlsCertificateAuthorityClientSocketFactory(SSLContext sslContext, String caHostname, List<X509Certificate> certificates) {
    --- End diff --
    
    Because we are only using this for direct communication between NiFi nodes and NiFi CAs, we don't have to worry about legacy compatibility, so we can restrict the TLS protocol version to `TLSv1.2` to enforce a strong protocol with strong and fast cipher suites. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72896574
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    +        keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase, certificates);
    +    }
    +
    +    public KeyStore createKeyStore(String keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException {
    +        KeyStore keyStore;
    +        if (PKCS12.equals(keyStoreType)) {
    --- End diff --
    
    I'm unable to import the pkcs12 file into firefox unless I specify bouncy castle as provider, as creating certificates for browser use is the main purpose of the client when executed manually on the CLI, I'm inclined to keep the reference.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882052
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityClient.java ---
    @@ -0,0 +1,158 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.nifi.toolkit.tls.TlsToolkitMain;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.util.InputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.PasswordUtil;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +import java.io.FileInputStream;
    +import java.io.FileOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStream;
    +import java.io.OutputStreamWriter;
    +import java.io.Writer;
    +import java.security.KeyPair;
    +import java.security.KeyStore;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.SecureRandom;
    +import java.security.cert.X509Certificate;
    +
    +/**
    + * Client that will generate a CSR and submit to a CA, writing out the results to a keystore and truststore along with a config file if successful
    + */
    +public class TlsCertificateAuthorityClient {
    +    private final File configFile;
    +    private final TlsHelper tlsHelper;
    +    private final PasswordUtil passwordUtil;
    +    private final TlsClientConfig tlsClientConfig;
    +    private final OutputStreamFactory outputStreamFactory;
    +    private final ObjectMapper objectMapper;
    +    private final TlsCertificateSigningRequestPerformer tlsCertificateSigningRequestPerformer;
    +
    +    public TlsCertificateAuthorityClient(File configFile) throws IOException, NoSuchAlgorithmException {
    +        this(configFile, FileInputStream::new, FileOutputStream::new);
    +    }
    +
    +    public TlsCertificateAuthorityClient(File configFile, InputStreamFactory inputStreamFactory, OutputStreamFactory outputStreamFactory)
    +            throws IOException, NoSuchAlgorithmException {
    +        this(configFile, outputStreamFactory, new ObjectMapper().readValue(inputStreamFactory.create(configFile), TlsClientConfig.class));
    +    }
    +
    +    public TlsCertificateAuthorityClient(File configFile, OutputStreamFactory outputStreamFactory, TlsClientConfig tlsClientConfig)
    +            throws NoSuchAlgorithmException {
    +        this.configFile = configFile;
    +        this.objectMapper = new ObjectMapper();
    +        this.tlsClientConfig = tlsClientConfig;
    +        this.tlsHelper = tlsClientConfig.createTlsHelper();
    +        this.passwordUtil = new PasswordUtil(new SecureRandom());
    +        this.outputStreamFactory = outputStreamFactory;
    +        this.tlsCertificateSigningRequestPerformer = tlsClientConfig.createCertificateSigningRequestPerformer();
    +    }
    +
    +    public static void main(String[] args) throws Exception {
    +        TlsHelper.addBouncyCastleProvider();
    +        if (args.length != 1 || StringUtils.isEmpty(args[0])) {
    +            throw new Exception("Expected config file as only argument");
    +        }
    +        TlsCertificateAuthorityClient tlsCertificateAuthorityClient = new TlsCertificateAuthorityClient(new File(args[0]));
    +        if (tlsCertificateAuthorityClient.needsRun()) {
    +            tlsCertificateAuthorityClient.generateCertificateAndGetItSigned();
    +        }
    +    }
    +
    +    public boolean needsRun() {
    +        return !(new File(tlsClientConfig.getKeyStore()).exists() && new File(tlsClientConfig.getTrustStore()).exists());
    +    }
    +
    +    public void generateCertificateAndGetItSigned() throws Exception {
    +        generateCertificateAndGetItSigned(null);
    +    }
    +
    +    public void generateCertificateAndGetItSigned(String certificateFile) throws Exception {
    +        KeyPair keyPair = tlsHelper.generateKeyPair();
    +
    +        String keyStoreType = tlsClientConfig.getKeyStoreType();
    +        if (StringUtils.isEmpty(keyStoreType)) {
    +            keyStoreType = TlsConfig.DEFAULT_KEY_STORE_TYPE;
    +            tlsClientConfig.setKeyStoreType(keyStoreType);
    +        }
    +
    +        KeyStore keyStore = tlsHelper.createKeyStore(keyStoreType);
    +        String keyPassword = tlsClientConfig.getKeyPassword();
    +        char[] passphrase;
    +        if (TlsHelper.PKCS12.equals(keyStoreType)) {
    +            passphrase = null;
    +            tlsClientConfig.setKeyPassword(null);
    +        } else {
    +            if (StringUtils.isEmpty(keyPassword)) {
    +                keyPassword = passwordUtil.generatePassword();
    +                tlsClientConfig.setKeyPassword(keyPassword);
    +            }
    +            passphrase = keyPassword.toCharArray();
    +        }
    +        X509Certificate[] certificates = tlsCertificateSigningRequestPerformer.perform(objectMapper, keyPair);
    +        tlsHelper.addToKeyStore(keyStore, keyPair, TlsToolkitMain.NIFI_KEY, passphrase, certificates);
    +
    +        String keyStorePassword = tlsClientConfig.getKeyStorePassword();
    +        if (StringUtils.isEmpty(keyStorePassword)) {
    +            keyStorePassword = passwordUtil.generatePassword();
    +            tlsClientConfig.setKeyStorePassword(keyStorePassword);
    +        }
    +
    +        try (OutputStream outputStream = outputStreamFactory.create(new File(tlsClientConfig.getKeyStore()))) {
    +            keyStore.store(outputStream, keyStorePassword.toCharArray());
    +        }
    +
    +        String trustStoreType = tlsClientConfig.getTrustStoreType();
    +        if (StringUtils.isEmpty(trustStoreType)) {
    +            trustStoreType = TlsConfig.DEFAULT_KEY_STORE_TYPE;
    +            tlsClientConfig.setTrustStoreType(trustStoreType);
    +        }
    +
    +        KeyStore trustStore = tlsHelper.createKeyStore(trustStoreType);
    +        trustStore.setCertificateEntry(TlsToolkitMain.NIFI_CERT, certificates[certificates.length - 1]);
    +
    +        String trustStorePassword = tlsClientConfig.getTrustStorePassword();
    +        if (StringUtils.isEmpty(trustStorePassword)) {
    +            trustStorePassword = passwordUtil.generatePassword();
    +            tlsClientConfig.setTrustStorePassword(trustStorePassword);
    +        }
    +
    +        try (OutputStream outputStream = outputStreamFactory.create(new File(tlsClientConfig.getTrustStore()))) {
    +            trustStore.store(outputStream, trustStorePassword.toCharArray());
    +        }
    +
    +        if (!StringUtils.isEmpty(certificateFile)) {
    +            try (Writer writer = new OutputStreamWriter(outputStreamFactory.create(new File(certificateFile)))) {
    --- End diff --
    
    set umask to 177 in the shell script


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72713766
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityServiceHandler.java ---
    @@ -0,0 +1,97 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.input.BoundedReader;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Request;
    +import org.eclipse.jetty.server.Response;
    +import org.eclipse.jetty.server.handler.AbstractHandler;
    +
    +import javax.servlet.ServletException;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
    +import java.io.IOException;
    +import java.security.KeyPair;
    +import java.security.cert.X509Certificate;
    +
    +/**
    + * Jetty service handler that validates the hmac of a CSR and issues a certificate if it checks out
    + */
    +public class TlsCertificateAuthorityServiceHandler extends AbstractHandler {
    +    public static final String CSR_FIELD_MUST_BE_SET = "csr field must be set";
    +    public static final String HMAC_FIELD_MUST_BE_SET = "hmac field must be set";
    +    public static final String FORBIDDEN = "forbidden";
    +    private final TlsHelper tlsHelper;
    +    private final String token;
    +    private final X509Certificate caCert;
    +    private final KeyPair keyPair;
    +    private final ObjectMapper objectMapper;
    +
    +    public TlsCertificateAuthorityServiceHandler(TlsHelper tlsHelper, String token, X509Certificate caCert, KeyPair keyPair, ObjectMapper objectMapper) {
    +        this.tlsHelper = tlsHelper;
    +        this.token = token;
    +        this.caCert = caCert;
    +        this.keyPair = keyPair;
    +        this.objectMapper = objectMapper;
    +    }
    +
    +    @Override
    +    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    +        try {
    +            TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = objectMapper.readValue(new BoundedReader(request.getReader(), 1024 * 1024), TlsCertificateAuthorityRequest.class);
    +
    +            if (!tlsCertificateAuthorityRequest.hasCsr()) {
    +                writeResponse(objectMapper, response, new TlsCertificateAuthorityResponse(CSR_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
    +                return;
    +            }
    +
    +            if (!tlsCertificateAuthorityRequest.hasHmac()) {
    --- End diff --
    
    I think we should move the HMAC presence & validation to be the first steps in the logic here. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73256049
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    +
    +    private String token;
    +    private String configJson;
    +    private boolean onlyUseConfigJson;
    +    private int port;
    +    private String dn;
    +
    +    public BaseCertificateAuthorityCommandLine(String header) {
    +        super(header);
    +        addOptionWithArg("t", TOKEN_ARG, "The token to use to prevent MITM (required and must be same as one used by CA)");
    +        addOptionWithArg("f", CONFIG_JSON_ARG, "The place to write configuration info", DEFAULT_CONFIG_JSON);
    +        addOptionNoArg("F", USE_CONFIG_JSON_ARG, "Flag specifying that all configuration is read from " + CONFIG_JSON_ARG + " to facilitate automated use (otherwise "
    +                + CONFIG_JSON_ARG + " will only be written to.");
    +        addOptionWithArg("p", PORT_ARG, "The port to use to communicate with the Certificate Authority", TlsConfig.DEFAULT_PORT);
    --- End diff --
    
    The default HTTPS port is `8443` but if this is running on the same instance as a secured NiFi instance, it will collide with the default HTTPS port there as well. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73265866
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java ---
    @@ -0,0 +1,101 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.standalone;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.manager.TlsCertificateAuthorityManager;
    +import org.apache.nifi.toolkit.tls.manager.TlsClientManager;
    +import org.apache.nifi.toolkit.tls.manager.writer.NifiPropertiesTlsClientConfigWriter;
    +import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import java.io.File;
    +import java.io.FileOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStreamWriter;
    +import java.security.GeneralSecurityException;
    +import java.security.KeyPair;
    +import java.security.KeyStore;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +public class TlsToolkitStandalone {
    +    public static final String NIFI_KEY = "nifi-key";
    +    public static final String NIFI_CERT = "nifi-cert";
    +    public static final String ROOT_CERT_PRIVATE_KEY = "rootCert.key";
    +    public static final String ROOT_CERT_CRT = "rootCert.crt";
    +    public static final String NIFI_PROPERTIES = "nifi.properties";
    +
    +    private final OutputStreamFactory outputStreamFactory;
    +
    +    public TlsToolkitStandalone() {
    +        this(FileOutputStream::new);
    +    }
    +
    +    public TlsToolkitStandalone(OutputStreamFactory outputStreamFactory) {
    +        this.outputStreamFactory = outputStreamFactory;
    +    }
    +
    +    public void createNifiKeystoresAndTrustStores(File baseDir, TlsConfig tlsConfig, NiFiPropertiesWriterFactory niFiPropertiesWriterFactory, List<String> hostnames, List<String> keyStorePasswords,
    +                                                  List<String> keyPasswords, List<String> trustStorePasswords, String httpsPort) throws GeneralSecurityException, IOException {
    +        String signingAlgorithm = tlsConfig.getSigningAlgorithm();
    +        int days = tlsConfig.getDays();
    +        String keyPairAlgorithm = tlsConfig.getKeyPairAlgorithm();
    +        int keySize = tlsConfig.getKeySize();
    +        TlsCertificateAuthorityManager tlsCertificateAuthorityManager = new TlsCertificateAuthorityManager(tlsConfig);
    +        KeyStore.PrivateKeyEntry privateKeyEntry = tlsCertificateAuthorityManager.getOrGenerateCertificateAuthority();
    +        X509Certificate certificate = (X509Certificate) privateKeyEntry.getCertificateChain()[0];
    +        KeyPair caKeyPair = new KeyPair(certificate.getPublicKey(), privateKeyEntry.getPrivateKey());
    +
    +        try (PemWriter pemWriter = new PemWriter(new OutputStreamWriter(outputStreamFactory.create(new File(baseDir, ROOT_CERT_CRT))))) {
    +            pemWriter.writeObject(new JcaMiscPEMGenerator(certificate));
    +        }
    +
    +        try (PemWriter pemWriter = new PemWriter(new OutputStreamWriter(outputStreamFactory.create(new File(baseDir, ROOT_CERT_PRIVATE_KEY))))) {
    +            pemWriter.writeObject(new JcaMiscPEMGenerator(caKeyPair));
    +        }
    +
    +        for (int i = 0; i < hostnames.size(); i++) {
    +            String hostname = hostnames.get(i);
    +            File hostDir = new File(baseDir, hostname);
    +
    +            if (!hostDir.mkdirs()) {
    --- End diff --
    
    thinking it makes sense to bomb earlier if the directory already exists and isn't empty to avoid having to deal with lots of edge cases


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72713616
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/TlsToolkitMain.java ---
    @@ -0,0 +1,121 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls;
    +
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHostConfigurationBuilder;
    +import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import java.io.File;
    +import java.io.FileWriter;
    +import java.io.IOException;
    +import java.security.GeneralSecurityException;
    +import java.security.KeyPair;
    +import java.security.KeyStore;
    +import java.security.SecureRandom;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +import static org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine.ERROR_GENERATING_CONFIG;
    +
    +/**
    + * Command line utility for generating a certificate authority and using it to issue certificates for all nifi nodes
    + */
    +public class TlsToolkitMain {
    +    public static final String NIFI_KEY = "nifi-key";
    +    public static final String NIFI_CERT = "nifi-cert";
    +    public static final String ROOT_CERT_PRIVATE_KEY = "rootCert.key";
    +    public static final String ROOT_CERT_CRT = "rootCert.crt";
    +    public static final String NIFI_PROPERTIES = "nifi.properties";
    +
    +    private final TlsHelper tlsHelper;
    +    private final File baseDir;
    +    private final NiFiPropertiesWriterFactory niFiPropertiesWriterFactory;
    +
    +    public TlsToolkitMain(TlsHelper tlsHelper, File baseDir, NiFiPropertiesWriterFactory niFiPropertiesWriterFactory) {
    +        this.tlsHelper = tlsHelper;
    +        this.baseDir = baseDir;
    +        this.niFiPropertiesWriterFactory = niFiPropertiesWriterFactory;
    +    }
    +
    +    public static void main(String[] args) {
    --- End diff --
    
    I believe this is being refactored to remove the tight coupling between `Main` and `CommandLine` -- i.e. the business logic will be in a class that can be invoked in a number of ways: other Java class instantiating the constructor, command line arguments being parsed and then passed, etc. This is inline with the client tool architecture. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882041
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateSigningRequestPerformer.java ---
    @@ -0,0 +1,144 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.IOUtils;
    +import org.apache.commons.io.input.BoundedInputStream;
    +import org.apache.http.HttpHost;
    +import org.apache.http.client.methods.CloseableHttpResponse;
    +import org.apache.http.client.methods.HttpPost;
    +import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
    +import org.apache.http.entity.ByteArrayEntity;
    +import org.apache.http.impl.client.CloseableHttpClient;
    +import org.apache.http.impl.client.HttpClientBuilder;
    +import org.apache.http.ssl.SSLContextBuilder;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Response;
    +
    +import java.io.IOException;
    +import java.nio.charset.StandardCharsets;
    +import java.security.KeyPair;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.cert.X509Certificate;
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.function.Supplier;
    +
    +public class TlsCertificateSigningRequestPerformer {
    +    public static final String RECEIVED_RESPONSE_CODE = "Received response code ";
    +    public static final String EXPECTED_ONE_CERTIFICATE = "Expected one certificate";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_HMAC = "Expected response to contain hmac";
    +    public static final String UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE = "Unexpected hmac received, possible man in the middle";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE = "Expected response to contain certificate";
    +    private final Supplier<HttpClientBuilder> httpClientBuilderSupplier;
    +    private final String caHostname;
    +    private final String dn;
    +    private final String token;
    +    private final int port;
    +    private final TlsHelper tlsHelper;
    +
    +    public TlsCertificateSigningRequestPerformer(TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(HttpClientBuilder::create, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    --- End diff --
    
    reducing visibility, it was for testing


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73263071
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/client/TlsCertificateAuthorityClientCommandLine.java ---
    @@ -0,0 +1,125 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service.client;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.service.BaseCertificateAuthorityCommandLine;
    +import org.apache.nifi.toolkit.tls.util.InputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +
    +import java.io.File;
    +import java.io.FileInputStream;
    +import java.io.IOException;
    +import java.io.InputStream;
    +
    +public class TlsCertificateAuthorityClientCommandLine extends BaseCertificateAuthorityCommandLine {
    +    public static final String DESCRIPTION = "Generates a private key and gets it signed by the certificate authority.";
    +    public static final String PKCS_12 = "PKCS12";
    +    public static final String CERTIFICATE_DIRECTORY = "certificateDirectory";
    +    public static final String DEFAULT_CERTIFICATE_DIRECTORY = ".";
    +    public static final String SAME_KEY_AND_KEY_STORE_PASSWORD_ARG = "sameKeyAndKeyStorePassword";
    +
    +    private final InputStreamFactory inputStreamFactory;
    +
    +    private String certificateDirectory;
    +    private boolean sameKeyAndKeyStorePassword;
    +
    +    public TlsCertificateAuthorityClientCommandLine() {
    +        this(FileInputStream::new);
    +    }
    +
    +    public TlsCertificateAuthorityClientCommandLine(InputStreamFactory inputStreamFactory) {
    +        super(DESCRIPTION);
    +        this.inputStreamFactory = inputStreamFactory;
    +        addOptionWithArg("C", CERTIFICATE_DIRECTORY, "The file to write the CA certificate to", DEFAULT_CERTIFICATE_DIRECTORY);
    +        addOptionNoArg("S", SAME_KEY_AND_KEY_STORE_PASSWORD_ARG, "When generating passwords, use the same one for KeyStore and Key");
    +    }
    +
    +    public static void main(String[] args) throws Exception {
    +        TlsHelper.addBouncyCastleProvider();
    +        TlsCertificateAuthorityClientCommandLine tlsCertificateAuthorityClientCommandLine = new TlsCertificateAuthorityClientCommandLine();
    +        try {
    +            tlsCertificateAuthorityClientCommandLine.parse(args);
    +        } catch (CommandLineParseException e) {
    +            System.exit(e.getExitCode());
    +        }
    +        new TlsCertificateAuthorityClient().generateCertificateAndGetItSigned(tlsCertificateAuthorityClientCommandLine.createClientConfig(),
    +                tlsCertificateAuthorityClientCommandLine.getCertificateDirectory(), tlsCertificateAuthorityClientCommandLine.getConfigJson(),
    +                tlsCertificateAuthorityClientCommandLine.sameKeyAndKeyStorePassword());
    +        System.exit(ExitCode.SUCCESS.ordinal());
    +    }
    +
    +    @Override
    +    protected boolean shouldAddDaysArg() {
    +        return false;
    +    }
    +
    +    @Override
    +    protected boolean shouldAddSigningAlgorithmArg() {
    +        return false;
    +    }
    +
    +    @Override
    +    protected String getKeyStoreTypeDefault() {
    +        return PKCS_12;
    +    }
    +
    +    @Override
    +    protected CommandLine doParse(String[] args) throws CommandLineParseException {
    +        CommandLine commandLine = super.doParse(args);
    +        certificateDirectory = commandLine.getOptionValue(CERTIFICATE_DIRECTORY, DEFAULT_CERTIFICATE_DIRECTORY);
    +        sameKeyAndKeyStorePassword = commandLine.hasOption(SAME_KEY_AND_KEY_STORE_PASSWORD_ARG);
    +        return commandLine;
    +    }
    +
    +    public boolean sameKeyAndKeyStorePassword() {
    +        return sameKeyAndKeyStorePassword;
    +    }
    +
    +    public String getCertificateDirectory() {
    +        return certificateDirectory;
    +    }
    +
    +    public TlsClientConfig createClientConfig() throws IOException {
    +        if (onlyUseConfigJson()) {
    +            try (InputStream inputStream = inputStreamFactory.create(new File(getConfigJson()))) {
    +                TlsClientConfig tlsClientConfig = new ObjectMapper().readValue(inputStream, TlsClientConfig.class);
    +                tlsClientConfig.initDefaults();
    +                return tlsClientConfig;
    +            }
    +        } else {
    +            TlsClientConfig tlsClientConfig = new TlsClientConfig();
    +            tlsClientConfig.setCaHostname(getCertificateAuthorityHostname());
    +            tlsClientConfig.setDn(getDn());
    +            tlsClientConfig.setToken(getToken());
    +            tlsClientConfig.setPort(getPort());
    +            tlsClientConfig.setKeyStore(KEYSTORE + getKeyStoreType().toLowerCase());
    +            tlsClientConfig.setKeyStoreType(getKeyStoreType());
    +            tlsClientConfig.setTrustStore(TRUSTSTORE + getKeyStoreType().toLowerCase());
    --- End diff --
    
    @alopresto noted, changing


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73004076
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    +        keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase, certificates);
    +    }
    +
    +    public KeyStore createKeyStore(String keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException {
    +        KeyStore keyStore;
    +        if (PKCS12.equals(keyStoreType)) {
    +            keyStore = KeyStore.getInstance(keyStoreType, BouncyCastleProvider.PROVIDER_NAME);
    +        } else {
    +            keyStore = KeyStore.getInstance(keyStoreType);
    +        }
    +        keyStore.load(null, null);
    +        return keyStore;
    +    }
    +
    +    public X509Certificate generateSelfSignedX509Certificate(KeyPair keyPair, String dn) throws CertificateException {
    +        return CertificateUtils.generateSelfSignedX509Certificate(keyPair, dn, signingAlgorithm, days);
    +    }
    +
    +    public X509Certificate generateIssuedCertificate(String dn, PublicKey publicKey, X509Certificate issuer, KeyPair issuerKeyPair) throws CertificateException {
    --- End diff --
    
    Made TlsHelper methods all static, inlined where it made sense


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    I don't really understand the structure of the tool here -- it looks like `TlsToolkitMain` is invoked from the scripts, and it has an internal instance of `TlsToolkitCommandLine` to parse the command line arguments, and an instance of `TlsHelper`. I would expect `TlsToolkitMain` to be a standalone class which encapsulated the logic (and ideally, to be named something like `CertificateGeneratorTool` as it is focusing solely on the key and certificate generation), and `TlsToolkitCommandLine` to be a wrapper class which handles and parses command line input to then invoke the main class logic. This way, the logic could be invoked programmatically from other classes with direct parameter provision. It seems to me that the current structure tightly couples all certificate generation & keystore population the with command line entry point. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    Improving logging, making client and server both error instead of overwriting


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72715741
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateSigningRequestPerformer.java ---
    @@ -0,0 +1,144 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.IOUtils;
    +import org.apache.commons.io.input.BoundedInputStream;
    +import org.apache.http.HttpHost;
    +import org.apache.http.client.methods.CloseableHttpResponse;
    +import org.apache.http.client.methods.HttpPost;
    +import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
    +import org.apache.http.entity.ByteArrayEntity;
    +import org.apache.http.impl.client.CloseableHttpClient;
    +import org.apache.http.impl.client.HttpClientBuilder;
    +import org.apache.http.ssl.SSLContextBuilder;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Response;
    +
    +import java.io.IOException;
    +import java.nio.charset.StandardCharsets;
    +import java.security.KeyPair;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.cert.X509Certificate;
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.function.Supplier;
    +
    +public class TlsCertificateSigningRequestPerformer {
    +    public static final String RECEIVED_RESPONSE_CODE = "Received response code ";
    +    public static final String EXPECTED_ONE_CERTIFICATE = "Expected one certificate";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_HMAC = "Expected response to contain hmac";
    +    public static final String UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE = "Unexpected hmac received, possible man in the middle";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE = "Expected response to contain certificate";
    +    private final Supplier<HttpClientBuilder> httpClientBuilderSupplier;
    +    private final String caHostname;
    +    private final String dn;
    +    private final String token;
    +    private final int port;
    +    private final TlsHelper tlsHelper;
    +
    +    public TlsCertificateSigningRequestPerformer(TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(HttpClientBuilder::create, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(httpClientBuilderSupplier, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, String caHostname, String dn, String token, int port, TlsHelper tlsHelper) {
    +        this.httpClientBuilderSupplier = httpClientBuilderSupplier;
    +        this.caHostname = caHostname;
    +        this.dn = dn;
    +        this.token = token;
    +        this.port = port;
    +        this.tlsHelper = tlsHelper;
    +    }
    +
    +    public static String getDn(String hostname) {
    +        return "CN=" + hostname + ",OU=NIFI";
    +    }
    +
    +    /**
    +     * Submits a CSR to the Certificate authority, checks the resulting hmac, and returns the chain if everything succeeds
    +     *
    +     * @param objectMapper for serialization
    +     * @param keyPair      the keypair to generate the csr for
    +     * @throws IOException if there is a problem during the process
    +     * @returnd the resulting certificate chain
    +     */
    +    public X509Certificate[] perform(ObjectMapper objectMapper, KeyPair keyPair) throws IOException {
    +        try {
    +            List<X509Certificate> certificates = new ArrayList<>();
    +
    +            HttpClientBuilder httpClientBuilder = httpClientBuilderSupplier.get();
    +            SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
    +
    +            // We will be validating that we are talking to the correct host once we get the response's hmac of the token and public key of the ca
    +            sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
    +            httpClientBuilder.setSSLSocketFactory(new TlsCertificateAuthorityClientSocketFactory(sslContextBuilder.build(), caHostname, certificates));
    +
    +            String jsonResponseString;
    +            int responseCode;
    +            try (CloseableHttpClient client = httpClientBuilder.build()) {
    +                JcaPKCS10CertificationRequest request = tlsHelper.generateCertificationRequest(dn, keyPair);
    +                TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(tlsHelper.calculateHMac(token, request.getPublicKey()),
    +                        tlsHelper.pemEncodeJcaObject(request));
    +
    +                HttpPost httpPost = new HttpPost();
    +                httpPost.setEntity(new ByteArrayEntity(objectMapper.writeValueAsBytes(tlsCertificateAuthorityRequest)));
    +
    +                try (CloseableHttpResponse response = client.execute(new HttpHost(caHostname, port, "https"), httpPost)) {
    +                    jsonResponseString = IOUtils.toString(new BoundedInputStream(response.getEntity().getContent(), 1024 * 1024), StandardCharsets.UTF_8);
    +                    responseCode = response.getStatusLine().getStatusCode();
    +                }
    +            }
    +
    +            if (responseCode != Response.SC_OK) {
    +                throw new IOException(RECEIVED_RESPONSE_CODE + responseCode + " with payload " + jsonResponseString);
    +            }
    +
    +            if (certificates.size() != 1) {
    +                throw new IOException(EXPECTED_ONE_CERTIFICATE);
    +            }
    +
    +            TlsCertificateAuthorityResponse tlsCertificateAuthorityResponse = objectMapper.readValue(jsonResponseString, TlsCertificateAuthorityResponse.class);
    +            if (!tlsCertificateAuthorityResponse.hasHmac()) {
    +                throw new IOException(EXPECTED_RESPONSE_TO_CONTAIN_HMAC);
    +            }
    +
    +            X509Certificate caCertificate = certificates.get(0);
    +            if (!tlsHelper.checkHMac(tlsCertificateAuthorityResponse.getHmac(), token, caCertificate.getPublicKey())) {
    --- End diff --
    
    Please move the HMAC verification above the response parsing and certificate extraction. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    @JPercivall I think I've addressed your assembly and license concerns, please let me know if you're satisfied with the answers/changes.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72478934
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    +    The following NOTICE information applies:
    +      Apache Commons Logging
    +      Copyright 2003-2014 The Apache Software Foundation
    +
    +  (ASLv2) Apache HttpComponents
    +    The following NOTICE information applies:
    +      Apache HttpClient
    +      Copyright 1999-2015 The Apache Software Foundation
    +
    +      Apache HttpCore
    +      Copyright 2005-2015 The Apache Software Foundation
    +
    +      This project contains annotations derived from JCIP-ANNOTATIONS
    +      Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
    +
    +  (ASLv2) Jackson JSON processor
    +    The following NOTICE information applies:
    +      # Jackson JSON processor
    +
    +      Jackson is a high-performance, Free/Open Source JSON processing library.
    +      It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
    +      been in development since 2007.
    +      It is currently developed by a community of developers, as well as supported
    +      commercially by FasterXML.com.
    +
    +      ## Licensing
    +
    +      Jackson core and extension components may licensed under different licenses.
    +      To find the details that apply to this artifact see the accompanying LICENSE file.
    +      For more information, including possible other licensing options, contact
    +      FasterXML.com (http://fasterxml.com).
    +
    +      ## Credits
    +
    +      A list of contributors may be found from CREDITS file, which is included
    +      in some artifacts (usually source distributions); but is always available
    +      from the source code management (SCM) system project uses.
    +
    +  (ASLv2) Jetty
    +    The following NOTICE information applies:
    +       Jetty Web Container
    +       Copyright 1995-2015 Mort Bay Consulting Pty Ltd.
    +
    +  (ASLv2) Apache log4j
    --- End diff --
    
    See my note on "Apache Commons Logging" regarding licensing for transitive deps.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    @alopresto I agree with your concerns about the different entry points, I'll try to unify them and get down to a single shell script with the main method and argument parsing determining the action


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72896762
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    +        keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase, certificates);
    +    }
    +
    +    public KeyStore createKeyStore(String keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException {
    +        KeyStore keyStore;
    +        if (PKCS12.equals(keyStoreType)) {
    +            keyStore = KeyStore.getInstance(keyStoreType, BouncyCastleProvider.PROVIDER_NAME);
    +        } else {
    +            keyStore = KeyStore.getInstance(keyStoreType);
    +        }
    +        keyStore.load(null, null);
    +        return keyStore;
    +    }
    +
    +    public X509Certificate generateSelfSignedX509Certificate(KeyPair keyPair, String dn) throws CertificateException {
    +        return CertificateUtils.generateSelfSignedX509Certificate(keyPair, dn, signingAlgorithm, days);
    +    }
    +
    +    public X509Certificate generateIssuedCertificate(String dn, PublicKey publicKey, X509Certificate issuer, KeyPair issuerKeyPair) throws CertificateException {
    --- End diff --
    
    The parameters are set by the TlsHelperConfig constructor to be what was parsed from command line, if we want to remove that common code and add duplicate code at the callsites, I think the callthroughs to CertificateUtils should just be inlined so we don't need to worry about it.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882165
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordUtil.java ---
    @@ -0,0 +1,34 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import java.math.BigInteger;
    +import java.security.SecureRandom;
    +
    +public class PasswordUtil {
    +    private final SecureRandom secureRandom;
    +
    +    public PasswordUtil(SecureRandom secureRandom) {
    +        this.secureRandom = secureRandom;
    +    }
    +
    +    public String generatePassword() {
    +        // [see http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string#answer-41156]
    +        return new BigInteger(1024, secureRandom).toString(36);
    --- End diff --
    
    reducing to 256 bits, base64 encoding the output and stripping the = or == off end


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73257620
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java ---
    @@ -0,0 +1,101 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.standalone;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.manager.TlsCertificateAuthorityManager;
    +import org.apache.nifi.toolkit.tls.manager.TlsClientManager;
    +import org.apache.nifi.toolkit.tls.manager.writer.NifiPropertiesTlsClientConfigWriter;
    +import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import java.io.File;
    +import java.io.FileOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStreamWriter;
    +import java.security.GeneralSecurityException;
    +import java.security.KeyPair;
    +import java.security.KeyStore;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +public class TlsToolkitStandalone {
    +    public static final String NIFI_KEY = "nifi-key";
    --- End diff --
    
    This should have a `.key` extension. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73253303
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandaloneCommandLine.java ---
    @@ -0,0 +1,188 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.standalone;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
    +import org.apache.nifi.toolkit.tls.util.PasswordUtil;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +import java.io.FileInputStream;
    +import java.io.IOException;
    +import java.util.ArrayList;
    +import java.util.Arrays;
    +import java.util.Collections;
    +import java.util.List;
    +import java.util.stream.Collectors;
    +import java.util.stream.IntStream;
    +
    +public class TlsToolkitStandaloneCommandLine extends BaseCommandLine {
    +    public static final String OUTPUT_DIRECTORY_ARG = "outputDirectory";
    +    public static final String NIFI_PROPERTIES_FILE_ARG = "nifiPropertiesFile";
    +    public static final String KEY_STORE_PASSWORD_ARG = "keyStorePassword";
    +    public static final String TRUST_STORE_PASSWORD_ARG = "trustStorePassword";
    +    public static final String KEY_PASSWORD_ARG = "keyPassword";
    +    public static final String SAME_KEY_AND_KEY_STORE_PASSWORD_ARG = "sameKeyAndKeyStorePassword";
    +    public static final String HOSTNAMES_ARG = "hostnames";
    +    public static final String HTTPS_PORT_ARG = "httpsPort";
    +
    +    public static final String DEFAULT_OUTPUT_DIRECTORY = new File(".").getAbsolutePath();
    +
    +    public static final String DESCRIPTION = "Creates certificates and config files for nifi cluster.";
    +
    +    private final PasswordUtil passwordUtil;
    +    private File baseDir;
    +    private List<String> hostnames;
    +    private String httpsPort;
    +    private NiFiPropertiesWriterFactory niFiPropertiesWriterFactory;
    +    private List<String> keyStorePasswords;
    +    private List<String> keyPasswords;
    +    private List<String> trustStorePasswords;
    +
    +    public TlsToolkitStandaloneCommandLine() {
    +        this(new PasswordUtil());
    +    }
    +
    +    protected TlsToolkitStandaloneCommandLine(PasswordUtil passwordUtil) {
    +        super(DESCRIPTION);
    +        this.passwordUtil = passwordUtil;
    +        addOptionWithArg("o", OUTPUT_DIRECTORY_ARG, "The directory to output keystores, truststore, config files.", DEFAULT_OUTPUT_DIRECTORY);
    +        addOptionWithArg("n", HOSTNAMES_ARG, "Comma separated list of hostnames.", TlsConfig.DEFAULT_HOSTNAME);
    --- End diff --
    
    If `-p` is set, the HTTPS port will be set, but the HTTPS hostname is not. It should be available from this list, so it should be populated. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73257593
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java ---
    @@ -0,0 +1,101 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.standalone;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.manager.TlsCertificateAuthorityManager;
    +import org.apache.nifi.toolkit.tls.manager.TlsClientManager;
    +import org.apache.nifi.toolkit.tls.manager.writer.NifiPropertiesTlsClientConfigWriter;
    +import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import java.io.File;
    +import java.io.FileOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStreamWriter;
    +import java.security.GeneralSecurityException;
    +import java.security.KeyPair;
    +import java.security.KeyStore;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +public class TlsToolkitStandalone {
    +    public static final String NIFI_KEY = "nifi-key";
    +    public static final String NIFI_CERT = "nifi-cert";
    --- End diff --
    
    This should have a `.pem` extension to inform the user of the PEM encoding. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882326
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityServiceHandler.java ---
    @@ -0,0 +1,97 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.input.BoundedReader;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Request;
    +import org.eclipse.jetty.server.Response;
    +import org.eclipse.jetty.server.handler.AbstractHandler;
    +
    +import javax.servlet.ServletException;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
    +import java.io.IOException;
    +import java.security.KeyPair;
    +import java.security.cert.X509Certificate;
    +
    +/**
    + * Jetty service handler that validates the hmac of a CSR and issues a certificate if it checks out
    + */
    +public class TlsCertificateAuthorityServiceHandler extends AbstractHandler {
    +    public static final String CSR_FIELD_MUST_BE_SET = "csr field must be set";
    +    public static final String HMAC_FIELD_MUST_BE_SET = "hmac field must be set";
    +    public static final String FORBIDDEN = "forbidden";
    +    private final TlsHelper tlsHelper;
    +    private final String token;
    +    private final X509Certificate caCert;
    +    private final KeyPair keyPair;
    +    private final ObjectMapper objectMapper;
    +
    +    public TlsCertificateAuthorityServiceHandler(TlsHelper tlsHelper, String token, X509Certificate caCert, KeyPair keyPair, ObjectMapper objectMapper) {
    +        this.tlsHelper = tlsHelper;
    +        this.token = token;
    +        this.caCert = caCert;
    +        this.keyPair = keyPair;
    +        this.objectMapper = objectMapper;
    +    }
    +
    +    @Override
    +    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    +        try {
    +            TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = objectMapper.readValue(new BoundedReader(request.getReader(), 1024 * 1024), TlsCertificateAuthorityRequest.class);
    +
    +            if (!tlsCertificateAuthorityRequest.hasCsr()) {
    +                writeResponse(objectMapper, response, new TlsCertificateAuthorityResponse(CSR_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
    +                return;
    +            }
    +
    +            if (!tlsCertificateAuthorityRequest.hasHmac()) {
    --- End diff --
    
    We need both a csr and hmac from the client in order to do the validation


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73272771
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/manager/TlsClientManager.java ---
    @@ -0,0 +1,116 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.manager;
    +
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.manager.writer.ConfigurationWriter;
    +import org.apache.nifi.toolkit.tls.util.InputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.PasswordUtil;
    +import org.apache.nifi.util.StringUtils;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import java.io.File;
    +import java.io.FileInputStream;
    +import java.io.IOException;
    +import java.io.OutputStream;
    +import java.io.OutputStreamWriter;
    +import java.security.GeneralSecurityException;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.UnrecoverableEntryException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.util.ArrayList;
    +import java.util.Collections;
    +import java.util.HashSet;
    +import java.util.List;
    +import java.util.Set;
    +
    +public class TlsClientManager extends BaseTlsManager {
    +    private final TlsClientConfig tlsClientConfig;
    +    private final KeyStore trustStore;
    +    private final List<ConfigurationWriter<TlsClientConfig>> configurationWriters;
    +    private final Set<String> certificateAliases;
    +    private File certificateAuthorityDirectory;
    +
    +    public TlsClientManager(TlsClientConfig tlsClientConfig) throws GeneralSecurityException, IOException {
    +        this(tlsClientConfig, new PasswordUtil(), FileInputStream::new);
    +    }
    +
    +    public TlsClientManager(TlsClientConfig tlsClientConfig, PasswordUtil passwordUtil, InputStreamFactory inputStreamFactory) throws GeneralSecurityException, IOException {
    +        super(tlsClientConfig, passwordUtil, inputStreamFactory);
    +        this.trustStore = loadKeystore(tlsClientConfig.getTrustStore(), tlsClientConfig.getTrustStoreType(), tlsClientConfig.getTrustStorePassword());
    +        this.tlsClientConfig = tlsClientConfig;
    +        this.configurationWriters = new ArrayList<>();
    +        this.certificateAliases = new HashSet<>();
    +    }
    +
    +    public void setCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
    +        trustStore.setCertificateEntry(alias, cert);
    +        certificateAliases.add(alias);
    +    }
    +
    +    public void setCertificateAuthorityDirectory(File certificateAuthorityDirectory) {
    +        this.certificateAuthorityDirectory = certificateAuthorityDirectory;
    +    }
    +
    +    @Override
    +    public void write(OutputStreamFactory outputStreamFactory) throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException {
    +        super.write(outputStreamFactory);
    +
    +        String trustStorePassword = tlsClientConfig.getTrustStorePassword();
    +        if (StringUtils.isEmpty(trustStorePassword)) {
    +            trustStorePassword = getPasswordUtil().generatePassword();
    +            tlsClientConfig.setTrustStorePassword(trustStorePassword);
    +        }
    +
    +        try (OutputStream outputStream = outputStreamFactory.create(new File(tlsClientConfig.getTrustStore()))) {
    +            trustStore.store(outputStream, trustStorePassword.toCharArray());
    +        }
    +
    +        for (ConfigurationWriter<TlsClientConfig> configurationWriter : configurationWriters) {
    +            configurationWriter.write(tlsClientConfig);
    +        }
    +
    +        if (certificateAuthorityDirectory != null) {
    --- End diff --
    
    Intended to address a possible future case where there are multiple trusted CAs to import into a browser


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    the newly failing test from last commit is in the snmp processor, not sure that it applies to anything I touched


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882314
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityClientSocketFactory.java ---
    @@ -0,0 +1,77 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.http.HttpHost;
    +import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    +import org.apache.http.protocol.HttpContext;
    +import org.bouncycastle.asn1.x500.style.BCStyle;
    +import org.bouncycastle.asn1.x500.style.IETFUtils;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
    +
    +import javax.net.ssl.SSLContext;
    +import javax.net.ssl.SSLSocket;
    +import java.io.IOException;
    +import java.net.InetSocketAddress;
    +import java.net.Socket;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +/**
    + * Socket Factory validates that it is talking to a RootCa claiming to have the given hostname.  It adds the certificate
    + * to a list for later validation against the payload's hmac
    + */
    +public class TlsCertificateAuthorityClientSocketFactory extends SSLConnectionSocketFactory {
    +    private final String caHostname;
    +    private final List<X509Certificate> certificates;
    +
    +    public TlsCertificateAuthorityClientSocketFactory(SSLContext sslContext, String caHostname, List<X509Certificate> certificates) {
    --- End diff --
    
    will do


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    As far as Documentation goes, I believe standard practice is to create a separate Jira to update the guides.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72317301
  
    --- Diff: nifi-assembly/pom.xml ---
    @@ -363,147 +363,6 @@ language governing permissions and limitations under the License. -->
             </dependency>
         </dependencies>
     
    -    <properties>
    --- End diff --
    
    @JPercivall I moved them into the pom of nifi-resources so that the filtering could happen before the files are packaged.  This kept me from needing to duplicate them so that the toolkit could bundle a valid nifi.properties, instead I can just resolve an up to date one.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882248
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordUtil.java ---
    @@ -0,0 +1,34 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import java.math.BigInteger;
    +import java.security.SecureRandom;
    +
    +public class PasswordUtil {
    +    private final SecureRandom secureRandom;
    +
    +    public PasswordUtil(SecureRandom secureRandom) {
    --- End diff --
    
    mostly for testing, added default no-arg constructor


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72715250
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    +        keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase, certificates);
    +    }
    +
    +    public KeyStore createKeyStore(String keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException {
    +        KeyStore keyStore;
    +        if (PKCS12.equals(keyStoreType)) {
    +            keyStore = KeyStore.getInstance(keyStoreType, BouncyCastleProvider.PROVIDER_NAME);
    +        } else {
    +            keyStore = KeyStore.getInstance(keyStoreType);
    +        }
    +        keyStore.load(null, null);
    +        return keyStore;
    +    }
    +
    +    public X509Certificate generateSelfSignedX509Certificate(KeyPair keyPair, String dn) throws CertificateException {
    +        return CertificateUtils.generateSelfSignedX509Certificate(keyPair, dn, signingAlgorithm, days);
    +    }
    +
    +    public X509Certificate generateIssuedCertificate(String dn, PublicKey publicKey, X509Certificate issuer, KeyPair issuerKeyPair) throws CertificateException {
    --- End diff --
    
    I think in the instance methods `signingAlgorithm` and `days` should be passed as parameters so these methods can be `static`. Personally, I get nervous when these kinds of methods use hidden state. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72460359
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/pom.xml ---
    @@ -0,0 +1,115 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!--
    +  Licensed to the Apache Software Foundation (ASF) under one or more
    +  contributor license agreements.  See the NOTICE file distributed with
    +  this work for additional information regarding copyright ownership.
    +  The ASF licenses this file to You under the Apache License, Version 2.0
    +  (the "License"); you may not use this file except in compliance with
    +  the License.  You may obtain a copy of the License at
    +      http://www.apache.org/licenses/LICENSE-2.0
    +  Unless required by applicable law or agreed to in writing, software
    +  distributed under the License is distributed on an "AS IS" BASIS,
    +  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    +  See the License for the specific language governing permissions and
    +  limitations under the License.
    +-->
    +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    +    <modelVersion>4.0.0</modelVersion>
    +    <parent>
    +        <groupId>org.apache.nifi</groupId>
    +        <artifactId>nifi-toolkit</artifactId>
    +        <version>1.0.0-SNAPSHOT</version>
    +    </parent>
    +    <artifactId>nifi-toolkit-tls</artifactId>
    +    <description>Tooling to make tls configuration easier</description>
    +    <dependencies>
    +        <dependency>
    +            <groupId>org.apache.nifi</groupId>
    +            <artifactId>nifi-properties</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.apache.nifi</groupId>
    +            <artifactId>nifi-security-utils</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.slf4j</groupId>
    +            <artifactId>slf4j-api</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.slf4j</groupId>
    +            <artifactId>slf4j-log4j12</artifactId>
    +            <version>1.7.12</version>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.bouncycastle</groupId>
    +            <artifactId>bcpkix-jdk15on</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.bouncycastle</groupId>
    +            <artifactId>bcprov-jdk15on</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>commons-cli</groupId>
    +            <artifactId>commons-cli</artifactId>
    +            <version>1.3.1</version>
    +        </dependency>
    +        <dependency>
    +            <groupId>commons-io</groupId>
    +            <artifactId>commons-io</artifactId>
    +            <version>2.5</version>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.eclipse.jetty</groupId>
    +            <artifactId>jetty-server</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>com.fasterxml.jackson.core</groupId>
    +            <artifactId>jackson-databind</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.apache.httpcomponents</groupId>
    +            <artifactId>httpclient</artifactId>
    +            <version>4.5.2</version>
    +        </dependency>
    +    </dependencies>
    +    <build>
    +        <plugins>
    +            <plugin>
    +                <groupId>org.apache.maven.plugins</groupId>
    +                <artifactId>maven-dependency-plugin</artifactId>
    +                <executions>
    +                    <execution>
    +                        <id>unpack</id>
    +                        <phase>process-resources</phase>
    +                        <goals>
    +                            <goal>unpack</goal>
    +                        </goals>
    +                        <configuration>
    +                            <artifactItems>
    +                                <artifactItem>
    +                                    <groupId>org.apache.nifi</groupId>
    +                                    <artifactId>nifi-resources</artifactId>
    +                                    <type>zip</type>
    +                                    <classifier>resources</classifier>
    +                                    <overWrite>true</overWrite>
    +                                    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    +                                    <includes>**/nifi.properties</includes>
    +                                </artifactItem>
    +                            </artifactItems>
    +                        </configuration>
    +                    </execution>
    +                </executions>
    --- End diff --
    
    What does this section of the nifi-toolkit-tls pom do? The maven-dependency-plugin is otherwise only used in the nifi-assembly.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72462162
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    --- End diff --
    
    I don't see where this is brought in as a dependency.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882026
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityServiceHandler.java ---
    @@ -0,0 +1,97 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.input.BoundedReader;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Request;
    +import org.eclipse.jetty.server.Response;
    +import org.eclipse.jetty.server.handler.AbstractHandler;
    +
    +import javax.servlet.ServletException;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
    +import java.io.IOException;
    +import java.security.KeyPair;
    +import java.security.cert.X509Certificate;
    +
    +/**
    + * Jetty service handler that validates the hmac of a CSR and issues a certificate if it checks out
    + */
    +public class TlsCertificateAuthorityServiceHandler extends AbstractHandler {
    +    public static final String CSR_FIELD_MUST_BE_SET = "csr field must be set";
    +    public static final String HMAC_FIELD_MUST_BE_SET = "hmac field must be set";
    +    public static final String FORBIDDEN = "forbidden";
    +    private final TlsHelper tlsHelper;
    +    private final String token;
    +    private final X509Certificate caCert;
    +    private final KeyPair keyPair;
    +    private final ObjectMapper objectMapper;
    +
    +    public TlsCertificateAuthorityServiceHandler(TlsHelper tlsHelper, String token, X509Certificate caCert, KeyPair keyPair, ObjectMapper objectMapper) {
    +        this.tlsHelper = tlsHelper;
    +        this.token = token;
    +        this.caCert = caCert;
    +        this.keyPair = keyPair;
    +        this.objectMapper = objectMapper;
    +    }
    +
    +    @Override
    +    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    +        try {
    +            TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = objectMapper.readValue(new BoundedReader(request.getReader(), 1024 * 1024), TlsCertificateAuthorityRequest.class);
    +
    +            if (!tlsCertificateAuthorityRequest.hasCsr()) {
    +                writeResponse(objectMapper, response, new TlsCertificateAuthorityResponse(CSR_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
    +                return;
    +            }
    +
    +            if (!tlsCertificateAuthorityRequest.hasHmac()) {
    +                writeResponse(objectMapper, response, new TlsCertificateAuthorityResponse(HMAC_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
    +                return;
    +            }
    +
    +            JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = tlsHelper.parseCsr(tlsCertificateAuthorityRequest.getCsr());
    +
    +            if (tlsHelper.checkHMac(tlsCertificateAuthorityRequest.getHmac(), token, jcaPKCS10CertificationRequest.getPublicKey())) {
    --- End diff --
    
    Noted, removing


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72469101
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    --- End diff --
    
    Transitive from org.apache.httpcomponents:httpclient:jar:4.5.2:compile


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882113
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    +        keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase, certificates);
    +    }
    +
    +    public KeyStore createKeyStore(String keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException {
    +        KeyStore keyStore;
    +        if (PKCS12.equals(keyStoreType)) {
    +            keyStore = KeyStore.getInstance(keyStoreType, BouncyCastleProvider.PROVIDER_NAME);
    +        } else {
    +            keyStore = KeyStore.getInstance(keyStoreType);
    +        }
    +        keyStore.load(null, null);
    +        return keyStore;
    +    }
    +
    +    public X509Certificate generateSelfSignedX509Certificate(KeyPair keyPair, String dn) throws CertificateException {
    +        return CertificateUtils.generateSelfSignedX509Certificate(keyPair, dn, signingAlgorithm, days);
    +    }
    +
    +    public X509Certificate generateIssuedCertificate(String dn, PublicKey publicKey, X509Certificate issuer, KeyPair issuerKeyPair) throws CertificateException {
    +        return CertificateUtils.generateIssuedCertificate(dn, publicKey, issuer, issuerKeyPair, signingAlgorithm, days);
    +    }
    +
    +    public JcaPKCS10CertificationRequest generateCertificationRequest(String requestedDn, KeyPair keyPair) throws OperatorCreationException {
    +        JcaPKCS10CertificationRequestBuilder jcaPKCS10CertificationRequestBuilder = new JcaPKCS10CertificationRequestBuilder(new X500Principal(requestedDn), keyPair.getPublic());
    +        JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(signingAlgorithm);
    +        return new JcaPKCS10CertificationRequest(jcaPKCS10CertificationRequestBuilder.build(jcaContentSignerBuilder.build(keyPair.getPrivate())));
    +    }
    +
    +    public X509Certificate signCsr(JcaPKCS10CertificationRequest certificationRequest, X509Certificate issuer, KeyPair issuerKeyPair) throws InvalidKeySpecException, EACException,
    --- End diff --
    
    Collapsed everything in the helper that throws more than one type of security exception into GeneralSecurityException


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72464516
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    +    The following NOTICE information applies:
    +      Apache Commons Logging
    +      Copyright 2003-2014 The Apache Software Foundation
    +
    +  (ASLv2) Apache HttpComponents
    +    The following NOTICE information applies:
    +      Apache HttpClient
    +      Copyright 1999-2015 The Apache Software Foundation
    +
    +      Apache HttpCore
    +      Copyright 2005-2015 The Apache Software Foundation
    +
    +      This project contains annotations derived from JCIP-ANNOTATIONS
    +      Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net
    +
    +  (ASLv2) Jackson JSON processor
    +    The following NOTICE information applies:
    +      # Jackson JSON processor
    +
    +      Jackson is a high-performance, Free/Open Source JSON processing library.
    +      It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
    +      been in development since 2007.
    +      It is currently developed by a community of developers, as well as supported
    +      commercially by FasterXML.com.
    +
    +      ## Licensing
    +
    +      Jackson core and extension components may licensed under different licenses.
    +      To find the details that apply to this artifact see the accompanying LICENSE file.
    +      For more information, including possible other licensing options, contact
    +      FasterXML.com (http://fasterxml.com).
    +
    +      ## Credits
    +
    +      A list of contributors may be found from CREDITS file, which is included
    +      in some artifacts (usually source distributions); but is always available
    +      from the source code management (SCM) system project uses.
    +
    +  (ASLv2) Jetty
    +    The following NOTICE information applies:
    +       Jetty Web Container
    +       Copyright 1995-2015 Mort Bay Consulting Pty Ltd.
    +
    +  (ASLv2) Apache log4j
    --- End diff --
    
    I don't see log4j used but I do SLF4J deps in the nifi-toolkit-tls pom. I think the SLF4J license should be added: http://www.slf4j.org/license.html


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72548970
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    --- End diff --
    
    I think all these methods need some kind of documentation, ideally public Javadoc, especially as this method could be interpreted by a caller to add a public key certificate to a truststore and would expose the private key instead. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72741196
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityClient.java ---
    @@ -0,0 +1,158 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.nifi.toolkit.tls.TlsToolkitMain;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.util.InputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.PasswordUtil;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +import java.io.FileInputStream;
    +import java.io.FileOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStream;
    +import java.io.OutputStreamWriter;
    +import java.io.Writer;
    +import java.security.KeyPair;
    +import java.security.KeyStore;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.SecureRandom;
    +import java.security.cert.X509Certificate;
    +
    +/**
    + * Client that will generate a CSR and submit to a CA, writing out the results to a keystore and truststore along with a config file if successful
    + */
    +public class TlsCertificateAuthorityClient {
    +    private final File configFile;
    +    private final TlsHelper tlsHelper;
    +    private final PasswordUtil passwordUtil;
    +    private final TlsClientConfig tlsClientConfig;
    +    private final OutputStreamFactory outputStreamFactory;
    +    private final ObjectMapper objectMapper;
    +    private final TlsCertificateSigningRequestPerformer tlsCertificateSigningRequestPerformer;
    +
    +    public TlsCertificateAuthorityClient(File configFile) throws IOException, NoSuchAlgorithmException {
    +        this(configFile, FileInputStream::new, FileOutputStream::new);
    +    }
    +
    +    public TlsCertificateAuthorityClient(File configFile, InputStreamFactory inputStreamFactory, OutputStreamFactory outputStreamFactory)
    +            throws IOException, NoSuchAlgorithmException {
    +        this(configFile, outputStreamFactory, new ObjectMapper().readValue(inputStreamFactory.create(configFile), TlsClientConfig.class));
    +    }
    +
    +    public TlsCertificateAuthorityClient(File configFile, OutputStreamFactory outputStreamFactory, TlsClientConfig tlsClientConfig)
    +            throws NoSuchAlgorithmException {
    +        this.configFile = configFile;
    +        this.objectMapper = new ObjectMapper();
    +        this.tlsClientConfig = tlsClientConfig;
    +        this.tlsHelper = tlsClientConfig.createTlsHelper();
    +        this.passwordUtil = new PasswordUtil(new SecureRandom());
    +        this.outputStreamFactory = outputStreamFactory;
    +        this.tlsCertificateSigningRequestPerformer = tlsClientConfig.createCertificateSigningRequestPerformer();
    +    }
    +
    +    public static void main(String[] args) throws Exception {
    +        TlsHelper.addBouncyCastleProvider();
    +        if (args.length != 1 || StringUtils.isEmpty(args[0])) {
    +            throw new Exception("Expected config file as only argument");
    +        }
    +        TlsCertificateAuthorityClient tlsCertificateAuthorityClient = new TlsCertificateAuthorityClient(new File(args[0]));
    +        if (tlsCertificateAuthorityClient.needsRun()) {
    +            tlsCertificateAuthorityClient.generateCertificateAndGetItSigned();
    +        }
    +    }
    +
    +    public boolean needsRun() {
    +        return !(new File(tlsClientConfig.getKeyStore()).exists() && new File(tlsClientConfig.getTrustStore()).exists());
    +    }
    +
    +    public void generateCertificateAndGetItSigned() throws Exception {
    +        generateCertificateAndGetItSigned(null);
    +    }
    +
    +    public void generateCertificateAndGetItSigned(String certificateFile) throws Exception {
    +        KeyPair keyPair = tlsHelper.generateKeyPair();
    +
    +        String keyStoreType = tlsClientConfig.getKeyStoreType();
    +        if (StringUtils.isEmpty(keyStoreType)) {
    +            keyStoreType = TlsConfig.DEFAULT_KEY_STORE_TYPE;
    +            tlsClientConfig.setKeyStoreType(keyStoreType);
    +        }
    +
    +        KeyStore keyStore = tlsHelper.createKeyStore(keyStoreType);
    +        String keyPassword = tlsClientConfig.getKeyPassword();
    +        char[] passphrase;
    +        if (TlsHelper.PKCS12.equals(keyStoreType)) {
    +            passphrase = null;
    +            tlsClientConfig.setKeyPassword(null);
    +        } else {
    +            if (StringUtils.isEmpty(keyPassword)) {
    +                keyPassword = passwordUtil.generatePassword();
    +                tlsClientConfig.setKeyPassword(keyPassword);
    +            }
    +            passphrase = keyPassword.toCharArray();
    +        }
    +        X509Certificate[] certificates = tlsCertificateSigningRequestPerformer.perform(objectMapper, keyPair);
    +        tlsHelper.addToKeyStore(keyStore, keyPair, TlsToolkitMain.NIFI_KEY, passphrase, certificates);
    +
    +        String keyStorePassword = tlsClientConfig.getKeyStorePassword();
    +        if (StringUtils.isEmpty(keyStorePassword)) {
    +            keyStorePassword = passwordUtil.generatePassword();
    +            tlsClientConfig.setKeyStorePassword(keyStorePassword);
    +        }
    +
    +        try (OutputStream outputStream = outputStreamFactory.create(new File(tlsClientConfig.getKeyStore()))) {
    +            keyStore.store(outputStream, keyStorePassword.toCharArray());
    +        }
    +
    +        String trustStoreType = tlsClientConfig.getTrustStoreType();
    +        if (StringUtils.isEmpty(trustStoreType)) {
    +            trustStoreType = TlsConfig.DEFAULT_KEY_STORE_TYPE;
    +            tlsClientConfig.setTrustStoreType(trustStoreType);
    +        }
    +
    +        KeyStore trustStore = tlsHelper.createKeyStore(trustStoreType);
    +        trustStore.setCertificateEntry(TlsToolkitMain.NIFI_CERT, certificates[certificates.length - 1]);
    +
    +        String trustStorePassword = tlsClientConfig.getTrustStorePassword();
    +        if (StringUtils.isEmpty(trustStorePassword)) {
    +            trustStorePassword = passwordUtil.generatePassword();
    +            tlsClientConfig.setTrustStorePassword(trustStorePassword);
    +        }
    +
    +        try (OutputStream outputStream = outputStreamFactory.create(new File(tlsClientConfig.getTrustStore()))) {
    +            trustStore.store(outputStream, trustStorePassword.toCharArray());
    +        }
    +
    +        if (!StringUtils.isEmpty(certificateFile)) {
    +            try (Writer writer = new OutputStreamWriter(outputStreamFactory.create(new File(certificateFile)))) {
    --- End diff --
    
    We might need to restrict the POSIX permissions for the certificates, keystore/truststore, key, and properties/config files being written out (not specific to this method). 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72485517
  
    --- Diff: nifi-assembly/pom.xml ---
    @@ -363,147 +363,6 @@ language governing permissions and limitations under the License. -->
             </dependency>
         </dependencies>
     
    -    <properties>
    --- End diff --
    
    @JPercivall rebuilding from top now, I did check and am pretty sure that nifi.properties still winds up in nifi-assembly.
    
    If you meant that it's not in the toolkit assembly, that's correct, it is built into the ssl toolkit jar.  The ssl toolkit is capable of generating a nifi.properties updated with the correct ssl values.  If the user does not specify a base file to use, it uses the embedded one.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72487873
  
    --- Diff: nifi-assembly/pom.xml ---
    @@ -363,147 +363,6 @@ language governing permissions and limitations under the License. -->
             </dependency>
         </dependencies>
     
    -    <properties>
    --- End diff --
    
    Yup I did mean the toolkit assembly, sorry for the confusion. 
    
    Ah that is cool, sounds good.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72896746
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateSigningRequestPerformer.java ---
    @@ -0,0 +1,144 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.IOUtils;
    +import org.apache.commons.io.input.BoundedInputStream;
    +import org.apache.http.HttpHost;
    +import org.apache.http.client.methods.CloseableHttpResponse;
    +import org.apache.http.client.methods.HttpPost;
    +import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
    +import org.apache.http.entity.ByteArrayEntity;
    +import org.apache.http.impl.client.CloseableHttpClient;
    +import org.apache.http.impl.client.HttpClientBuilder;
    +import org.apache.http.ssl.SSLContextBuilder;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Response;
    +
    +import java.io.IOException;
    +import java.nio.charset.StandardCharsets;
    +import java.security.KeyPair;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.cert.X509Certificate;
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.function.Supplier;
    +
    +public class TlsCertificateSigningRequestPerformer {
    +    public static final String RECEIVED_RESPONSE_CODE = "Received response code ";
    +    public static final String EXPECTED_ONE_CERTIFICATE = "Expected one certificate";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_HMAC = "Expected response to contain hmac";
    +    public static final String UNEXPECTED_HMAC_RECEIVED_POSSIBLE_MAN_IN_THE_MIDDLE = "Unexpected hmac received, possible man in the middle";
    +    public static final String EXPECTED_RESPONSE_TO_CONTAIN_CERTIFICATE = "Expected response to contain certificate";
    +    private final Supplier<HttpClientBuilder> httpClientBuilderSupplier;
    +    private final String caHostname;
    +    private final String dn;
    +    private final String token;
    +    private final int port;
    +    private final TlsHelper tlsHelper;
    +
    +    public TlsCertificateSigningRequestPerformer(TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(HttpClientBuilder::create, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, TlsClientConfig tlsClientConfig) throws NoSuchAlgorithmException {
    +        this(httpClientBuilderSupplier, tlsClientConfig.getCaHostname(), tlsClientConfig.getDn(), tlsClientConfig.getToken(), tlsClientConfig.getPort(), tlsClientConfig.createTlsHelper());
    +    }
    +
    +    public TlsCertificateSigningRequestPerformer(Supplier<HttpClientBuilder> httpClientBuilderSupplier, String caHostname, String dn, String token, int port, TlsHelper tlsHelper) {
    +        this.httpClientBuilderSupplier = httpClientBuilderSupplier;
    +        this.caHostname = caHostname;
    +        this.dn = dn;
    +        this.token = token;
    +        this.port = port;
    +        this.tlsHelper = tlsHelper;
    +    }
    +
    +    public static String getDn(String hostname) {
    +        return "CN=" + hostname + ",OU=NIFI";
    +    }
    +
    +    /**
    +     * Submits a CSR to the Certificate authority, checks the resulting hmac, and returns the chain if everything succeeds
    +     *
    +     * @param objectMapper for serialization
    +     * @param keyPair      the keypair to generate the csr for
    +     * @throws IOException if there is a problem during the process
    +     * @returnd the resulting certificate chain
    +     */
    +    public X509Certificate[] perform(ObjectMapper objectMapper, KeyPair keyPair) throws IOException {
    +        try {
    +            List<X509Certificate> certificates = new ArrayList<>();
    +
    +            HttpClientBuilder httpClientBuilder = httpClientBuilderSupplier.get();
    +            SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
    +
    +            // We will be validating that we are talking to the correct host once we get the response's hmac of the token and public key of the ca
    +            sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
    +            httpClientBuilder.setSSLSocketFactory(new TlsCertificateAuthorityClientSocketFactory(sslContextBuilder.build(), caHostname, certificates));
    +
    +            String jsonResponseString;
    +            int responseCode;
    +            try (CloseableHttpClient client = httpClientBuilder.build()) {
    +                JcaPKCS10CertificationRequest request = tlsHelper.generateCertificationRequest(dn, keyPair);
    +                TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = new TlsCertificateAuthorityRequest(tlsHelper.calculateHMac(token, request.getPublicKey()),
    +                        tlsHelper.pemEncodeJcaObject(request));
    +
    +                HttpPost httpPost = new HttpPost();
    +                httpPost.setEntity(new ByteArrayEntity(objectMapper.writeValueAsBytes(tlsCertificateAuthorityRequest)));
    +
    +                try (CloseableHttpResponse response = client.execute(new HttpHost(caHostname, port, "https"), httpPost)) {
    +                    jsonResponseString = IOUtils.toString(new BoundedInputStream(response.getEntity().getContent(), 1024 * 1024), StandardCharsets.UTF_8);
    +                    responseCode = response.getStatusLine().getStatusCode();
    +                }
    +            }
    +
    +            if (responseCode != Response.SC_OK) {
    +                throw new IOException(RECEIVED_RESPONSE_CODE + responseCode + " with payload " + jsonResponseString);
    --- End diff --
    
    Updated PR to catch exception and wrap in very generic message on server side.  As far as response goes, if you look at TlsCertificateAuthorityServiceHandler, it sends back an enumerated set of error messages that shouldn't reveal too much to a bad guy.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    I am reviewing, focusing on the cryptographic code in here as well as the token signing for communication between the nodes and CA over an untrusted channel. 
    
    @brosander can you please provide some documentation/admin guide? The only thing I have seen so far is the usage in the NiFiToolkitTLS class. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72741316
  
    --- Diff: nifi-commons/nifi-security-utils/src/test/groovy/org/apache/nifi/security/util/CertificateUtilsTest.groovy ---
    @@ -116,53 +132,7 @@ class CertificateUtilsTest extends GroovyTestCase {
         private
         static X509Certificate generateCertificate(String dn) throws IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, OperatorCreationException {
             KeyPair keyPair = generateKeyPair();
    -        return generateCertificate(dn, keyPair);
    -    }
    -
    -    /**
    -     * Generates a signed certificate with a specific keypair.
    -     *
    -     * @param dn the DN
    -     * @param keyPair the public key will be included in the certificate and the the private key is used to sign the certificate
    -     * @return the certificate
    -     * @throws IOException
    -     * @throws NoSuchAlgorithmException
    -     * @throws CertificateException
    -     * @throws NoSuchProviderException
    -     * @throws SignatureException
    -     * @throws InvalidKeyException
    -     * @throws OperatorCreationException
    -     */
    -    private
    -    static X509Certificate generateCertificate(String dn, KeyPair keyPair) throws IOException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, InvalidKeyException, OperatorCreationException {
    -        PrivateKey privateKey = keyPair.getPrivate();
    -        ContentSigner sigGen = new JcaContentSignerBuilder(SIGNATURE_ALGORITHM).setProvider(PROVIDER).build(privateKey);
    -        SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
    -        Date startDate = new Date(YESTERDAY);
    -        Date endDate = new Date(ONE_YEAR_FROM_NOW);
    -
    -        X509v3CertificateBuilder certBuilder = new X509v3CertificateBuilder(
    -                new X500Name(dn),
    -                BigInteger.valueOf(System.currentTimeMillis()),
    -                startDate, endDate,
    -                new X500Name(dn),
    -                subPubKeyInfo);
    -
    -        // Set certificate extensions
    -        // (1) digitalSignature extension
    -        certBuilder.addExtension(X509Extension.keyUsage, true,
    -                new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment | KeyUsage.keyAgreement));
    -
    -        // (2) extendedKeyUsage extension
    -        Vector<KeyPurposeId> ekUsages = new Vector<>();
    -        ekUsages.add(KeyPurposeId.id_kp_clientAuth);
    -        ekUsages.add(KeyPurposeId.id_kp_serverAuth);
    -        certBuilder.addExtension(X509Extension.extendedKeyUsage, false, new ExtendedKeyUsage(ekUsages));
    -
    -        // Sign the certificate
    -        X509CertificateHolder certificateHolder = certBuilder.build(sigGen);
    -        return new JcaX509CertificateConverter().setProvider(PROVIDER)
    -                .getCertificate(certificateHolder);
    +        return CertificateUtils.generateSelfSignedX509Certificate(keyPair, dn, SIGNATURE_ALGORITHM, 365);
    --- End diff --
    
    @brosander and I discussed the need for certificate migration, especially for the CA, and handling the trust chain amongst the nodes. I think if this value (throughout the tool) is increased for now, the additional use cases and logic to handle key/cert rollover can be addressed in a `x.1.x` release. Not ideal, but it is not an easy problem to tackle so close to the current release deadline. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72461496
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/pom.xml ---
    @@ -0,0 +1,89 @@
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
    +license agreements. See the NOTICE file distributed with this work for additional
    +information regarding copyright ownership. The ASF licenses this file to
    +You under the Apache License, Version 2.0 (the "License"); you may not use
    +this file except in compliance with the License. You may obtain a copy of
    +the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
    +by applicable law or agreed to in writing, software distributed under the
    +License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
    +OF ANY KIND, either express or implied. See the License for the specific
    +language governing permissions and limitations under the License. -->
    +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    +    <modelVersion>4.0.0</modelVersion>
    +    <parent>
    +        <groupId>org.apache.nifi</groupId>
    +        <artifactId>nifi-toolkit</artifactId>
    +        <version>1.0.0-SNAPSHOT</version>
    +    </parent>
    +    <artifactId>nifi-toolkit-assembly</artifactId>
    +    <packaging>pom</packaging>
    +    <description>This is the assembly Apache NiFi Toolkit</description>
    +    <build>
    +        <plugins>
    +            <plugin>
    +                <groupId>org.apache.rat</groupId>
    +                <artifactId>apache-rat-plugin</artifactId>
    +                <configuration>
    +                    <excludes combine.children="append">
    +                        <exclude>src/main/resources/conf/config-client.json</exclude>
    +                        <exclude>src/main/resources/conf/config-server.json</exclude>
    +                    </excludes>
    +                </configuration>
    +            </plugin>
    +            <plugin>
    +                <artifactId>maven-assembly-plugin</artifactId>
    +                <configuration>
    +                    <finalName>nifi-toolkit-${project.version}</finalName>
    +                </configuration>
    +                <executions>
    +                    <execution>
    +                        <id>make shared resource</id>
    +                        <goals>
    +                            <goal>single</goal>
    +                        </goals>
    +                        <phase>package</phase>
    +                        <configuration>
    +                            <archiverConfig>
    +                                <defaultDirectoryMode>0755</defaultDirectoryMode>
    +                                <directoryMode>0755</directoryMode>
    +                                <fileMode>0644</fileMode>
    +                            </archiverConfig>
    +                            <descriptors>
    +                                <descriptor>src/main/assembly/dependencies.xml</descriptor>
    +                            </descriptors>
    +                            <tarLongFileMode>posix</tarLongFileMode>
    +                        </configuration>
    +                    </execution>
    +                </executions>
    +            </plugin>
    +        </plugins>
    +    </build>
    +    <dependencies>
    +        <dependency>
    +            <groupId>org.apache.nifi</groupId>
    +            <artifactId>nifi-toolkit-tls</artifactId>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.slf4j</groupId>
    +            <artifactId>slf4j-api</artifactId>
    +            <scope>compile</scope>
    +            <version>1.7.12</version>
    +        </dependency>
    +        <dependency>
    +            <groupId>org.eclipse.jetty</groupId>
    +            <artifactId>jetty-server</artifactId>
    +            <scope>compile</scope>
    +        </dependency>
    +        <dependency>
    +            <groupId>javax.servlet</groupId>
    +            <artifactId>javax.servlet-api</artifactId>
    +            <scope>compile</scope>
    +        </dependency>
    +        <dependency>
    +            <groupId>commons-io</groupId>
    +            <artifactId>commons-io</artifactId>
    --- End diff --
    
    This is already brought in by "nifi-toolkit-tls" does this need to be duplicated?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72740552
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityClientSocketFactory.java ---
    @@ -0,0 +1,77 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.http.HttpHost;
    +import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    +import org.apache.http.protocol.HttpContext;
    +import org.bouncycastle.asn1.x500.style.BCStyle;
    +import org.bouncycastle.asn1.x500.style.IETFUtils;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
    +
    +import javax.net.ssl.SSLContext;
    +import javax.net.ssl.SSLSocket;
    +import java.io.IOException;
    +import java.net.InetSocketAddress;
    +import java.net.Socket;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +/**
    + * Socket Factory validates that it is talking to a RootCa claiming to have the given hostname.  It adds the certificate
    + * to a list for later validation against the payload's hmac
    + */
    +public class TlsCertificateAuthorityClientSocketFactory extends SSLConnectionSocketFactory {
    +    private final String caHostname;
    +    private final List<X509Certificate> certificates;
    +
    +    public TlsCertificateAuthorityClientSocketFactory(SSLContext sslContext, String caHostname, List<X509Certificate> certificates) {
    +        super(sslContext);
    +        this.caHostname = caHostname;
    +        this.certificates = certificates;
    +    }
    +
    +    @Override
    +    public synchronized Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress,
    +                                             InetSocketAddress localAddress, HttpContext context) throws IOException {
    +        Socket result = super.connectSocket(connectTimeout, socket, host, remoteAddress, localAddress, context);
    +        if (!SSLSocket.class.isInstance(result)) {
    +            throw new IOException("Expected tls socket");
    +        }
    +        SSLSocket sslSocket = (SSLSocket) result;
    +        java.security.cert.Certificate[] peerCertificateChain = sslSocket.getSession().getPeerCertificates();
    +        if (peerCertificateChain.length != 1) {
    +            throw new IOException("Expected root ca cert");
    +        }
    +        if (!X509Certificate.class.isInstance(peerCertificateChain[0])) {
    +            throw new IOException("Expected root ca cert in X509 format");
    +        }
    +        String cn;
    +        try {
    +            X509Certificate certificate = (X509Certificate) peerCertificateChain[0];
    +            cn = IETFUtils.valueToString(new JcaX509CertificateHolder(certificate).getSubject().getRDNs(BCStyle.CN)[0].getFirst().getValue());
    --- End diff --
    
    I'd recommend looking at `CertificateUtils.extractPeerDNFromSSLSocket()` for this operation as it handles a bit more validation. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73272482
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/standalone/TlsToolkitStandalone.java ---
    @@ -0,0 +1,101 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.standalone;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.configuration.TlsClientConfig;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.toolkit.tls.manager.TlsCertificateAuthorityManager;
    +import org.apache.nifi.toolkit.tls.manager.TlsClientManager;
    +import org.apache.nifi.toolkit.tls.manager.writer.NifiPropertiesTlsClientConfigWriter;
    +import org.apache.nifi.toolkit.tls.properties.NiFiPropertiesWriterFactory;
    +import org.apache.nifi.toolkit.tls.util.OutputStreamFactory;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import java.io.File;
    +import java.io.FileOutputStream;
    +import java.io.IOException;
    +import java.io.OutputStreamWriter;
    +import java.security.GeneralSecurityException;
    +import java.security.KeyPair;
    +import java.security.KeyStore;
    +import java.security.cert.X509Certificate;
    +import java.util.List;
    +
    +public class TlsToolkitStandalone {
    +    public static final String NIFI_KEY = "nifi-key";
    +    public static final String NIFI_CERT = "nifi-cert";
    --- End diff --
    
    adding .pem


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73256631
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    +
    +    private String token;
    +    private String configJson;
    +    private boolean onlyUseConfigJson;
    +    private int port;
    +    private String dn;
    +
    +    public BaseCertificateAuthorityCommandLine(String header) {
    +        super(header);
    +        addOptionWithArg("t", TOKEN_ARG, "The token to use to prevent MITM (required and must be same as one used by CA)");
    --- End diff --
    
    I think this message was copied from the client. This is the CA, so it should read "clients must use this token to authenticate". 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    @brosander I understand the direction of this PR and I think as it is functional, and I'd like to see it included in the beta vote on Thursday to increase the coverage of community testing. If you can fix the quick issues outlined above, we can merge this as is. I would propose we then raise a Jira to evaluate refactoring to see where we might streamline it for the general availability release. That can include more documentation and edge case/input validation. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72551782
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    --- End diff --
    
    Good point, will address


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72478228
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    --- End diff --
    
    Ah ok, good call.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72549313
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/TlsHelper.java ---
    @@ -0,0 +1,177 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import org.apache.nifi.security.util.CertificateUtils;
    +import org.apache.nifi.toolkit.tls.commandLine.TlsToolkitCommandLine;
    +import org.apache.nifi.toolkit.tls.configuration.TlsHelperConfig;
    +import org.bouncycastle.cert.X509CertificateHolder;
    +import org.bouncycastle.cert.crmf.CRMFException;
    +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
    +import org.bouncycastle.eac.EACException;
    +import org.bouncycastle.jce.provider.BouncyCastleProvider;
    +import org.bouncycastle.openssl.PEMParser;
    +import org.bouncycastle.openssl.jcajce.JcaMiscPEMGenerator;
    +import org.bouncycastle.operator.OperatorCreationException;
    +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    +import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
    +import org.bouncycastle.util.io.pem.PemWriter;
    +
    +import javax.crypto.Mac;
    +import javax.crypto.spec.SecretKeySpec;
    +import javax.security.auth.x500.X500Principal;
    +import java.io.IOException;
    +import java.io.StringReader;
    +import java.io.StringWriter;
    +import java.nio.charset.StandardCharsets;
    +import java.security.GeneralSecurityException;
    +import java.security.InvalidKeyException;
    +import java.security.KeyPair;
    +import java.security.KeyPairGenerator;
    +import java.security.KeyStore;
    +import java.security.KeyStoreException;
    +import java.security.MessageDigest;
    +import java.security.NoSuchAlgorithmException;
    +import java.security.NoSuchProviderException;
    +import java.security.PublicKey;
    +import java.security.Security;
    +import java.security.SignatureException;
    +import java.security.cert.Certificate;
    +import java.security.cert.CertificateException;
    +import java.security.cert.X509Certificate;
    +import java.security.spec.InvalidKeySpecException;
    +
    +public class TlsHelper {
    +    public static final String PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
    +    public static final String PKCS12 = "PKCS12";
    +    private final KeyPairGenerator keyPairGenerator;
    +    private final int days;
    +    private final String signingAlgorithm;
    +
    +    public TlsHelper(TlsHelperConfig tlsHelperConfig) throws NoSuchAlgorithmException {
    +        this(tlsHelperConfig.getDays(), tlsHelperConfig.getKeySize(), tlsHelperConfig.getKeyPairAlgorithm(), tlsHelperConfig.getSigningAlgorithm());
    +    }
    +
    +    public TlsHelper(TlsToolkitCommandLine tlsToolkitCommandLine) throws NoSuchAlgorithmException {
    +        this(tlsToolkitCommandLine.getTlsHelperConfig());
    +    }
    +
    +    public TlsHelper(int days, int keySize, String keyPairAlgorithm, String signingAlgorithm) throws NoSuchAlgorithmException {
    +        this(createKeyPairGenerator(keyPairAlgorithm, keySize), days, signingAlgorithm);
    +    }
    +
    +    protected TlsHelper(KeyPairGenerator keyPairGenerator, int days, String signingAlgorithm) {
    +        this.keyPairGenerator = keyPairGenerator;
    +        this.days = days;
    +        this.signingAlgorithm = signingAlgorithm;
    +    }
    +
    +    public static void addBouncyCastleProvider() {
    +        Security.addProvider(new BouncyCastleProvider());
    +    }
    +
    +    private static KeyPairGenerator createKeyPairGenerator(String algorithm, int keySize) throws NoSuchAlgorithmException {
    +        KeyPairGenerator instance = KeyPairGenerator.getInstance(algorithm);
    +        instance.initialize(keySize);
    +        return instance;
    +    }
    +
    +    public KeyPair generateKeyPair() throws NoSuchAlgorithmException {
    +        return keyPairGenerator.generateKeyPair();
    +    }
    +
    +    public void addToKeyStore(KeyStore keyStore, KeyPair keyPair, String alias, char[] passphrase, Certificate... certificates) throws GeneralSecurityException, IOException {
    +        keyStore.setKeyEntry(alias, keyPair.getPrivate(), passphrase, certificates);
    +    }
    +
    +    public KeyStore createKeyStore(String keyStoreType) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException {
    +        KeyStore keyStore;
    +        if (PKCS12.equals(keyStoreType)) {
    --- End diff --
    
    Is there a reason you explicitly reference the BouncyCastle provider to get an instance of the PKCS12 keystore?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r73270744
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/BaseCertificateAuthorityCommandLine.java ---
    @@ -0,0 +1,87 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import org.apache.commons.cli.CommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.BaseCommandLine;
    +import org.apache.nifi.toolkit.tls.commandLine.CommandLineParseException;
    +import org.apache.nifi.toolkit.tls.commandLine.ExitCode;
    +import org.apache.nifi.toolkit.tls.configuration.TlsConfig;
    +import org.apache.nifi.util.StringUtils;
    +
    +import java.io.File;
    +
    +public class BaseCertificateAuthorityCommandLine extends BaseCommandLine {
    +    public static final String TOKEN_ARG = "token";
    +    public static final String CONFIG_JSON_ARG = "configJson";
    +    public static final String USE_CONFIG_JSON_ARG = "useConfigJson";
    +    public static final String PORT_ARG = "PORT";
    +
    +    public static final String DEFAULT_CONFIG_JSON = new File("config.json").getAbsolutePath();
    --- End diff --
    
    using getPath


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72882118
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/service/TlsCertificateAuthorityServiceHandler.java ---
    @@ -0,0 +1,97 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.service;
    +
    +import com.fasterxml.jackson.databind.ObjectMapper;
    +import org.apache.commons.io.input.BoundedReader;
    +import org.apache.nifi.toolkit.tls.util.TlsHelper;
    +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
    +import org.eclipse.jetty.server.Request;
    +import org.eclipse.jetty.server.Response;
    +import org.eclipse.jetty.server.handler.AbstractHandler;
    +
    +import javax.servlet.ServletException;
    +import javax.servlet.http.HttpServletRequest;
    +import javax.servlet.http.HttpServletResponse;
    +import java.io.IOException;
    +import java.security.KeyPair;
    +import java.security.cert.X509Certificate;
    +
    +/**
    + * Jetty service handler that validates the hmac of a CSR and issues a certificate if it checks out
    + */
    +public class TlsCertificateAuthorityServiceHandler extends AbstractHandler {
    +    public static final String CSR_FIELD_MUST_BE_SET = "csr field must be set";
    +    public static final String HMAC_FIELD_MUST_BE_SET = "hmac field must be set";
    +    public static final String FORBIDDEN = "forbidden";
    +    private final TlsHelper tlsHelper;
    +    private final String token;
    +    private final X509Certificate caCert;
    +    private final KeyPair keyPair;
    +    private final ObjectMapper objectMapper;
    +
    +    public TlsCertificateAuthorityServiceHandler(TlsHelper tlsHelper, String token, X509Certificate caCert, KeyPair keyPair, ObjectMapper objectMapper) {
    +        this.tlsHelper = tlsHelper;
    +        this.token = token;
    +        this.caCert = caCert;
    +        this.keyPair = keyPair;
    +        this.objectMapper = objectMapper;
    +    }
    +
    +    @Override
    +    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    +        try {
    +            TlsCertificateAuthorityRequest tlsCertificateAuthorityRequest = objectMapper.readValue(new BoundedReader(request.getReader(), 1024 * 1024), TlsCertificateAuthorityRequest.class);
    +
    +            if (!tlsCertificateAuthorityRequest.hasCsr()) {
    +                writeResponse(objectMapper, response, new TlsCertificateAuthorityResponse(CSR_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
    +                return;
    +            }
    +
    +            if (!tlsCertificateAuthorityRequest.hasHmac()) {
    +                writeResponse(objectMapper, response, new TlsCertificateAuthorityResponse(HMAC_FIELD_MUST_BE_SET), Response.SC_BAD_REQUEST);
    +                return;
    +            }
    +
    +            JcaPKCS10CertificationRequest jcaPKCS10CertificationRequest = tlsHelper.parseCsr(tlsCertificateAuthorityRequest.getCsr());
    +
    +            if (tlsHelper.checkHMac(tlsCertificateAuthorityRequest.getHmac(), token, jcaPKCS10CertificationRequest.getPublicKey())) {
    --- End diff --
    
    Will do


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by brosander <gi...@git.apache.org>.
Github user brosander commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72488752
  
    --- Diff: nifi-assembly/pom.xml ---
    @@ -363,147 +363,6 @@ language governing permissions and limitations under the License. -->
             </dependency>
         </dependencies>
     
    -    <properties>
    --- End diff --
    
    @JPercivall still seeing a resolved nifi.properties in the nifi-assembly output


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    Running the bash scripts only provides console output when an exception occurs. Especially for the standalone, but also the client/server scripts, could we please provide positive output explaining what was accomplished?
    
    In addition, there are Log4J warnings printed.
    
    Example:
    
    ```bash
    hw12203:...assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT (pr695) alopresto
    \U0001f513 7s @ 16:00:40 $ ./bin/tls-toolkit.sh server -D CN=rootca.nifi.apache.org -t shorttoken
    log4j:WARN No appenders could be found for logger (org.eclipse.jetty.util.log).
    log4j:WARN Please initialize the log4j system properly.
    log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    Server Started
    ^C
    ```
    
    ```bash
    hw12203:...assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT (pr695) alopresto
    \U0001f513 113s @ 16:01:50 $ ./bin/tls-toolkit.sh client -D CN=client.nifi.apache.org -t shorttoken
    log4j:WARN No appenders could be found for logger (org.apache.http.client.protocol.RequestAddCookies).
    log4j:WARN Please initialize the log4j system properly.
    log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    hw12203:...assembly/target/nifi-toolkit-1.0.0-SNAPSHOT-bin/nifi-toolkit-1.0.0-SNAPSHOT (pr695) alopresto
    \U0001f513 43s @ 16:02:33 $
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by JPercivall <gi...@git.apache.org>.
Github user JPercivall commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72488748
  
    --- Diff: nifi-toolkit/nifi-toolkit-assembly/NOTICE ---
    @@ -0,0 +1,112 @@
    +Apache NiFi Toolkit
    +Copyright 2014-2016 The Apache Software Foundation
    +
    +This product includes software developed at
    +The Apache Software Foundation (http://www.apache.org/).
    +
    +===========================================
    +Apache Software License v2
    +===========================================
    +
    +The following binary components are provided under the Apache Software License v2
    +
    +  (ASLv2) Apache NiFi
    +    The following NOTICE information applies:
    +      Apache NiFi
    +      Copyright 2014-2016 The Apache Software Foundation
    +
    +      This product includes software developed at
    +      The Apache Software Foundation (http://www.apache.org/).
    +
    +      This product includes the following work from the Apache Hadoop project:
    +
    +      BoundedByteArrayOutputStream.java adapted to SoftLimitBoundedByteArrayOutputStream.java
    +
    +  (ASLv2) Apache Commons CLI
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Codec
    +    The following NOTICE information applies:
    +      Apache Commons Codec
    +      Copyright 2002-2014 The Apache Software Foundation
    +
    +      src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java
    +      contains test data from http://aspell.net/test/orig/batch0.tab.
    +      Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org)
    +
    +      ===============================================================================
    +
    +      The content of package org.apache.commons.codec.language.bm has been translated
    +      from the original php source code available at http://stevemorse.org/phoneticinfo.htm
    +      with permission from the original authors.
    +      Original source copyright:
    +      Copyright (c) 2008 Alexander Beider & Stephen P. Morse.
    +
    +  (ASLv2) Apache Commons IO
    +    The following NOTICE information applies:
    +      Apache Commons IO
    +      Copyright 2002-2012 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Lang
    +    The following NOTICE information applies:
    +      Apache Commons Lang
    +      Copyright 2001-2015 The Apache Software Foundation
    +
    +  (ASLv2) Apache Commons Logging
    --- End diff --
    
    Right it contains all the license and notice information for all the direct dependencies that make their way into the distribution. It is on those dependencies to make sure their license and notice files accurately reflect the dependencies they bundle and it is on us to properly reflect those license and notice files in our own files.
    
    This way we don't have to drill all the way down into all transitive deps of all the direct deps we import, we just have to reflect the license and notice information of the direct deps.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi pull request #695: NIFI-2193 - Command line SSL config utility as well ...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/695#discussion_r72723924
  
    --- Diff: nifi-toolkit/nifi-toolkit-tls/src/main/java/org/apache/nifi/toolkit/tls/util/PasswordUtil.java ---
    @@ -0,0 +1,34 @@
    +/*
    + * Licensed to the Apache Software Foundation (ASF) under one or more
    + * contributor license agreements.  See the NOTICE file distributed with
    + * this work for additional information regarding copyright ownership.
    + * The ASF licenses this file to You under the Apache License, Version 2.0
    + * (the "License"); you may not use this file except in compliance with
    + * the License.  You may obtain a copy of the License at
    + *
    + *     http://www.apache.org/licenses/LICENSE-2.0
    + *
    + * Unless required by applicable law or agreed to in writing, software
    + * distributed under the License is distributed on an "AS IS" BASIS,
    + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    + * See the License for the specific language governing permissions and
    + * limitations under the License.
    + */
    +
    +package org.apache.nifi.toolkit.tls.util;
    +
    +import java.math.BigInteger;
    +import java.security.SecureRandom;
    +
    +public class PasswordUtil {
    +    private final SecureRandom secureRandom;
    +
    +    public PasswordUtil(SecureRandom secureRandom) {
    --- End diff --
    
    Is the `SecureRandom` initialized externally for a reason? Is this just to make testing easier?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

[GitHub] nifi issue #695: NIFI-2193 - Command line SSL config utility as well as cert...

Posted by alopresto <gi...@git.apache.org>.
Github user alopresto commented on the issue:

    https://github.com/apache/nifi/pull/695
  
    Had a discussion with @brosander and I believe he is re-organizing the structure of the classes. I will continue adding comments on this iteration but I expect a new push is coming soon. 


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---