blob: 53b16db6339c89ddfdcf84358e9832c768461a3d [file] [log] [blame]
/*
* 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.brooklyn.entity.java;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import org.apache.brooklyn.util.collections.MutableMap.Builder;
import org.apache.brooklyn.util.core.crypto.FluentKeySigner;
import org.apache.brooklyn.util.core.crypto.SecureKeys;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.jmx.jmxmp.JmxmpAgent;
import org.apache.brooklyn.util.net.Urls;
import com.google.common.base.Preconditions;
public class JmxmpSslSupport {
final static String BROOKLYN_VERSION = "0.8.0-incubating"; // BROOKLYN_VERSION (updated by script)
private final JmxSupport jmxSupport;
private KeyStore agentTrustStore;
private KeyStore agentKeyStore;
public JmxmpSslSupport(JmxSupport jmxSupport) {
this.jmxSupport = Preconditions.checkNotNull(jmxSupport);
}
public String getJmxSslKeyStoreFilePath() {
return Urls.mergePaths(jmxSupport.getRunDir(), "jmx-keystore");
}
public String getJmxSslTrustStoreFilePath() {
return Urls.mergePaths(jmxSupport.getRunDir(), "jmx-truststore");
}
public void applyAgentJmxJavaSystemProperties(Builder<String, Object> result) {
result.
put(JmxmpAgent.USE_SSL_PROPERTY, true).
put(JmxmpAgent.AUTHENTICATE_CLIENTS_PROPERTY, true).
// the option below wants a jmxremote.password file; we use certs (above) to authenticate
put("com.sun.management.jmxremote.authenticate", false);
result.
put(JmxmpAgent.JMXMP_KEYSTORE_FILE_PROPERTY, getJmxSslKeyStoreFilePath()).
put(JmxmpAgent.JMXMP_TRUSTSTORE_FILE_PROPERTY, getJmxSslTrustStoreFilePath());
}
public FluentKeySigner getBrooklynRootSigner() {
// TODO use brooklyn root CA keys etc
return new FluentKeySigner("brooklyn-root");
}
/** builds remote keystores, stores config keys/certs, and copies necessary files across */
public void install() {
try {
// build truststore and keystore
FluentKeySigner signer = getBrooklynRootSigner();
KeyPair jmxAgentKey = SecureKeys.newKeyPair();
X509Certificate jmxAgentCert = signer.newCertificateFor("jmxmp-agent", jmxAgentKey);
agentKeyStore = SecureKeys.newKeyStore();
agentKeyStore.setKeyEntry("jmxmp-agent", jmxAgentKey.getPrivate(),
// TODO jmx.ssl.agent.keyPassword
"".toCharArray(),
new Certificate[] { jmxAgentCert });
ByteArrayOutputStream agentKeyStoreBytes = new ByteArrayOutputStream();
agentKeyStore.store(agentKeyStoreBytes,
// TODO jmx.ssl.agent.keyStorePassword
"".toCharArray());
agentTrustStore = SecureKeys.newKeyStore();
agentTrustStore.setCertificateEntry("brooklyn", getJmxAccessCert());
ByteArrayOutputStream agentTrustStoreBytes = new ByteArrayOutputStream();
agentTrustStore.store(agentTrustStoreBytes, "".toCharArray());
// install the truststore and keystore and rely on JmxSupport to install the agent
Tasks.setBlockingDetails("Copying keystore and truststore to the server.");
try {
jmxSupport.getMachine().get().copyTo(new ByteArrayInputStream(agentKeyStoreBytes.toByteArray()), getJmxSslKeyStoreFilePath());
jmxSupport.getMachine().get().copyTo(new ByteArrayInputStream(agentTrustStoreBytes.toByteArray()), getJmxSslTrustStoreFilePath());
} finally {
Tasks.resetBlockingDetails();
}
} catch (Exception e) {
throw Exceptions.propagate(e);
}
}
public synchronized Certificate getJmxAccessCert() {
Certificate cert = jmxSupport.getConfig(UsesJmx.JMX_SSL_ACCESS_CERT);
if (cert!=null) return cert;
// TODO load from keyStoreUrl
KeyPair jmxAccessKey = SecureKeys.newKeyPair();
X509Certificate jmxAccessCert = getBrooklynRootSigner().newCertificateFor("brooklyn-jmx-access", jmxAccessKey);
jmxSupport.setConfig(UsesJmx.JMX_SSL_ACCESS_CERT, jmxAccessCert);
jmxSupport.setConfig(UsesJmx.JMX_SSL_ACCESS_KEY, jmxAccessKey.getPrivate());
return jmxAccessCert;
}
public synchronized PrivateKey getJmxAccessKey() {
PrivateKey key = jmxSupport.getConfig(UsesJmx.JMX_SSL_ACCESS_KEY);
if (key!=null) return key;
getJmxAccessCert();
return jmxSupport.getConfig(UsesJmx.JMX_SSL_ACCESS_KEY);
}
}