blob: db7a2b98690d59b427bc346a67b587719cd38356 [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.cassandra.security;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.cassandra.config.TransparentDataEncryptionOptions;
/**
* A {@code KeyProvider} that retrieves keys from a java keystore.
*/
public class JKSKeyProvider implements KeyProvider
{
private static final Logger logger = LoggerFactory.getLogger(JKSKeyProvider.class);
static final String PROP_KEYSTORE = "keystore";
static final String PROP_KEYSTORE_PW = "keystore_password";
static final String PROP_KEYSTORE_TYPE = "store_type";
static final String PROP_KEY_PW = "key_password";
private final KeyStore store;
private final boolean isJceks;
private final TransparentDataEncryptionOptions options;
public JKSKeyProvider(TransparentDataEncryptionOptions options)
{
this.options = options;
logger.info("initializing keystore from file {}", options.get(PROP_KEYSTORE));
try (FileInputStream inputStream = new FileInputStream(options.get(PROP_KEYSTORE)))
{
store = KeyStore.getInstance(options.get(PROP_KEYSTORE_TYPE));
store.load(inputStream, options.get(PROP_KEYSTORE_PW).toCharArray());
isJceks = store.getType().equalsIgnoreCase("jceks");
}
catch (Exception e)
{
throw new RuntimeException("couldn't load keystore", e);
}
}
public Key getSecretKey(String keyAlias) throws IOException
{
// there's a lovely behavior with jceks files that all aliases are lower-cased
if (isJceks)
keyAlias = keyAlias.toLowerCase();
Key key;
try
{
String password = options.get(PROP_KEY_PW);
if (password == null || password.isEmpty())
password = options.get(PROP_KEYSTORE_PW);
key = store.getKey(keyAlias, password.toCharArray());
}
catch (Exception e)
{
throw new IOException("unable to load key from keystore");
}
if (key == null)
throw new IOException(String.format("key %s was not found in keystore", keyAlias));
return key;
}
}