Skip to content

Commit

Permalink
HDDS-1946. CertificateClient should not persist keys/certs to ozone.m… (
Browse files Browse the repository at this point in the history
  • Loading branch information
vivekratnavel authored and ahussein committed Oct 29, 2019
1 parent 458b30d commit 20c6358
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 193 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
*/
public class XceiverClientGrpc extends XceiverClientSpi {
static final Logger LOG = LoggerFactory.getLogger(XceiverClientGrpc.class);
private static final String COMPONENT = "dn";
private final Pipeline pipeline;
private final Configuration config;
private Map<UUID, XceiverClientProtocolServiceStub> asyncStubs;
Expand Down Expand Up @@ -150,9 +151,9 @@ private void connectToDatanode(DatanodeDetails dn, String encodedToken)
.intercept(new ClientCredentialInterceptor(userName, encodedToken),
new GrpcClientInterceptor());
if (secConfig.isGrpcTlsEnabled()) {
File trustCertCollectionFile = secConfig.getTrustStoreFile();
File privateKeyFile = secConfig.getClientPrivateKeyFile();
File clientCertChainFile = secConfig.getClientCertChainFile();
File trustCertCollectionFile = secConfig.getTrustStoreFile(COMPONENT);
File privateKeyFile = secConfig.getClientPrivateKeyFile(COMPONENT);
File clientCertChainFile = secConfig.getClientCertChainFile(COMPONENT);

SslContextBuilder sslContextBuilder = GrpcSslContexts.forClient();
if (trustCertCollectionFile != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.apache.hadoop.hdds.security.x509;

import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ozone.OzoneConfigKeys;
import org.apache.ratis.thirdparty.io.netty.handler.ssl.SslProvider;
Expand Down Expand Up @@ -246,23 +247,12 @@ public String getPrivateKeyFileName() {
return privateKeyFileName;
}

/**
* Returns the File path to where keys are stored.
*
* @return path Key location.
*/
public Path getKeyLocation() {
Preconditions.checkNotNull(this.metadatDir, "Metadata directory can't be"
+ " null. Please check configs.");
return Paths.get(metadatDir, keyDir);
}

/**
* Returns the File path to where keys are stored with an additional component
* name inserted in between.
*
* @param component - Component Name - String.
* @return Path location.
* @return Path Key location.
*/
public Path getKeyLocation(String component) {
Preconditions.checkNotNull(this.metadatDir, "Metadata directory can't be"
Expand All @@ -271,18 +261,8 @@ public Path getKeyLocation(String component) {
}

/**
* Returns the File path to where keys are stored.
*
* @return path Key location.
*/
public Path getCertificateLocation() {
Preconditions.checkNotNull(this.metadatDir, "Metadata directory can't be"
+ " null. Please check configs.");
return Paths.get(metadatDir, certificateDir);
}

/**
* Returns the File path to where keys are stored with an addition component
* Returns the File path to where certificates are stored with an addition
* component
* name inserted in between.
*
* @param component - Component Name - String.
Expand Down Expand Up @@ -379,31 +359,75 @@ public boolean isGrpcMutualTlsRequired() {
return this.grpcMutualTlsRequired;
}

/**
* Returns the TLS-enabled gRPC client private key file(Only needed for mutual
* authentication) for the given component.
* @param component name of the component.
* @return the TLS-enabled gRPC client private key file.
*/
public File getClientPrivateKeyFile(String component) {
return Paths.get(getKeyLocation(component).toString(),
"client." + privateKeyFileName).toFile();
}

/**
* Returns the TLS-enabled gRPC client private key file(Only needed for mutual
* authentication).
* @return the TLS-enabled gRPC client private key file.
*/
public File getClientPrivateKeyFile() {
return Paths.get(getKeyLocation().toString(),
"client." + privateKeyFileName).toFile();
return getClientPrivateKeyFile(StringUtils.EMPTY);
}

/**
* Returns the TLS-enabled gRPC server private key file for the given
* component.
* @param component name of the component.
* @return the TLS-enabled gRPC server private key file.
*/
public File getServerPrivateKeyFile(String component) {
return Paths.get(getKeyLocation(component).toString(),
"server." + privateKeyFileName).toFile();
}

/**
* Returns the TLS-enabled gRPC server private key file.
* @return the TLS-enabled gRPC server private key file.
*/
public File getServerPrivateKeyFile() {
return Paths.get(getKeyLocation().toString(),
"server." + privateKeyFileName).toFile();
return getServerPrivateKeyFile(StringUtils.EMPTY);
}

/**
* Get the trusted CA certificate file for the given component. (CA
* certificate)
* @param component name of the component.
* @return the trusted CA certificate.
*/
public File getTrustStoreFile(String component) {
return Paths.get(getKeyLocation(component).toString(),
trustStoreFileName).
toFile();
}

/**
* Get the trusted CA certificate file. (CA certificate)
* @return the trusted CA certificate.
*/
public File getTrustStoreFile() {
return Paths.get(getKeyLocation().toString(), trustStoreFileName).
return getTrustStoreFile(StringUtils.EMPTY);
}

/**
* Get the TLS-enabled gRPC Client certificate chain file for the given
* component (only needed for
* mutual authentication).
* @param component name of the component.
* @return the TLS-enabled gRPC Server certificate chain file.
*/
public File getClientCertChainFile(String component) {
return Paths.get(getKeyLocation(component).toString(),
clientCertChainFileName).
toFile();
}

Expand All @@ -413,7 +437,18 @@ public File getTrustStoreFile() {
* @return the TLS-enabled gRPC Server certificate chain file.
*/
public File getClientCertChainFile() {
return Paths.get(getKeyLocation().toString(), clientCertChainFileName).
return getClientCertChainFile(StringUtils.EMPTY);
}

/**
* Get the TLS-enabled gRPC Server certificate chain file for the given
* component.
* @param component name of the component.
* @return the TLS-enabled gRPC Server certificate chain file.
*/
public File getServerCertChainFile(String component) {
return Paths.get(getKeyLocation(component).toString(),
serverCertChainFileName).
toFile();
}

Expand All @@ -422,8 +457,7 @@ public File getClientCertChainFile() {
* @return the TLS-enabled gRPC Server certificate chain file.
*/
public File getServerCertChainFile() {
return Paths.get(getKeyLocation().toString(), serverCertChainFileName).
toFile();
return getServerCertChainFile(StringUtils.EMPTY);
}

/**
Expand All @@ -437,7 +471,7 @@ public SslProvider getGrpcSslProvider() {

/**
* Return true if using test certificates with authority as localhost.
* This should be used only for unit test where certifiates are generated
* This should be used only for unit test where certificates are generated
* by openssl with localhost as DN and should never use for production as it
* will bypass the hostname/ip matching verification.
* @return true if using test certificates.
Expand All @@ -464,7 +498,7 @@ private Provider initSecurityProvider(String providerName) {

/**
* Returns max date for which S3 tokens will be valid.
* */
*/
public long getS3TokenMaxDate() {
return getConfiguration().getTimeDuration(
OzoneConfigKeys.OZONE_S3_TOKEN_MAX_LIFETIME_KEY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,24 @@
import org.slf4j.LoggerFactory;

import org.apache.hadoop.hdds.security.x509.SecurityConfig;

/**
* Certificate client for DataNodes.
*/
public class DNCertificateClient extends DefaultCertificateClient {

private static final Logger LOG =
LoggerFactory.getLogger(DNCertificateClient.class);

public static final String COMPONENT_NAME = "dn";

public DNCertificateClient(SecurityConfig securityConfig,
String certSerialId) {
super(securityConfig, LOG, certSerialId);
super(securityConfig, LOG, certSerialId, COMPONENT_NAME);
}

public DNCertificateClient(SecurityConfig securityConfig) {
super(securityConfig, LOG, null);
super(securityConfig, LOG, null, COMPONENT_NAME);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,18 @@ public abstract class DefaultCertificateClient implements CertificateClient {
private X509Certificate x509Certificate;
private Map<String, X509Certificate> certificateMap;
private String certSerialId;
private String component;


DefaultCertificateClient(SecurityConfig securityConfig, Logger log,
String certSerialId) {
String certSerialId, String component) {
Objects.requireNonNull(securityConfig);
this.securityConfig = securityConfig;
keyCodec = new KeyCodec(securityConfig);
keyCodec = new KeyCodec(securityConfig, component);
this.logger = log;
this.certificateMap = new ConcurrentHashMap<>();
this.certSerialId = certSerialId;
this.component = component;

loadAllCertificates();
}
Expand All @@ -108,15 +110,15 @@ public abstract class DefaultCertificateClient implements CertificateClient {
* */
private void loadAllCertificates() {
// See if certs directory exists in file system.
Path certPath = securityConfig.getCertificateLocation();
Path certPath = securityConfig.getCertificateLocation(component);
if (Files.exists(certPath) && Files.isDirectory(certPath)) {
getLogger().info("Loading certificate from location:{}.",
certPath);
File[] certFiles = certPath.toFile().listFiles();

if (certFiles != null) {
CertificateCodec certificateCodec =
new CertificateCodec(securityConfig);
new CertificateCodec(securityConfig, component);
for (File file : certFiles) {
if (file.isFile()) {
try {
Expand Down Expand Up @@ -158,7 +160,7 @@ public PrivateKey getPrivateKey() {
return privateKey;
}

Path keyPath = securityConfig.getKeyLocation();
Path keyPath = securityConfig.getKeyLocation(component);
if (OzoneSecurityUtil.checkIfFileExist(keyPath,
securityConfig.getPrivateKeyFileName())) {
try {
Expand All @@ -182,7 +184,7 @@ public PublicKey getPublicKey() {
return publicKey;
}

Path keyPath = securityConfig.getKeyLocation();
Path keyPath = securityConfig.getKeyLocation(component);
if (OzoneSecurityUtil.checkIfFileExist(keyPath,
securityConfig.getPublicKeyFileName())) {
try {
Expand Down Expand Up @@ -477,9 +479,10 @@ public void storeCertificate(String pemEncodedCert, boolean force)
@Override
public void storeCertificate(String pemEncodedCert, boolean force,
boolean caCert) throws CertificateException {
CertificateCodec certificateCodec = new CertificateCodec(securityConfig);
CertificateCodec certificateCodec = new CertificateCodec(securityConfig,
component);
try {
Path basePath = securityConfig.getCertificateLocation();
Path basePath = securityConfig.getCertificateLocation(component);

X509Certificate cert =
CertificateCodec.getX509Certificate(pemEncodedCert);
Expand Down Expand Up @@ -738,7 +741,7 @@ protected boolean validateKeyPair(PublicKey pubKey)
* location.
* */
protected void bootstrapClientKeys() throws CertificateException {
Path keyPath = securityConfig.getKeyLocation();
Path keyPath = securityConfig.getKeyLocation(component);
if (Files.notExists(keyPath)) {
try {
Files.createDirectories(keyPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ public class OMCertificateClient extends DefaultCertificateClient {
private static final Logger LOG =
LoggerFactory.getLogger(OMCertificateClient.class);

public static final String COMPONENT_NAME = "om";

public OMCertificateClient(SecurityConfig securityConfig,
String certSerialId) {
super(securityConfig, LOG, certSerialId);
super(securityConfig, LOG, certSerialId, COMPONENT_NAME);
}

public OMCertificateClient(SecurityConfig securityConfig) {
super(securityConfig, LOG, null);
super(securityConfig, LOG, null, COMPONENT_NAME);
}

protected InitResponse handleCase(InitCase init) throws
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@

package org.apache.hadoop.hdds.security.x509.certificate.utils;

import com.google.common.base.Preconditions;
import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
import org.bouncycastle.cert.X509CertificateHolder;
Expand Down Expand Up @@ -70,7 +68,7 @@ public class CertificateCodec {
Stream.of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE)
.collect(Collectors.toSet());
/**
* Creates an CertificateCodec.
* Creates a CertificateCodec with component name.
*
* @param config - Security Config.
* @param component - Component String.
Expand All @@ -80,27 +78,6 @@ public CertificateCodec(SecurityConfig config, String component) {
this.location = securityConfig.getCertificateLocation(component);
}

/**
* Creates an CertificateCodec.
*
* @param config - Security Config.
*/
public CertificateCodec(SecurityConfig config) {
this.securityConfig = config;
this.location = securityConfig.getCertificateLocation();
}

/**
* Creates an CertificateCodec.
*
* @param configuration - Configuration
*/
public CertificateCodec(Configuration configuration) {
Preconditions.checkNotNull(configuration, "Config cannot be null");
this.securityConfig = new SecurityConfig(configuration);
this.location = securityConfig.getCertificateLocation();
}

/**
* Returns a X509 Certificate from the Certificate Holder.
*
Expand Down
Loading

0 comments on commit 20c6358

Please sign in to comment.