/**
* 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.hadoop.gateway.services.security.impl;
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import org.apache.hadoop.gateway.i18n.GatewaySpiMessages;
import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
import org.apache.hadoop.gateway.services.ServiceLifecycleException;
import org.apache.hadoop.gateway.services.security.KeystoreServiceException;
import org.apache.hadoop.gateway.services.security.impl.X509CertificateUtil;
public class CMFKeystoreService extends BaseKeystoreService {
private static GatewaySpiMessages LOG = MessagesFactory.get( GatewaySpiMessages.class );
private static final String TEST_CERT_DN = "CN=hadoop,OU=Test,O=Hadoop,L=Test,ST=Test,C=US";
private static final String CREDENTIALS_SUFFIX = "-credentials.jceks";
private String serviceName = null;
public CMFKeystoreService(String keystoreDir, String serviceName)
throws ServiceLifecycleException {
this.serviceName = serviceName;
this.keyStoreDir = keystoreDir + File.separator;
File ksd = new File(this.keyStoreDir);
if (!ksd.exists() && !ksd.mkdirs()) {
throw new ServiceLifecycleException("Cannot create the keystore directory");
}
}
public void createKeystore() throws KeystoreServiceException {
String filename = keyStoreDir + serviceName + ".jks";
createKeystore(filename, "JKS");
}
public KeyStore getKeystore() throws KeystoreServiceException {
final File keyStoreFile = new File( keyStoreDir + serviceName );
return getKeystore(keyStoreFile, "JKS");
}
public void addSelfSignedCert(String alias, char[] passphrase)
throws KeystoreServiceException {
KeyPairGenerator keyPairGenerator;
try {
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair KPair = keyPairGenerator.generateKeyPair();
X509Certificate cert = X509CertificateUtil.generateCertificate(TEST_CERT_DN, KPair, 365, "SHA1withRSA");
KeyStore privateKS = getKeystore();
if (privateKS != null) {
privateKS.setKeyEntry(alias, KPair.getPrivate(),
passphrase,
new java.security.cert.Certificate[]{cert});
writeKeystoreToFile(privateKS, new File( keyStoreDir + serviceName ));
} else {
throw new IOException("Unable to open gateway keystore.");
}
} catch (NoSuchAlgorithmException e) {
LOG.failedToAddSeflSignedCertForGateway(alias, e);
} catch (GeneralSecurityException e) {
LOG.failedToAddSeflSignedCertForGateway(alias, e);
} catch (IOException e) {
LOG.failedToAddSeflSignedCertForGateway(alias, e);
}
}
public void createCredentialStore() throws KeystoreServiceException {
String filename = keyStoreDir + serviceName + CREDENTIALS_SUFFIX;
createKeystore(filename, "JCEKS");
}
public boolean isCredentialStoreAvailable() throws KeystoreServiceException {
final File keyStoreFile = new File( keyStoreDir + serviceName + CREDENTIALS_SUFFIX );
try {
return isKeystoreAvailable(keyStoreFile, "JCEKS");
} catch (KeyStoreException e) {
throw new KeystoreServiceException(e);
} catch (IOException e) {
throw new KeystoreServiceException(e);
}
}
public boolean isKeystoreAvailable() throws KeystoreServiceException {
final File keyStoreFile = new File( keyStoreDir + serviceName + ".jks" );
try {
return isKeystoreAvailable(keyStoreFile, "JKS");
} catch (KeyStoreException e) {
throw new KeystoreServiceException(e);
} catch (IOException e) {
throw new KeystoreServiceException(e);
}
}
public Key getKey(String alias, char[] passphrase) throws KeystoreServiceException {
Key key = null;
KeyStore ks = getKeystore();
if (ks != null) {
try {
key = ks.getKey(alias, passphrase);
} catch (UnrecoverableKeyException e) {
// TODO Auto-generated catch block
LOG.failedToGetKey(alias, e);
} catch (KeyStoreException e) {
LOG.failedToGetKey(alias, e);
} catch (NoSuchAlgorithmException e) {
LOG.failedToGetKey(alias, e);
}
}
return key;
}
public KeyStore getCredentialStore() throws KeystoreServiceException {
final File keyStoreFile = new File( keyStoreDir + serviceName + CREDENTIALS_SUFFIX );
return getKeystore(keyStoreFile, "JCEKS");
}
public void addCredential(String alias, String value) throws KeystoreServiceException {
KeyStore ks = getCredentialStore();
addCredential(alias, value, ks);
final File keyStoreFile = new File( keyStoreDir + serviceName + CREDENTIALS_SUFFIX );
try {
writeKeystoreToFile(ks, keyStoreFile);
} catch (KeyStoreException e) {
LOG.failedToAddCredential(e);
} catch (NoSuchAlgorithmException e) {
LOG.failedToAddCredential(e);
} catch (CertificateException e) {
LOG.failedToAddCredential(e);
} catch (IOException e) {
LOG.failedToAddCredential(e);
}
}
public char[] getCredential(String alias) throws KeystoreServiceException {
char[] credential = null;
KeyStore ks = getCredentialStore();
credential = getCredential(alias, credential, ks);
return credential;
}
}