/** * 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; } }