com.adobe.granite.crypto.spi.base.KeyProviderBase Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2016 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.granite.crypto.spi.base;
import org.osgi.annotation.versioning.ConsumerType;
import com.adobe.granite.crypto.CryptoException;
import com.adobe.granite.crypto.spi.Algorithms;
import com.adobe.granite.crypto.spi.KeyGenerator;
import com.adobe.granite.crypto.spi.KeyProvider;
/**
* Base Implementation of the
* {@link com.adobe.granite.crypto.spi.KeyProvider} service
*
*/
@ConsumerType
public abstract class KeyProviderBase implements KeyProvider {
private static final String AES_KEY_PROPERTY = "master";
private static final String HMAC_KEY_PROPERTY = "hmac";
protected KeyGenerator keyGenerator;
protected KeyProviderBase(KeyGenerator keyGenerator) {
this.keyGenerator = keyGenerator;
}
@Override
public final byte[] obtainKey(Algorithms algorithm) throws CryptoException {
final String algoProp;
if (Algorithms.AES == algorithm) {
algoProp = AES_KEY_PROPERTY;
} else if (Algorithms.HMAC == algorithm) {
algoProp = HMAC_KEY_PROPERTY;
} else if (algorithm == null) {
throw new IllegalArgumentException("Algorithm must not be null or empty");
} else {
throw new IllegalArgumentException("Unrecognised or unsupported signature algorithm: " + algorithm);
}
try {
return getOrCreateKey(algorithm, algoProp);
} catch (Exception e) {
throw new CryptoException("Exception while trying to provide a key");
}
}
/**
* Establishes a connection to the storage system used to
* {@link #readKey(String) read} and/or
* {@link #writeKey(String, byte[]) write} the key material from and
* to the storage.
*
* @throws Exception if an error occurs establishing the connection.
*/
protected abstract void establishConnection() throws Exception;
/**
* Drops the connection to the stoarge system. Any problems while dropping
* the connection must be ignored (or logged) and no exception must be
* thrown.
*
*/
protected abstract void dropConnection();
/**
* Reads key material from the given {@code property}.
*
* @param property The name of the property providing the key material. This is just a single name and
* implementations may handle this in an implementation dependent way.
* @return The key material as a {@code byte[]}
* @throws Exception If an error occurs reading the key material or converting it into a {@code byte[]}.
*/
protected abstract byte[] readKey(final String property) throws Exception;
/**
* Writes key material to the given {@code property}
*
* @param property The name of the property to write the key material to. This is just a single name and
* implementations may handle this in an implementation dependent way.
* @param key The key material to write.
* @throws Exception If an error occurs writing the key material.
*/
protected abstract void writeKey(final String property, final byte[] key)
throws Exception;
//---------------------- PRIVATE METHODS ----------------
private byte[] getOrCreateKey(Algorithms algorithm, String algoProp) throws Exception {
try {
establishConnection();
byte [] key = readKey(algoProp);
if (keyGenerator == null) {
throw new CryptoException("Exception while trying to generate a new key");
}
if (key == null && keyGenerator != null) {
key = keyGenerator.initKey(algorithm);
writeKey(algoProp, key);
}
return key;
} finally {
// cleanup
dropConnection();
}
}
}