org.apache.hadoop.security.ssl.HopsSSLTestUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.security.ssl.HopsSSLTestUtils.java

Source

/**
 * Copyright 2016 Apache Software Foundation.
 *
 * Licensed 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.hadoop.security.ssl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.net.HopsSSLSocketFactory;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.ProxyUsers;
import org.junit.After;
import org.junit.Rule;
import org.junit.rules.ExpectedException;
import org.junit.runners.Parameterized;

import java.io.File;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class HopsSSLTestUtils {
    private final Log LOG = LogFactory.getLog(HopsSSLTestUtils.class);

    protected enum CERT_ERR {
        ERR_CN, NO_CA
    }

    @Parameterized.Parameters
    public static Collection parameters() {
        return Arrays.asList(new Object[][] { { CERT_ERR.ERR_CN }, { CERT_ERR.NO_CA } });
    }

    protected CERT_ERR error_mode = CERT_ERR.ERR_CN;
    protected String passwd = "123456";
    private String outDir;
    private Path serverKeyStore, serverTrustStore;
    private Path c_clientKeyStore, c_clientTrustStore;
    protected Path err_clientKeyStore, err_clientTrustStore;
    protected List<Path> filesToPurge;
    protected Configuration conf;

    protected Thread invoker;

    @Rule
    public final ExpectedException rule = ExpectedException.none();

    @After
    public void destroy() throws Exception {
        if (null != filesToPurge) {
            purgeFiles(filesToPurge);
        }
    }

    private void purgeFiles(List<Path> files) throws Exception {
        File file;
        for (Path path : files) {
            file = new File(path.toUri());
            if (file.exists()) {
                file.delete();
            }
        }
    }

    protected ByteBuffer[] getCryptoMaterial() throws Exception {
        ByteBuffer[] material = new ByteBuffer[2];
        ByteBuffer kstore = ByteBuffer.wrap(Files.readAllBytes(c_clientKeyStore));
        ByteBuffer tstore = ByteBuffer.wrap(Files.readAllBytes(c_clientTrustStore));
        material[0] = kstore;
        material[1] = tstore;

        return material;
    }

    protected void setCryptoConfig(Configuration conf, String classPathDir) throws Exception {
        conf.set(CommonConfigurationKeysPublic.HADOOP_RPC_SOCKET_FACTORY_CLASS_DEFAULT_KEY,
                "org.apache.hadoop.net.HopsSSLSocketFactory");
        conf.setBoolean(CommonConfigurationKeysPublic.IPC_SERVER_SSL_ENABLED, true);
        conf.set(SSLFactory.SSL_ENABLED_PROTOCOLS, "TLSv1.2,TLSv1.1");
        conf.set(SSLFactory.SSL_HOSTNAME_VERIFIER_KEY, "ALLOW_ALL");
        String user = UserGroupInformation.getCurrentUser().getUserName();
        conf.set(ProxyUsers.CONF_HADOOP_PROXYUSER + "." + user, "*");

        Configuration sslServerConf = KeyStoreTestUtil.createServerSSLConfig(serverKeyStore.toString(), passwd,
                passwd, serverTrustStore.toString(), passwd, "");
        Path sslServerPath = Paths.get(classPathDir, HopsSSLTestUtils.class.getSimpleName() + ".ssl-server.xml");
        filesToPurge.add(sslServerPath);
        File sslServer = new File(sslServerPath.toUri());
        KeyStoreTestUtil.saveConfig(sslServer, sslServerConf);
        conf.set(SSLFactory.SSL_SERVER_CONF_KEY, HopsSSLTestUtils.class.getSimpleName() + ".ssl-server.xml");

        // Set the client certificate with correct CN and signed by the CA
        conf.set(HopsSSLSocketFactory.CryptoKeys.KEY_STORE_FILEPATH_KEY.getValue(), c_clientKeyStore.toString());
        conf.set(HopsSSLSocketFactory.CryptoKeys.KEY_STORE_PASSWORD_KEY.getValue(), passwd);
        conf.set(HopsSSLSocketFactory.CryptoKeys.KEY_PASSWORD_KEY.getValue(), passwd);
        conf.set(HopsSSLSocketFactory.CryptoKeys.TRUST_STORE_FILEPATH_KEY.getValue(),
                c_clientTrustStore.toString());
        conf.set(HopsSSLSocketFactory.CryptoKeys.TRUST_STORE_PASSWORD_KEY.getValue(), passwd);
        conf.set(HopsSSLSocketFactory.CryptoKeys.SOCKET_ENABLED_PROTOCOL.getValue(), "TLSv1.2");
    }

    protected List<Path> prepareCryptoMaterial(Configuration conf, String outDir) throws Exception {
        List<Path> filesToPurge = new ArrayList<>();
        this.outDir = outDir;

        String keyAlg = "RSA";
        String signAlg = "SHA256withRSA";

        // Generate CA
        KeyPair caKeyPair = KeyStoreTestUtil.generateKeyPair(keyAlg);
        X509Certificate caCert = KeyStoreTestUtil.generateCertificate("CN=CARoot", caKeyPair, 42, signAlg);

        // Generate server certificate signed by CA
        KeyPair serverKeyPair = KeyStoreTestUtil.generateKeyPair(keyAlg);
        X509Certificate serverCrt = KeyStoreTestUtil.generateSignedCertificate("CN=serverCrt", serverKeyPair, 42,
                signAlg, caKeyPair.getPrivate(), caCert);

        serverKeyStore = Paths.get(outDir, "server.keystore.jks");
        serverTrustStore = Paths.get(outDir, "server.truststore.jks");
        filesToPurge.add(serverKeyStore);
        filesToPurge.add(serverTrustStore);
        KeyStoreTestUtil.createKeyStore(serverKeyStore.toString(), passwd, passwd, "server_alias",
                serverKeyPair.getPrivate(), serverCrt);
        KeyStoreTestUtil.createTrustStore(serverTrustStore.toString(), passwd, "CARoot", caCert);

        // Generate client certificate with the correct CN field and signed by the CA
        KeyPair c_clientKeyPair = KeyStoreTestUtil.generateKeyPair(keyAlg);
        String c_cn = "CN=" + UserGroupInformation.getCurrentUser().getUserName();
        X509Certificate c_clientCrt = KeyStoreTestUtil.generateSignedCertificate(c_cn, c_clientKeyPair, 42, signAlg,
                caKeyPair.getPrivate(), caCert);

        c_clientKeyStore = Paths.get(outDir, "c_client.keystore.jks");
        c_clientTrustStore = Paths.get(outDir, "c_client.truststore.jks");
        filesToPurge.add(c_clientKeyStore);
        filesToPurge.add(c_clientTrustStore);
        KeyStoreTestUtil.createKeyStore(c_clientKeyStore.toString(), passwd, passwd, "c_client_alias",
                c_clientKeyPair.getPrivate(), c_clientCrt);
        KeyStoreTestUtil.createTrustStore(c_clientTrustStore.toString(), passwd, "CARoot", caCert);

        if (error_mode.equals(CERT_ERR.NO_CA)) {
            LOG.info("no ca error mode");
            // Generate client certificate with the correct CN field but NOT signed by the CA
            KeyPair noCA_clientKeyPair = KeyStoreTestUtil.generateKeyPair(keyAlg);
            X509Certificate noCA_clientCrt = KeyStoreTestUtil.generateCertificate(c_cn, noCA_clientKeyPair, 42,
                    signAlg);

            err_clientKeyStore = Paths.get(outDir, "noCA_client.keystore.jks");
            err_clientTrustStore = Paths.get(outDir, "noCA_client.truststore.jks");
            filesToPurge.add(err_clientKeyStore);
            filesToPurge.add(err_clientTrustStore);
            KeyStoreTestUtil.createKeyStore(err_clientKeyStore.toString(), passwd, passwd, "noca_client_alias",
                    noCA_clientKeyPair.getPrivate(), noCA_clientCrt);
            KeyStoreTestUtil.createTrustStore(err_clientTrustStore.toString(), passwd, "CARoot", caCert);

        } else if (error_mode.equals(CERT_ERR.ERR_CN)) {
            LOG.info("wrong cn error mode");
            // Generate client with INCORRECT CN field but signed by the CA
            KeyPair errCN_clientKeyPair = KeyStoreTestUtil.generateKeyPair(keyAlg);
            X509Certificate errCN_clientCrt = KeyStoreTestUtil.generateSignedCertificate("CN=Phil Lynott",
                    errCN_clientKeyPair, 42, signAlg, caKeyPair.getPrivate(), caCert);

            err_clientKeyStore = Paths.get(outDir, "errCN_client.keystore.jks");
            err_clientTrustStore = Paths.get(outDir, "errCN_client.truststore.jks");
            filesToPurge.add(err_clientKeyStore);
            filesToPurge.add(err_clientTrustStore);
            KeyStoreTestUtil.createKeyStore(err_clientKeyStore.toString(), passwd, passwd, "errcn_client_alias",
                    errCN_clientKeyPair.getPrivate(), errCN_clientCrt);
            KeyStoreTestUtil.createTrustStore(err_clientTrustStore.toString(), passwd, "CARoot", caCert);
        }

        return filesToPurge;
    }
}