accumulo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ctubb...@apache.org
Subject [33/50] [abbrv] ACCUMULO-998 applying Micheal Allen's updated patch for at-rest encryption
Date Wed, 17 Jul 2013 02:33:35 GMT
http://git-wip-us.apache.org/repos/asf/accumulo/blob/65b5a3a3/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleParameters.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleParameters.java b/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleParameters.java
new file mode 100644
index 0000000..7027496
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleParameters.java
@@ -0,0 +1,629 @@
+/*
+ * 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.accumulo.core.security.crypto;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.SecureRandom;
+import java.util.Map;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherOutputStream;
+
+/**
+ * This class defines several parameters needed by by a module providing cryptographic stream support in Accumulo. The following Javadoc details which
+ * parameters are used for which operations (encryption vs. decryption), which ones return values (i.e. are "out" parameters from the {@link CryptoModule}), and
+ * which ones are required versus optional in certain situations.
+ * 
+ * Most of the time, these classes can be constructed using
+ * {@link CryptoModuleFactory#createParamsObjectFromAccumuloConfiguration(org.apache.accumulo.core.conf.AccumuloConfiguration)}.
+ */
+public class CryptoModuleParameters {
+  
+  /**
+   * Gets the name of the symmetric algorithm to use for encryption.
+   * 
+   * @see CryptoModuleParameters#setAlgorithmName(String)
+   */
+  
+  public String getAlgorithmName() {
+    return algorithmName;
+  }
+  
+  /**
+   * Sets the name of the symmetric algorithm to use for an encryption stream.
+   * <p>
+   * Valid names are names recognized by your cryptographic engine provider. For the default Java provider, valid names would include things like "AES", "RC4",
+   * "DESede", etc.
+   * <p>
+   * For <b>encryption</b>, this value is <b>required</b> and is always used. Its value should be prepended or otherwise included with the ciphertext for future
+   * decryption. <br>
+   * For <b>decryption</b>, this value is often disregarded in favor of the value encoded with the ciphertext.
+   * 
+   * @param algorithmName
+   *          the name of the cryptographic algorithm to use.
+   * @see <a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#AppA">Standard Algorithm Names in JCE</a>
+   * 
+   */
+  
+  public void setAlgorithmName(String algorithmName) {
+    this.algorithmName = algorithmName;
+  }
+  
+  /**
+   * Gets the name of the encryption mode to use for encryption.
+   * 
+   * @see CryptoModuleParameters#setEncryptionMode(String)
+   */
+  
+  public String getEncryptionMode() {
+    return encryptionMode;
+  }
+  
+  /**
+   * Sets the name of the encryption mode to use for an encryption stream.
+   * <p>
+   * Valid names are names recognized by your cryptographic engine provider. For the default Java provider, valid names would include things like "EBC", "CBC",
+   * "CFB", etc.
+   * <p>
+   * For <b>encryption</b>, this value is <b>required</b> and is always used. Its value should be prepended or otherwise included with the ciphertext for future
+   * decryption. <br>
+   * For <b>decryption</b>, this value is often disregarded in favor of the value encoded with the ciphertext.
+   * 
+   * @param encryptionMode
+   *          the name of the encryption mode to use.
+   * @see <a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#AppA">Standard Mode Names in JCE</a>
+   * 
+   */
+  
+  public void setEncryptionMode(String encryptionMode) {
+    this.encryptionMode = encryptionMode;
+  }
+  
+  /**
+   * Gets the name of the padding type to use for encryption.
+   * 
+   * @see CryptoModuleParameters#setPadding(String)
+   */
+  
+  public String getPadding() {
+    return padding;
+  }
+  
+  /**
+   * Sets the name of the padding type to use for an encryption stream.
+   * <p>
+   * Valid names are names recognized by your cryptographic engine provider. For the default Java provider, valid names would include things like
+   * "PKCS5Padding", "None", etc.
+   * <p>
+   * For <b>encryption</b>, this value is <b>required</b> and is always used. Its value should be prepended or otherwise included with the ciphertext for future
+   * decryption. <br>
+   * For <b>decryption</b>, this value is often disregarded in favor of the value encoded with the ciphertext.
+   * 
+   * @param padding
+   *          the name of the padding type to use.
+   * @see <a href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#AppA">Standard Padding Names in JCE</a>
+   * 
+   */
+  public void setPadding(String padding) {
+    this.padding = padding;
+  }
+  
+  /**
+   * Gets the plaintext secret key.
+   * <p>
+   * For <b>decryption</b>, this value is often the out parameter of using a secret key encryption strategy to decrypt an encrypted version of this secret key.
+   * (See {@link CryptoModuleParameters#setKeyEncryptionStrategyClass(String)}.)
+   * 
+   * 
+   * @see CryptoModuleParameters#setPlaintextKey(byte[])
+   */
+  public byte[] getPlaintextKey() {
+    return plaintextKey;
+  }
+  
+  /**
+   * Sets the plaintext secret key that will be used to encrypt and decrypt bytes.
+   * <p>
+   * Valid values and lengths for this secret key depend entirely on the algorithm type. Refer to the documentation about the algorithm for further information.
+   * <p>
+   * For <b>encryption</b>, this value is <b>optional</b>. If it is not provided, it will be automatically generated by the underlying cryptographic module. <br>
+   * For <b>decryption</b>, this value is often obtained from the underlying cipher stream, or derived from the encrypted version of the key (see
+   * {@link CryptoModuleParameters#setEncryptedKey(byte[])}).
+   * 
+   * @param plaintextKey
+   *          the value of the plaintext secret key
+   */
+  
+  public void setPlaintextKey(byte[] plaintextKey) {
+    this.plaintextKey = plaintextKey;
+  }
+  
+  /**
+   * Gets the length of the secret key.
+   * 
+   * @see CryptoModuleParameters#setKeyLength(int)
+   */
+  public int getKeyLength() {
+    return keyLength;
+  }
+  
+  /**
+   * Sets the length of the secret key that will be used to encrypt and decrypt bytes.
+   * <p>
+   * Valid lengths depend entirely on the algorithm type. Refer to the documentation about the algorithm for further information. (For example, AES may use
+   * either 128 or 256 bit keys in the default Java cryptography provider.)
+   * <p>
+   * For <b>encryption</b>, this value is <b>required if the secret key is not set</b>. <br>
+   * For <b>decryption</b>, this value is often obtained from the underlying cipher stream, or derived from the encrypted version of the key (see
+   * {@link CryptoModuleParameters#setEncryptedKey(byte[])}).
+   * 
+   * @param keyLength
+   *          the length of the secret key to be generated
+   */
+  
+  public void setKeyLength(int keyLength) {
+    this.keyLength = keyLength;
+  }
+  
+  /**
+   * Gets the random number generator name.
+   * 
+   * @see CryptoModuleParameters#setRandomNumberGenerator(String)
+   */
+  
+  public String getRandomNumberGenerator() {
+    return randomNumberGenerator;
+  }
+  
+  /**
+   * Sets the name of the random number generator to use. The default for this for the baseline JCE implementation is "SHA1PRNG".
+   * <p>
+   * 
+   * <p>
+   * For <b>encryption</b>, this value is <b>required</b>. <br>
+   * For <b>decryption</b>, this value is often obtained from the underlying cipher stream.
+   * 
+   * @param randomNumberGenerator
+   *          the name of the random number generator to use
+   */
+  
+  public void setRandomNumberGenerator(String randomNumberGenerator) {
+    this.randomNumberGenerator = randomNumberGenerator;
+  }
+  
+  /**
+   * Gets the random number generator provider name.
+   * 
+   * @see CryptoModuleParameters#setRandomNumberGeneratorProvider(String)
+   */
+  public String getRandomNumberGeneratorProvider() {
+    return randomNumberGeneratorProvider;
+  }
+  
+  /**
+   * Sets the name of the random number generator provider to use. The default for this for the baseline JCE implementation is "SUN".
+   * <p>
+   * The provider, as the name implies, provides the RNG implementation specified by {@link CryptoModuleParameters#getRandomNumberGenerator()}.
+   * <p>
+   * For <b>encryption</b>, this value is <b>required</b>. <br>
+   * For <b>decryption</b>, this value is often obtained from the underlying cipher stream.
+   * 
+   * @param randomNumberGeneratorProvider
+   *          the name of the provider to use
+   */
+  
+  public void setRandomNumberGeneratorProvider(String randomNumberGeneratorProvider) {
+    this.randomNumberGeneratorProvider = randomNumberGeneratorProvider;
+  }
+  
+  /**
+   * Gets the key encryption strategy class.
+   * 
+   * @see CryptoModuleParameters#setKeyEncryptionStrategyClass(String)
+   */
+  
+  public String getKeyEncryptionStrategyClass() {
+    return keyEncryptionStrategyClass;
+  }
+  
+  /**
+   * Sets the class name of the key encryption strategy class. The class obeys the {@link SecretKeyEncryptionStrategy} interface. It instructs the
+   * {@link DefaultCryptoModule} on how to encrypt the keys it uses to secure the streams.
+   * <p>
+   * The default implementation of this interface, {@link DefaultSecretKeyEncryptionStrategy}, creates a random key encryption key (KEK) as another symmetric
+   * key and places the KEK into HDFS. <i>This is not really very secure.</i> Users of the crypto modules are encouraged to either safeguard that KEK carefully
+   * or to obtain and use another {@link SecretKeyEncryptionStrategy} class.
+   * <p>
+   * For <b>encryption</b>, this value is <b>optional</b>. If it is not specified, then it assumed that the secret keys used for encrypting files will not be
+   * encrypted. This is not a secure approach, thus setting this is highly recommended.<br>
+   * For <b>decryption</b>, this value is often obtained from the underlying cipher stream. However, the underlying stream's value can be overridden (at least
+   * when using {@link DefaultCryptoModule}) by setting the {@link CryptoModuleParameters#setOverrideStreamsSecretKeyEncryptionStrategy(boolean)} to true.
+   * 
+   * @param keyEncryptionStrategyClass
+   *          the name of the key encryption strategy class to use
+   */
+  public void setKeyEncryptionStrategyClass(String keyEncryptionStrategyClass) {
+    this.keyEncryptionStrategyClass = keyEncryptionStrategyClass;
+  }
+  
+  /**
+   * Gets the encrypted version of the plaintext key. This parameter is generally either obtained from an underlying stream or computed in the process of
+   * employed the {@link CryptoModuleParameters#getKeyEncryptionStrategyClass()}.
+   * 
+   * @see CryptoModuleParameters#setEncryptedKey(byte[])
+   */
+  public byte[] getEncryptedKey() {
+    return encryptedKey;
+  }
+  
+  /**
+   * Sets the encrypted version of the plaintext key ({@link CryptoModuleParameters#getPlaintextKey()}). Generally this operation will be done either by:
+   * <p>
+   * <ul>
+   * <li>the code reading an encrypted stream and coming across the encrypted version of one of these keys, OR
+   * <li>the {@link CryptoModuleParameters#getKeyEncryptionStrategyClass()} that encrypted the plaintext key (see
+   * {@link CryptoModuleParameters#getPlaintextKey()}).
+   * <ul>
+   * <p>
+   * For <b>encryption</b>, this value is generally not required, but is usually set by the underlying module during encryption. <br>
+   * For <b>decryption</b>, this value is <b>usually required</b>.
+   * 
+   * 
+   * @param encryptedKey
+   *          the encrypted value of the plaintext key
+   */
+  
+  public void setEncryptedKey(byte[] encryptedKey) {
+    this.encryptedKey = encryptedKey;
+  }
+  
+  /**
+   * Gets the opaque ID associated with the encrypted version of the plaintext key.
+   * 
+   * @see CryptoModuleParameters#setOpaqueKeyEncryptionKeyID(String)
+   * @return
+   */
+  public String getOpaqueKeyEncryptionKeyID() {
+    return opaqueKeyEncryptionKeyID;
+  }
+  
+  /**
+   * Sets an opaque ID assocaited with the encrypted version of the plaintext key.
+   * <p>
+   * Often, implementors of the {@link SecretKeyEncryptionStrategy} will need to record some information about how they encrypted a particular plaintext key.
+   * For example, if the strategy employs several keys for its encryption, it will want to record which key it used. The caller should not have to worry about
+   * the format or contents of this internal ID; thus, the strategy class will encode whatever information it needs into this string. It is then beholden to the
+   * calling code to record this opqaue string properly to the underlying cryptographically-encoded stream, and then set the opaque ID back into this parameter
+   * object upon reading.
+   * <p>
+   * For <b>encryption</b>, this value is generally not required, but will be typically generated and set by the {@link SecretKeyEncryptionStrategy} class (see
+   * {@link CryptoModuleParameters#getKeyEncryptionStrategyClass()}). <br>
+   * For <b>decryption</b>, this value is <b>required</b>, though it will typically be read from the underlying stream.
+   * 
+   * @param opaqueKeyEncryptionKeyID
+   *          the opaque ID assoicated with the encrypted version of the plaintext key (see {@link CryptoModuleParameters#getEncryptedKey()}).
+   */
+  
+  public void setOpaqueKeyEncryptionKeyID(String opaqueKeyEncryptionKeyID) {
+    this.opaqueKeyEncryptionKeyID = opaqueKeyEncryptionKeyID;
+  }
+  
+  /**
+   * Gets the flag that indicates whether or not the module should record its cryptographic parameters to the stream automatically, or rely on the calling code
+   * to do so.
+   * 
+   * @see CryptoModuleParameters#setRecordParametersToStream(boolean)
+   */
+  public boolean getRecordParametersToStream() {
+    return recordParametersToStream;
+  }
+  
+  /**
+   * Gets the flag that indicates whether or not the module should record its cryptographic parameters to the stream automatically, or rely on the calling code
+   * to do so.
+   * 
+   * <p>
+   * 
+   * If this is set to <i>true</i>, then the stream passed to {@link CryptoModule#getEncryptingOutputStream(CryptoModuleParameters)} will be <i>written to by the module</i> before it
+   * is returned to the caller. There are situations where it is easier to let the crypto module do this writing on behalf of the caller, and other times where
+   * it is not appropriate (if the format of the underlying stream must be carefully maintained, for instance).
+   * 
+   * @param recordParametersToStream
+   *          whether or not to require the module to record its parameters to the stream by itself
+   */
+  public void setRecordParametersToStream(boolean recordParametersToStream) {
+    this.recordParametersToStream = recordParametersToStream;
+  }
+  
+  /**
+   * Gets the flag that indicates whether or not to close the underlying stream when the cipher stream is closed.
+   * 
+   * @see CryptoModuleParameters#setCloseUnderylingStreamAfterCryptoStreamClose(boolean)
+   */
+  public boolean getCloseUnderylingStreamAfterCryptoStreamClose() {
+    return closeUnderylingStreamAfterCryptoStreamClose;
+  }
+  
+  /**
+   * Sets the flag that indicates whether or not to close the underlying stream when the cipher stream is closed.
+   * 
+   * <p>
+   * 
+   * {@link CipherOutputStream} will only output its padding bytes when its {@link CipherOutputStream#close()} method is called. However, there are times when a
+   * caller doesn't want its underlying stream closed at the time that the {@link CipherOutputStream} is closed. This flag indicates that the
+   * {@link CryptoModule} should wrap the underlying stream in a basic {@link FilterOutputStream} which will swallow any close() calls and prevent them from
+   * propogating to the underlying stream.
+   * 
+   * @param closeUnderylingStreamAfterCryptoStreamClose
+   *          the flag that indicates whether or not to close the underlying stream when the cipher stream is closed
+   */
+  public void setCloseUnderylingStreamAfterCryptoStreamClose(boolean closeUnderylingStreamAfterCryptoStreamClose) {
+    this.closeUnderylingStreamAfterCryptoStreamClose = closeUnderylingStreamAfterCryptoStreamClose;
+  }
+  
+  /**
+   * Gets the flag that indicates if the underlying stream's key encryption strategy should be overridden by the currently configured key encryption strategy.
+   * 
+   * @see CryptoModuleParameters#setOverrideStreamsSecretKeyEncryptionStrategy(boolean)
+   */
+  public boolean getOverrideStreamsSecretKeyEncryptionStrategy() {
+    return overrideStreamsSecretKeyEncryptionStrategy;
+  }
+  
+  /**
+   * Sets the flag that indicates if the underlying stream's key encryption strategy should be overridden by the currently configured key encryption strategy.
+   * 
+   * <p>
+   * 
+   * So, why is this important? Say you started out with the default secret key encryption strategy. So, now you have a secret key in HDFS that encrypts all the
+   * other secret keys. <i>Then</i> you deploy a key management solution. You want to move that secret key up to the key management server. Great! No problem.
+   * Except, all your encrypted files now contain a setting that says
+   * "hey I was encrypted by the default strategy, so find decrypt my key using that, not the key management server". This setting signals the
+   * {@link CryptoModule} that it should ignore the setting in the file and prefer the one from the configuration.
+   * 
+   * @param overrideStreamsSecretKeyEncryptionStrategy
+   *          the flag that indicates if the underlying stream's key encryption strategy should be overridden by the currently configured key encryption
+   *          strategy
+   */
+  
+  public void setOverrideStreamsSecretKeyEncryptionStrategy(boolean overrideStreamsSecretKeyEncryptionStrategy) {
+    this.overrideStreamsSecretKeyEncryptionStrategy = overrideStreamsSecretKeyEncryptionStrategy;
+  }
+  
+  /**
+   * Gets the plaintext output stream to wrap for encryption.
+   * 
+   * @see CryptoModuleParameters#setPlaintextOutputStream(OutputStream)
+   */
+  public OutputStream getPlaintextOutputStream() {
+    return plaintextOutputStream;
+  }
+  
+  /**
+   * Sets the plaintext output stream to wrap for encryption.
+   * 
+   * <p>
+   * 
+   * For <b>encryption</b>, this parameter is <b>required</b>. <br>
+   * For <b>decryption</b>, this parameter is ignored.
+   * 
+   * @param plaintextOutputStream
+   */
+  public void setPlaintextOutputStream(OutputStream plaintextOutputStream) {
+    this.plaintextOutputStream = plaintextOutputStream;
+  }
+  
+  /**
+   * Gets the encrypted output stream, which is nearly always a wrapped version of the output stream from
+   * {@link CryptoModuleParameters#getPlaintextOutputStream()}.
+   * 
+   * <p>
+   * 
+   * Generally this method is used by {@link CryptoModule} classes as an <i>out</i> parameter from calling
+   * {@link CryptoModule#getEncryptingOutputStream(CryptoModuleParameters)}.
+   * 
+   * @see CryptoModuleParameters#setEncryptedOutputStream(OutputStream)
+   */
+  
+  public OutputStream getEncryptedOutputStream() {
+    return encryptedOutputStream;
+  }
+  
+  /**
+   * Sets the encrypted output stream. This method should really only be called by {@link CryptoModule} implementations unless something very unusual is going
+   * on.
+   * 
+   * @param encryptedOutputStream
+   *          the encrypted version of the stream from output stream from {@link CryptoModuleParameters#getPlaintextOutputStream()}.
+   */
+  public void setEncryptedOutputStream(OutputStream encryptedOutputStream) {
+    this.encryptedOutputStream = encryptedOutputStream;
+  }
+  
+
+  /**
+   * Gets the plaintext input stream, which is nearly always a wrapped version of the output from {@link CryptoModuleParameters#getEncryptedInputStream()}.
+   * 
+   * <p>
+   * 
+   * Generally this method is used by {@link CryptoModule} classes as an <i>out</i> parameter from calling {@link CryptoModule#getDecryptingInputStream(CryptoModuleParameters)}.
+   * 
+   * 
+   * @see CryptoModuleParameters#setPlaintextInputStream(InputStream)
+   */
+  public InputStream getPlaintextInputStream() {
+    return plaintextInputStream;
+  }
+  
+  /**
+   * Sets the plaintext input stream, which is nearly always a wrapped version of the output from {@link CryptoModuleParameters#getEncryptedInputStream()}.
+   * 
+   * <p>
+   * 
+   * This method should really only be called by {@link CryptoModule} implementations.
+   * 
+   * @param plaintextInputStream
+   */
+  
+  public void setPlaintextInputStream(InputStream plaintextInputStream) {
+    this.plaintextInputStream = plaintextInputStream;
+  }
+  
+  /**
+   * Gets the encrypted input stream to wrap for decryption.
+   * 
+   * @see CryptoModuleParameters#setEncryptedInputStream(InputStream)
+   */
+  public InputStream getEncryptedInputStream() {
+    return encryptedInputStream;
+  }
+  
+  /**
+   * Sets the encrypted input stream to wrap for decryption.
+   * 
+   * @param encryptedInputStream
+   */
+  
+  public void setEncryptedInputStream(InputStream encryptedInputStream) {
+    this.encryptedInputStream = encryptedInputStream;
+  }
+  
+  /**
+   * Gets the initialized cipher object.
+   * 
+   * 
+   * @see CryptoModuleParameters#setCipher(Cipher)
+   */
+  public Cipher getCipher() {
+    return cipher;
+  }
+  
+  /**
+   * Sets the initialized cipher object. Generally speaking, callers do not have to create and set this object. There may be circumstances where the cipher
+   * object is created outside of the module (to determine IV lengths, for one). If it is created and you want the module to use the cipher you already
+   * initialized, set it here.
+   * 
+   * @param cipher
+   *          the cipher object
+   */
+  public void setCipher(Cipher cipher) {
+    this.cipher = cipher;
+  }
+  
+  /**
+   * Gets the initialized secure random object.
+   * 
+   * @see CryptoModuleParameters#setSecureRandom(SecureRandom)
+   */
+  public SecureRandom getSecureRandom() {
+    return secureRandom;
+  }
+  
+  /**
+   * Sets the initialized secure random object. Generally speaking, callers do not have to create and set this object. There may be circumstances where the
+   * random object is created outside of the module (for instance, to create a random secret key). If it is created outside the module and you want the module
+   * to use the random object you already created, set it here.
+   * 
+   * @param secureRandom
+   *          the {@link SecureRandom} object
+   */
+  
+  public void setSecureRandom(SecureRandom secureRandom) {
+    this.secureRandom = secureRandom;
+  }
+  
+  /**
+   * Gets the initialization vector to use for this crypto module.
+   * 
+   * @see CryptoModuleParameters#setInitializationVector(byte[])
+   */
+  public byte[] getInitializationVector() {
+    return initializationVector;
+  }
+  
+  /**
+   * Sets the initialization vector to use for this crypto module.
+   * 
+   * <p>
+   * 
+   * For <b>encryption</b>, this parameter is <i>optional</i>. If the initialization vector is created by the caller, for whatever reasons, it can be set here
+   * and the crypto module will use it. <br>
+   * 
+   * For <b>decryption</b>, this parameter is <b>required</b>. It should be read from the underlying stream that contains the encrypted data.
+   * 
+   * @param initializationVector
+   *          the initialization vector to use for this crypto operation.
+   */
+  public void setInitializationVector(byte[] initializationVector) {
+    this.initializationVector = initializationVector;
+  }
+  
+  /**
+   * Gets the overall set of options for the {@link CryptoModule}.
+   * 
+   * @see CryptoModuleParameters#setAllOptions(Map)
+   */
+  public Map<String,String> getAllOptions() {
+    return allOptions;
+  }
+  
+  /**
+   * Sets the overall set of options for the {@link CryptoModule}.
+   * 
+   * <p>
+   * 
+   * Often, options for the cryptographic modules will be encoded as key/value pairs in a configuration file. This map represents those values. It may include
+   * some of the parameters already called out as members of this class. It may contain any number of additional parameters which may be required by different
+   * module or key encryption strategy implementations.
+   * 
+   * @param allOptions
+   *          the set of key/value pairs that confiure a module, based on a configuration file
+   */
+  public void setAllOptions(Map<String,String> allOptions) {
+    this.allOptions = allOptions;
+  }
+  
+  private String algorithmName = null;
+  private String encryptionMode = null;
+  private String padding = null;
+  private byte[] plaintextKey;
+  private int keyLength = 0;
+  private String randomNumberGenerator = null;
+  private String randomNumberGeneratorProvider = null;
+  
+  private String keyEncryptionStrategyClass;
+  private byte[] encryptedKey;
+  private String opaqueKeyEncryptionKeyID;
+  
+  private boolean recordParametersToStream = true;
+  private boolean closeUnderylingStreamAfterCryptoStreamClose = true;
+  private boolean overrideStreamsSecretKeyEncryptionStrategy = false;
+  
+  private OutputStream plaintextOutputStream;
+  private OutputStream encryptedOutputStream;
+  private InputStream plaintextInputStream;
+  private InputStream encryptedInputStream;
+  
+  private Cipher cipher;
+  private SecureRandom secureRandom;
+  private byte[] initializationVector;
+  
+  private Map<String,String> allOptions;
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/65b5a3a3/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModule.java b/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModule.java
index 58e1e75..905eb6e 100644
--- a/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModule.java
+++ b/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModule.java
@@ -22,8 +22,6 @@ import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.io.PushbackInputStream;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
@@ -41,250 +39,379 @@ import org.apache.accumulo.core.conf.Property;
 import org.apache.log4j.Logger;
 
 /**
- * This class contains the gritty details around setting up encrypted streams for reading and writing the log file. It obeys the interface CryptoModule, which
- * other developers can implement to change out this logic as necessary.
+ * This class implements the {@link CryptoModule} interface, defining how calling applications can receive encrypted 
+ * input and output streams.  While the default implementation given here allows for a lot of flexibility in terms of 
+ * choices of algorithm, key encryption strategies, and so on, some Accumulo users may choose to swap out this implementation
+ * for others, and can base their implementation details off of this class's work.
+ * 
+ * In general, the module is quite straightforward: provide it with crypto-related settings and an input/output stream, and
+ * it will hand back those streams wrapped in encrypting (or decrypting) streams.
  * 
- * @deprecated This feature is experimental and may go away in future versions.
  */
-@Deprecated
 public class DefaultCryptoModule implements CryptoModule {
   
-  // This is how *I* like to format my variable declarations. Your mileage may vary.
-  
   private static final String ENCRYPTION_HEADER_MARKER = "---Log File Encrypted (v1)---";
   private static Logger log = Logger.getLogger(DefaultCryptoModule.class);
   
   public DefaultCryptoModule() {}
   
+  
   @Override
-  public OutputStream getEncryptingOutputStream(OutputStream out, Map<String,String> cryptoOpts) throws IOException {
-    
-    log.debug("Initializing crypto output stream");
+  public CryptoModuleParameters initializeCipher(CryptoModuleParameters params) {
+    String cipherTransformation = getCipherTransformation(params); 
     
-    String cipherSuite = cryptoOpts.get(Property.CRYPTO_CIPHER_SUITE.getKey());
+    log.trace(String.format("Using cipher suite \"%s\" with key length %d with RNG \"%s\" and RNG provider \"%s\" and key encryption strategy \"%s\"",
+        cipherTransformation, params.getKeyLength(), params.getRandomNumberGenerator(), params.getRandomNumberGeneratorProvider(),
+        params.getKeyEncryptionStrategyClass()));
     
-    if (cipherSuite.equals("NullCipher")) {
-      return out;
+    if (params.getSecureRandom() == null) {
+      SecureRandom secureRandom = DefaultCryptoModuleUtils.getSecureRandom(params.getRandomNumberGenerator(), params.getRandomNumberGeneratorProvider());
+      params.setSecureRandom(secureRandom);
     }
     
-    String algorithmName = cryptoOpts.get(Property.CRYPTO_CIPHER_ALGORITHM_NAME.getKey());
-    String secureRNG = cryptoOpts.get(Property.CRYPTO_SECURE_RNG.getKey());
-    String secureRNGProvider = cryptoOpts.get(Property.CRYPTO_SECURE_RNG_PROVIDER.getKey());
-    SecureRandom secureRandom = DefaultCryptoModuleUtils.getSecureRandom(secureRNG, secureRNGProvider);
-    int keyLength = Integer.parseInt(cryptoOpts.get(Property.CRYPTO_CIPHER_KEY_LENGTH.getKey()));
-    
-    byte[] randomKey = new byte[keyLength / 8];
-    
-    Map<CryptoInitProperty,Object> cryptoInitParams = new HashMap<CryptoInitProperty,Object>();
-    
-    secureRandom.nextBytes(randomKey);
-    cryptoInitParams.put(CryptoInitProperty.PLAINTEXT_SESSION_KEY, randomKey);
-    
-    SecretKeyEncryptionStrategy keyEncryptionStrategy = CryptoModuleFactory.getSecretKeyEncryptionStrategy(cryptoOpts
-        .get(Property.CRYPTO_SECRET_KEY_ENCRYPTION_STRATEGY_CLASS.getKey()));
-    SecretKeyEncryptionStrategyContext keyEncryptionStrategyContext = keyEncryptionStrategy.getNewContext();
-    
-    keyEncryptionStrategyContext.setPlaintextSecretKey(randomKey);
-    keyEncryptionStrategyContext.setContext(cryptoOpts);
-    
-    keyEncryptionStrategyContext = keyEncryptionStrategy.encryptSecretKey(keyEncryptionStrategyContext);
-    
-    byte[] encryptedRandomKey = keyEncryptionStrategyContext.getEncryptedSecretKey();
-    String opaqueId = keyEncryptionStrategyContext.getOpaqueKeyEncryptionKeyID();
-    
-    OutputStream cipherOutputStream = getEncryptingOutputStream(out, cryptoOpts, cryptoInitParams);
-    
-    // Get the IV from the init params, since we didn't create it but the other getEncryptingOutputStream did
-    byte[] initVector = (byte[]) cryptoInitParams.get(CryptoInitProperty.INITIALIZATION_VECTOR);
+    Cipher cipher = DefaultCryptoModuleUtils.getCipher(cipherTransformation);
     
-    DataOutputStream dataOut = new DataOutputStream(out);
-    
-    // Write a marker to indicate this is an encrypted log file (in case we read it a plain one and need to
-    // not try to decrypt it. Can happen during a failure when the log's encryption settings are changing.
-    dataOut.writeUTF(ENCRYPTION_HEADER_MARKER);
-    
-    // Write out the cipher suite and algorithm used to encrypt this file. In case the admin changes, we want to still
-    // decode the old format.
-    dataOut.writeUTF(cipherSuite);
-    dataOut.writeUTF(algorithmName);
+    if (params.getInitializationVector() == null) {
+      try {
+        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(params.getPlaintextKey(), params.getAlgorithmName()), params.getSecureRandom());
+      } catch (InvalidKeyException e) {
+        log.error("Accumulo encountered an unknown error in generating the secret key object (SecretKeySpec) for an encrypted stream");
+        throw new RuntimeException(e);
+      }
+      
+      params.setInitializationVector(cipher.getIV());
+      
+      
+    } else {
+      try {
+        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(params.getPlaintextKey(), params.getAlgorithmName()), new IvParameterSpec(params.getInitializationVector()));
+      } catch (InvalidKeyException e) {
+        log.error("Accumulo encountered an unknown error in generating the secret key object (SecretKeySpec) for an encrypted stream");
+        throw new RuntimeException(e);
+      } catch (InvalidAlgorithmParameterException e) {
+        log.error("Accumulo encountered an unknown error in setting up the initialization vector for an encrypted stream");
+        throw new RuntimeException(e);
+      }
+    }
+
+    params.setCipher(cipher);
     
-    // Write the init vector to the log file
-    dataOut.writeInt(initVector.length);
-    dataOut.write(initVector);
+    return params;
     
-    // Write out the encrypted session key and the opaque ID
-    dataOut.writeUTF(opaqueId);
-    dataOut.writeInt(encryptedRandomKey.length);
-    dataOut.write(encryptedRandomKey);
+  }
+
+  private String getCipherTransformation(CryptoModuleParameters params) {
+    String cipherSuite = params.getAlgorithmName() + "/" + params.getEncryptionMode() + "/" + params.getPadding();
+    return cipherSuite;
+  }
+  
+  private String[] parseCipherSuite(String cipherSuite) {
+    return cipherSuite.split("/");
+  }
+  
+  private boolean validateNotEmpty(String givenValue, boolean allIsWell, StringBuffer buf, String errorMessage) {
+    if (givenValue == null || givenValue.equals("")) {
+      buf.append(errorMessage);
+      buf.append("\n");
+      return false;
+    }
     
-    // Write the secret key (encrypted) into the log file
-    // dataOut.writeInt(randomKey.length);
-    // dataOut.write(randomKey);
+    return true && allIsWell;
+  }
+
+  private boolean validateNotNull(Object givenValue, boolean allIsWell, StringBuffer buf, String errorMessage) {
+    if (givenValue == null) {
+      buf.append(errorMessage);
+      buf.append("\n");
+      return false;
+    }
     
-    return cipherOutputStream;
+    return true && allIsWell;
   }
+
   
-  @Override
-  public InputStream getDecryptingInputStream(InputStream in, Map<String,String> cryptoOpts) throws IOException {
-    DataInputStream dataIn = new DataInputStream(in);
+  private boolean validateNotZero(int givenValue, boolean allIsWell, StringBuffer buf, String errorMessage) {
+    if (givenValue == 0) {
+      buf.append(errorMessage);
+      buf.append("\n");
+      return false;
+    }
     
-    String marker = dataIn.readUTF();
+    return true && allIsWell;
+  }
+
+  private boolean validateParamsObject(CryptoModuleParameters params, int cipherMode) {
     
-    log.debug("Read encryption header");
-    if (marker.equals(ENCRYPTION_HEADER_MARKER)) {
-      
-      String cipherSuiteFromFile = dataIn.readUTF();
-      String algorithmNameFromFile = dataIn.readUTF();
+    if (cipherMode == Cipher.ENCRYPT_MODE) {
       
-      // Read the secret key and initialization vector from the file
-      int initVectorLength = dataIn.readInt();
-      byte[] initVector = new byte[initVectorLength];
-      dataIn.read(initVector, 0, initVectorLength);
+      StringBuffer errorBuf = new StringBuffer("The following problems were found with the CryptoModuleParameters object you provided for an encrypt operation:\n");
+      boolean allIsWell = true;
       
-      // Read the opaque ID and encrypted session key
-      String opaqueId = dataIn.readUTF();
-      int encryptedSecretKeyLength = dataIn.readInt();
-      byte[] encryptedSecretKey = new byte[encryptedSecretKeyLength];
-      dataIn.read(encryptedSecretKey);
+      allIsWell = validateNotEmpty(params.getAlgorithmName(), allIsWell, errorBuf, "No algorithm name was specified.");
       
-      SecretKeyEncryptionStrategy keyEncryptionStrategy = CryptoModuleFactory.getSecretKeyEncryptionStrategy(cryptoOpts
-          .get(Property.CRYPTO_SECRET_KEY_ENCRYPTION_STRATEGY_CLASS.getKey()));
-      SecretKeyEncryptionStrategyContext keyEncryptionStrategyContext = keyEncryptionStrategy.getNewContext();
-      
-      keyEncryptionStrategyContext.setOpaqueKeyEncryptionKeyID(opaqueId);
-      keyEncryptionStrategyContext.setContext(cryptoOpts);
-      keyEncryptionStrategyContext.setEncryptedSecretKey(encryptedSecretKey);
-      
-      keyEncryptionStrategyContext = keyEncryptionStrategy.decryptSecretKey(keyEncryptionStrategyContext);
+      if (allIsWell && params.getAlgorithmName().equals("NullCipher")) {
+        return true;
+      }
       
-      byte[] secretKey = keyEncryptionStrategyContext.getPlaintextSecretKey();
+      allIsWell = validateNotEmpty(params.getPadding(),                       allIsWell, errorBuf, "No padding was specified.");
+      allIsWell = validateNotZero (params.getKeyLength(),                     allIsWell, errorBuf, "No key length was specified.");
+      allIsWell = validateNotEmpty(params.getEncryptionMode(),                allIsWell, errorBuf, "No encryption mode was specified.");
+      allIsWell = validateNotEmpty(params.getRandomNumberGenerator(),         allIsWell, errorBuf, "No random number generator was specified.");
+      allIsWell = validateNotEmpty(params.getRandomNumberGeneratorProvider(), allIsWell, errorBuf, "No random number generate provider was specified.");
+      allIsWell = validateNotNull (params.getPlaintextOutputStream(),         allIsWell, errorBuf, "No plaintext output stream was specified.");
+
+      if (!allIsWell) {
+        log.error("CryptoModulesParameters object is not valid.");
+        log.error(errorBuf.toString());
+        throw new RuntimeException("CryptoModulesParameters object is not valid.");
+      }
       
-      // int secretKeyLength = dataIn.readInt();
-      // byte[] secretKey = new byte[secretKeyLength];
-      // dataIn.read(secretKey, 0, secretKeyLength);
+      return allIsWell;
       
-      Map<CryptoModule.CryptoInitProperty,Object> cryptoInitParams = new HashMap<CryptoModule.CryptoInitProperty,Object>();
-      cryptoInitParams.put(CryptoInitProperty.CIPHER_SUITE, cipherSuiteFromFile);
-      cryptoInitParams.put(CryptoInitProperty.ALGORITHM_NAME, algorithmNameFromFile);
-      cryptoInitParams.put(CryptoInitProperty.PLAINTEXT_SESSION_KEY, secretKey);
-      cryptoInitParams.put(CryptoInitProperty.INITIALIZATION_VECTOR, initVector);
+    } else if (cipherMode == Cipher.DECRYPT_MODE) {
+      StringBuffer errorBuf = new StringBuffer("The following problems were found with the CryptoModuleParameters object you provided for a decrypt operation:\n");
+      boolean allIsWell = true;
+
+      allIsWell = validateNotEmpty(params.getPadding(),                       allIsWell, errorBuf, "No padding was specified.");
+      allIsWell = validateNotZero (params.getKeyLength(),                     allIsWell, errorBuf, "No key length was specified.");
+      allIsWell = validateNotEmpty(params.getEncryptionMode(),                allIsWell, errorBuf, "No encryption mode was specified.");
+      allIsWell = validateNotEmpty(params.getRandomNumberGenerator(),         allIsWell, errorBuf, "No random number generator was specified.");
+      allIsWell = validateNotEmpty(params.getRandomNumberGeneratorProvider(), allIsWell, errorBuf, "No random number generate provider was specified.");
+      allIsWell = validateNotNull (params.getEncryptedInputStream(),          allIsWell, errorBuf, "No encrypted input stream was specified.");
+      allIsWell = validateNotNull (params.getInitializationVector(),          allIsWell, errorBuf, "No initialization vector was specified.");
+      allIsWell = validateNotNull (params.getEncryptedKey(),                  allIsWell, errorBuf, "No encrypted key was specified.");
       
-      InputStream cipherInputStream = getDecryptingInputStream(dataIn, cryptoOpts, cryptoInitParams);
-      return cipherInputStream;
+      if (params.getKeyEncryptionStrategyClass() != null && !params.getKeyEncryptionStrategyClass().equals("NullSecretKeyEncryptionStrategy")) {
+        allIsWell = validateNotEmpty(params.getOpaqueKeyEncryptionKeyID(), allIsWell, errorBuf, "No opqaue key encryption ID was specified.");
+      }
       
-    } else {
-      // Push these bytes back on to the stream. This method is a bit roundabout but isolates our code
-      // from having to understand the format that DataOuputStream uses for its bytes.
-      ByteArrayOutputStream tempByteOut = new ByteArrayOutputStream();
-      DataOutputStream tempOut = new DataOutputStream(tempByteOut);
-      tempOut.writeUTF(marker);
       
-      byte[] bytesToPutBack = tempByteOut.toByteArray();
+      if (!allIsWell) {
+        log.error("CryptoModulesParameters object is not valid.");
+        log.error(errorBuf.toString());
+        throw new RuntimeException("CryptoModulesParameters object is not valid.");
+      }
       
-      PushbackInputStream pushbackStream = new PushbackInputStream(in, bytesToPutBack.length);
-      pushbackStream.unread(bytesToPutBack);
+      return allIsWell;
       
-      return pushbackStream;
-    }
+    } 
     
+    return false;
   }
   
+  
   @Override
-  public OutputStream getEncryptingOutputStream(OutputStream out, Map<String,String> conf, Map<CryptoModule.CryptoInitProperty,Object> cryptoInitParams) {
+  public CryptoModuleParameters getEncryptingOutputStream(CryptoModuleParameters params) throws IOException {
+    
+    log.trace("Initializing crypto output stream (new style)");
+    
+    boolean allParamsOK = validateParamsObject(params, Cipher.ENCRYPT_MODE);
+    if (!allParamsOK) {
+      // This would be weird because the above call should throw an exception, but if they don't we'll check and throw.
+      
+      log.error("CryptoModuleParameters was not valid.");
+      throw new RuntimeException("Invalid CryptoModuleParameters");
+    }
+    
     
-    log.debug("Initializing crypto output stream");
+    // If they want a null output stream, just return their plaintext stream as the encrypted stream
+    if (params.getAlgorithmName().equals("NullCipher")) {
+      params.setEncryptedOutputStream(params.getPlaintextOutputStream());
+      return params;
+    }
+    
+    // Get the secret key
     
-    String cipherSuite = conf.get(Property.CRYPTO_CIPHER_SUITE.getKey());
+    SecureRandom secureRandom = DefaultCryptoModuleUtils.getSecureRandom(params.getRandomNumberGenerator(), params.getRandomNumberGeneratorProvider());
     
-    if (cipherSuite.equals("NullCipher")) {
-      return out;
+    if (params.getPlaintextKey() == null) {
+      byte[] randomKey = new byte[params.getKeyLength() / 8];
+      secureRandom.nextBytes(randomKey);
+      params.setPlaintextKey(randomKey);
     }
     
-    String algorithmName = conf.get(Property.CRYPTO_CIPHER_ALGORITHM_NAME.getKey());
-    String secureRNG = conf.get(Property.CRYPTO_SECURE_RNG.getKey());
-    String secureRNGProvider = conf.get(Property.CRYPTO_SECURE_RNG_PROVIDER.getKey());
-    int keyLength = Integer.parseInt(conf.get(Property.CRYPTO_CIPHER_KEY_LENGTH.getKey()));
-    String keyStrategyName = conf.get(Property.CRYPTO_SECRET_KEY_ENCRYPTION_STRATEGY_CLASS.getKey());
+    // Encrypt the secret key
+    
+    SecretKeyEncryptionStrategy keyEncryptionStrategy = CryptoModuleFactory.getSecretKeyEncryptionStrategy(params.getKeyEncryptionStrategyClass());
+    params = keyEncryptionStrategy.encryptSecretKey(params);
+    
+    // Now the encrypted version of the key and any opaque ID are within the params object.  Initialize the cipher.
     
-    log.debug(String.format(
-        "Using cipher suite \"%s\" (algorithm \"%s\") with key length %d with RNG \"%s\" and RNG provider \"%s\" and key encryption strategy %s", cipherSuite,
-        algorithmName, keyLength, secureRNG, secureRNGProvider, keyStrategyName));
+    // Check if the caller wants us to close the downstream stream when close() is called on the
+    // cipher object.  Calling close() on a CipherOutputStream is necessary for it to write out
+    // padding bytes.
+    if (!params.getCloseUnderylingStreamAfterCryptoStreamClose()) {
+      params.setPlaintextOutputStream(new DiscardCloseOutputStream(params.getPlaintextOutputStream()));
+    }
+
+    if (params.getCipher() == null) {
+      initializeCipher(params);
+    }
     
-    SecureRandom secureRandom = DefaultCryptoModuleUtils.getSecureRandom(secureRNG, secureRNGProvider);
-    Cipher cipher = DefaultCryptoModuleUtils.getCipher(cipherSuite);
-    byte[] randomKey = (byte[]) cryptoInitParams.get(CryptoInitProperty.PLAINTEXT_SESSION_KEY);
-    byte[] initVector = (byte[]) cryptoInitParams.get(CryptoInitProperty.INITIALIZATION_VECTOR);
+    CipherOutputStream cipherOutputStream = new CipherOutputStream(params.getPlaintextOutputStream(), params.getCipher());
+    BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(cipherOutputStream);    
     
-    // If they pass us an IV, use it...
-    if (initVector != null) {
+    params.setEncryptedOutputStream(bufferedOutputStream);
+    
+    if (params.getRecordParametersToStream()) {
+      DataOutputStream dataOut = new DataOutputStream(params.getPlaintextOutputStream());
       
-      try {
-        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(randomKey, algorithmName), new IvParameterSpec(initVector));
-      } catch (InvalidKeyException e) {
-        log.error("Accumulo encountered an unknown error in generating the secret key object (SecretKeySpec) for an encrypted stream");
-        throw new RuntimeException(e);
-      } catch (InvalidAlgorithmParameterException e) {
-        log.error("Accumulo encountered an unknown error in generating the secret key object (SecretKeySpec) for an encrypted stream");
-        throw new RuntimeException(e);
-      }
+      // Write a marker to indicate this is an encrypted log file (in case we read it a plain one and need to
+      // not try to decrypt it. Can happen during a failure when the log's encryption settings are changing.      
+      dataOut.writeUTF(ENCRYPTION_HEADER_MARKER);
       
-    } else {
-      // We didn't get an IV, so we'll let the cipher make one for us and then put its value back into the map so
-      // that the caller has access to it, to persist it.
-      try {
-        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(randomKey, algorithmName), secureRandom);
-      } catch (InvalidKeyException e) {
-        log.error("Accumulo encountered an unknown error in generating the secret key object (SecretKeySpec) for the write-ahead log");
-        throw new RuntimeException(e);
+      
+      // Write out all the parameters
+      dataOut.writeInt(params.getAllOptions().size());
+      for (String key : params.getAllOptions().keySet()) {
+        dataOut.writeUTF(key);
+        dataOut.writeUTF(params.getAllOptions().get(key));
       }
+
+      // Write out the cipher suite and algorithm used to encrypt this file. In case the admin changes, we want to still
+      // decode the old format.
+      dataOut.writeUTF(getCipherTransformation(params));
+      dataOut.writeUTF(params.getAlgorithmName());
+      
+      // Write the init vector to the log file
+      dataOut.writeInt(params.getInitializationVector().length);
+      dataOut.write(params.getInitializationVector());
       
-      // Since the IV length is determined by the algorithm, we let the cipher generate our IV for us,
-      // rather than calling secure random directly.
-      initVector = cipher.getIV();
-      cryptoInitParams.put(CryptoInitProperty.INITIALIZATION_VECTOR, initVector);
+      // Write out the encrypted session key and the opaque ID
+      dataOut.writeUTF(params.getOpaqueKeyEncryptionKeyID());
+      dataOut.writeInt(params.getEncryptedKey().length);
+      dataOut.write(params.getEncryptedKey());
     }
     
-    CipherOutputStream cipherOutputStream = new CipherOutputStream(out, cipher);
-    BufferedOutputStream bufferedCipherOutputStream = new BufferedOutputStream(cipherOutputStream);
-    
-    return bufferedCipherOutputStream;
+    return params;
   }
   
   @Override
-  public InputStream getDecryptingInputStream(InputStream in, Map<String,String> cryptoOpts, Map<CryptoModule.CryptoInitProperty,Object> cryptoInitParams)
-      throws IOException {
-    String cipherSuite = cryptoOpts.get(Property.CRYPTO_CIPHER_SUITE.getKey());
-    String algorithmName = cryptoOpts.get(Property.CRYPTO_CIPHER_ALGORITHM_NAME.getKey());
-    String cipherSuiteFromInitParams = (String) cryptoInitParams.get(CryptoInitProperty.CIPHER_SUITE);
-    String algorithmNameFromInitParams = (String) cryptoInitParams.get(CryptoInitProperty.ALGORITHM_NAME);
-    byte[] initVector = (byte[]) cryptoInitParams.get(CryptoInitProperty.INITIALIZATION_VECTOR);
-    byte[] secretKey = (byte[]) cryptoInitParams.get(CryptoInitProperty.PLAINTEXT_SESSION_KEY);
-    
-    if (initVector == null || secretKey == null || cipherSuiteFromInitParams == null || algorithmNameFromInitParams == null) {
-      log.error("Called getDecryptingInputStream() without proper crypto init params.  Need initVector, plaintext key, cipher suite and algorithm name");
-      throw new RuntimeException("Called getDecryptingInputStream() without initialization vector and/or plaintext session key");
+  public CryptoModuleParameters getDecryptingInputStream(CryptoModuleParameters params) throws IOException {
+    log.trace("About to initialize decryption stream (new style)");
+        
+    if (params.getRecordParametersToStream()) {
+      DataInputStream dataIn = new DataInputStream(params.getEncryptedInputStream());
+      log.trace("About to read encryption parameters from underlying stream");
+      
+      String marker = dataIn.readUTF();
+      if (marker.equals(ENCRYPTION_HEADER_MARKER)) {
+        
+        Map<String, String> paramsFromFile = new HashMap<String, String>();
+        
+        // Read in the bulk of parameters
+        int paramsCount = dataIn.readInt();
+        for (int i = 0; i < paramsCount; i++) {
+          String key = dataIn.readUTF();
+          String value = dataIn.readUTF();
+          
+          paramsFromFile.put(key, value);
+        }
+                
+        // Set the cipher parameters
+        String cipherSuiteFromFile = dataIn.readUTF();
+        String algorithmNameFromFile = dataIn.readUTF();
+        String[] cipherSuiteParts = parseCipherSuite(cipherSuiteFromFile);
+        params.setAlgorithmName(algorithmNameFromFile);
+        params.setEncryptionMode(cipherSuiteParts[1]);
+        params.setPadding(cipherSuiteParts[2]);
+        
+        
+        // Read the secret key and initialization vector from the file
+        int initVectorLength = dataIn.readInt();
+        byte[] initVector = new byte[initVectorLength];
+        dataIn.read(initVector, 0, initVectorLength);
+        
+        params.setInitializationVector(initVector);
+        
+        // Read the opaque ID and encrypted session key
+        String opaqueId = dataIn.readUTF();
+        params.setOpaqueKeyEncryptionKeyID(opaqueId);
+        
+        int encryptedSecretKeyLength = dataIn.readInt();
+        byte[] encryptedSecretKey = new byte[encryptedSecretKeyLength]; 
+        dataIn.read(encryptedSecretKey);
+        params.setEncryptedKey(encryptedSecretKey);
+        
+        
+        if (params.getOverrideStreamsSecretKeyEncryptionStrategy()) {
+          // Merge in options from file selectively
+          for (String name : paramsFromFile.keySet()) {
+            if (!name.equals(Property.CRYPTO_SECRET_KEY_ENCRYPTION_STRATEGY_CLASS.getKey())) {
+              params.getAllOptions().put(name, paramsFromFile.get(name));
+            }
+          }
+          params.setKeyEncryptionStrategyClass(params.getAllOptions().get(Property.CRYPTO_SECRET_KEY_ENCRYPTION_STRATEGY_CLASS.getKey()));
+        } else {
+          params = CryptoModuleFactory.fillParamsObjectFromStringMap(params, paramsFromFile);
+        }
+             
+        SecretKeyEncryptionStrategy keyEncryptionStrategy = CryptoModuleFactory.getSecretKeyEncryptionStrategy(params.getKeyEncryptionStrategyClass());
+        
+        params = keyEncryptionStrategy.decryptSecretKey(params);
+        
+      } else {
+        
+        log.trace("Read something off of the encrypted input stream that was not the encryption header marker, so pushing back bytes and returning the given stream");
+        // Push these bytes back on to the stream. This method is a bit roundabout but isolates our code
+        // from having to understand the format that DataOuputStream uses for its bytes.
+        ByteArrayOutputStream tempByteOut = new ByteArrayOutputStream();
+        DataOutputStream tempOut = new DataOutputStream(tempByteOut);
+        tempOut.writeUTF(marker);
+        
+        byte[] bytesToPutBack = tempByteOut.toByteArray();
+        
+        PushbackInputStream pushbackStream = new PushbackInputStream(params.getEncryptedInputStream(), bytesToPutBack.length);
+        pushbackStream.unread(bytesToPutBack);
+        
+        params.setPlaintextInputStream(pushbackStream);
+        
+        return params;
+      }      
     }
     
-    // Always use the init param's cipher suite, but check it against configured one and warn about discrepencies.
-    if (!cipherSuiteFromInitParams.equals(cipherSuite) || !algorithmNameFromInitParams.equals(algorithmName))
-      log.warn(String.format("Configured cipher suite and algorithm (\"%s\" and \"%s\") is different "
-          + "from cipher suite found in log file (\"%s\" and \"%s\")", cipherSuite, algorithmName, cipherSuiteFromInitParams, algorithmNameFromInitParams));
+    // We validate here after reading parameters from the stream, not at the top of the function.
+    boolean allParamsOK = validateParamsObject(params, Cipher.DECRYPT_MODE);
     
-    Cipher cipher = DefaultCryptoModuleUtils.getCipher(cipherSuiteFromInitParams);
+    if (!allParamsOK) {
+      log.error("CryptoModuleParameters object failed validation for decrypt");
+      throw new RuntimeException("CryptoModuleParameters object failed validation for decrypt");
+    }
+    
+    Cipher cipher = DefaultCryptoModuleUtils.getCipher(getCipherTransformation(params));
     
     try {
-      cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(secretKey, algorithmNameFromInitParams), new IvParameterSpec(initVector));
+      cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(params.getPlaintextKey(), params.getAlgorithmName()), new IvParameterSpec(params.getInitializationVector()));
     } catch (InvalidKeyException e) {
       log.error("Error when trying to initialize cipher with secret key");
       throw new RuntimeException(e);
     } catch (InvalidAlgorithmParameterException e) {
       log.error("Error when trying to initialize cipher with initialization vector");
       throw new RuntimeException(e);
-    }
+    }   
+    
     
-    BufferedInputStream bufferedDecryptingInputStream = new BufferedInputStream(new CipherInputStream(in, cipher));
+    BufferedInputStream bufferedDecryptingInputStream = new BufferedInputStream(new CipherInputStream(params.getEncryptedInputStream(), cipher));
+
+    log.trace("Initialized cipher input stream with transformation ["+getCipherTransformation(params)+"]");
     
-    return bufferedDecryptingInputStream;
+    params.setPlaintextInputStream(bufferedDecryptingInputStream);
+
+    return params;
+  }
+
+  @Override
+  public CryptoModuleParameters generateNewRandomSessionKey(CryptoModuleParameters params) {
+
+    if (params.getSecureRandom() == null) {
+      params.setSecureRandom(DefaultCryptoModuleUtils.getSecureRandom(params.getRandomNumberGenerator(), params.getRandomNumberGeneratorProvider()));
+    }
+    byte[] newSessionKey = new byte[params.getKeyLength() / 8];
+
+    params.getSecureRandom().nextBytes(newSessionKey);
+    params.setPlaintextKey(newSessionKey);
     
+    return params;
   }
+  
 }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/65b5a3a3/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModuleUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModuleUtils.java b/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModuleUtils.java
index 712d517..34ec1f3 100644
--- a/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModuleUtils.java
+++ b/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModuleUtils.java
@@ -68,5 +68,4 @@ public class DefaultCryptoModuleUtils {
     return cipher;
   }
   
-  
 }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/65b5a3a3/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultSecretKeyEncryptionStrategy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultSecretKeyEncryptionStrategy.java b/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultSecretKeyEncryptionStrategy.java
index 10690b5..f0ece50 100644
--- a/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultSecretKeyEncryptionStrategy.java
+++ b/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultSecretKeyEncryptionStrategy.java
@@ -17,21 +17,16 @@
 
 package org.apache.accumulo.core.security.crypto;
 
-import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
-import java.util.HashMap;
-import java.util.Map;
 
 import javax.crypto.Cipher;
-import javax.crypto.CipherOutputStream;
-import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.IllegalBlockSizeException;
 import javax.crypto.spec.SecretKeySpec;
 
 import org.apache.accumulo.core.conf.Property;
@@ -42,231 +37,78 @@ import org.apache.log4j.Logger;
 
 public class DefaultSecretKeyEncryptionStrategy implements SecretKeyEncryptionStrategy {
   
-  private static final Logger log = Logger.getLogger(DefaultSecretKeyEncryptionStrategy.class); 
-  
-  public static class DefaultSecretKeyEncryptionStrategyContext implements SecretKeyEncryptionStrategyContext {
-
-    private byte[] plaintextSecretKey;
-    private byte[] encryptedSecretKey;
-    private Map<String, String> context;
-    private String opaqueKeyId;
-    
-    @Override
-    public String getOpaqueKeyEncryptionKeyID() {
-      return opaqueKeyId;
-    }
-
-    @Override
-    public void setOpaqueKeyEncryptionKeyID(String id) {
-      this.opaqueKeyId = id;
-    }
-
-    @Override
-    public byte[] getPlaintextSecretKey() {
-      return plaintextSecretKey;
-    }
-
-    @Override
-    public void setPlaintextSecretKey(byte[] key) {
-      this.plaintextSecretKey = key;
-    }
-
-    @Override
-    public byte[] getEncryptedSecretKey() {
-      return encryptedSecretKey;
-    }
-
-    @Override
-    public void setEncryptedSecretKey(byte[] key) {
-      this.encryptedSecretKey = key;
-    }
-
-    @Override
-    public Map<String,String> getContext() {
-      return context;
-    }
-
-    @Override
-    public void setContext(Map<String,String> context) {
-      this.context = context;
-    }
-  }
-  
-  
-  @Override
-  public SecretKeyEncryptionStrategyContext encryptSecretKey(SecretKeyEncryptionStrategyContext context)  {
-    String hdfsURI = context.getContext().get(Property.CRYPTO_DEFAULT_KEY_STRATEGY_HDFS_URI.getKey());
-    String pathToKeyName = context.getContext().get(Property.CRYPTO_DEFAULT_KEY_STRATEGY_KEY_LOCATION.getKey());
-    Path pathToKey = new Path(pathToKeyName);
-    
-    FileSystem fs = getHadoopFileSystem(hdfsURI);
-    try {
-      
-      doKeyEncryptionOperation(Cipher.ENCRYPT_MODE, context, pathToKeyName, pathToKey, fs);
-      
-    } catch (IOException e) {
-      log.error(e);
-      throw new RuntimeException(e);
-    }
-  
-    return context;
-    
-  }
+  private static final Logger log = Logger.getLogger(DefaultSecretKeyEncryptionStrategy.class);
 
-  private void initializeKeyEncryptingKey(FileSystem fs, Path pathToKey, SecretKeyEncryptionStrategyContext context) throws IOException {
-    Map<String, String> cryptoContext = context.getContext(); 
-    DataOutputStream out = fs.create(pathToKey);
-    // Very important, lets hedge our bets
-    fs.setReplication(pathToKey, (short) 5);
-    
-    // Write number of context entries
-    out.writeInt(cryptoContext.size());
-    
-    for (String key : cryptoContext.keySet()) {
-      out.writeUTF(key);
-      out.writeUTF(cryptoContext.get(key));
-    }
-    
-    SecureRandom random = DefaultCryptoModuleUtils.getSecureRandom(cryptoContext.get(Property.CRYPTO_SECURE_RNG.getKey()), cryptoContext.get(Property.CRYPTO_SECURE_RNG_PROVIDER.getKey()));
-    int keyLength = Integer.parseInt(cryptoContext.get(Property.CRYPTO_CIPHER_KEY_LENGTH.getKey()));
-    byte[] newRandomKeyEncryptionKey = new byte[keyLength / 8];
-    
-    random.nextBytes(newRandomKeyEncryptionKey);
-    
-    Cipher cipher = DefaultCryptoModuleUtils.getCipher(cryptoContext.get(Property.CRYPTO_CIPHER_SUITE.getKey()));
-    try {
-      cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(newRandomKeyEncryptionKey, cryptoContext.get(Property.CRYPTO_CIPHER_ALGORITHM_NAME.getKey())), random);
-    } catch (InvalidKeyException e) {
-      log.error(e);
-      throw new RuntimeException(e);
-    }
-    
-    byte[] initVector = cipher.getIV();
-    
-    out.writeInt(initVector.length);
-    out.write(initVector);
-    
-    out.writeInt(newRandomKeyEncryptionKey.length);
-    out.write(newRandomKeyEncryptionKey);
-    
-    out.flush();
-    out.close();
-    
-  }
-
-  private FileSystem getHadoopFileSystem(String hdfsURI) {
-    FileSystem fs = null;
-    
-    if (hdfsURI != null && !hdfsURI.equals("")) {
-      try {
-        fs = FileSystem.get(CachedConfiguration.getInstance());
-      } catch (IOException e) {
-        log.error(e);
-        throw new RuntimeException(e);
-      }
-    }
-    else {
-      try {
-        fs = FileSystem.get(new URI(hdfsURI), CachedConfiguration.getInstance());
-      } catch (URISyntaxException e) {
-        log.error(e);
-        throw new RuntimeException(e);
-      } catch (IOException e) {
-        log.error(e);
-        throw new RuntimeException(e);
-      }
-      
-      
-    }
-    return fs;
-  }
-  
-  @Override
-  public SecretKeyEncryptionStrategyContext decryptSecretKey(SecretKeyEncryptionStrategyContext context) {
-    String hdfsURI = context.getContext().get(Property.CRYPTO_DEFAULT_KEY_STRATEGY_HDFS_URI.getKey());
-    String pathToKeyName = context.getContext().get(Property.CRYPTO_DEFAULT_KEY_STRATEGY_KEY_LOCATION.getKey());
-    Path pathToKey = new Path(pathToKeyName);
-    
-    FileSystem fs = getHadoopFileSystem(hdfsURI);
-    try {
-      doKeyEncryptionOperation(Cipher.DECRYPT_MODE, context, pathToKeyName, pathToKey, fs);
-      
-      
-    } catch (IOException e) {
-      log.error(e);
-      throw new RuntimeException(e);
-    }
-    
-    return context;
-  }
-
-  private void doKeyEncryptionOperation(int encryptionMode, SecretKeyEncryptionStrategyContext context, String pathToKeyName, Path pathToKey, FileSystem fs)
+  private void doKeyEncryptionOperation(int encryptionMode, CryptoModuleParameters params, String pathToKeyName, Path pathToKey, FileSystem fs)
       throws IOException {
     DataInputStream in = null;
     try {
       if (!fs.exists(pathToKey)) {
         
-        if (encryptionMode == Cipher.DECRYPT_MODE) {
+        if (encryptionMode == Cipher.UNWRAP_MODE) {
           log.error("There was a call to decrypt the session key but no key encryption key exists.  Either restore it, reconfigure the conf file to point to it in HDFS, or throw the affected data away and begin again.");
           throw new RuntimeException("Could not find key encryption key file in configured location in HDFS ("+pathToKeyName+")");
         } else {
-          initializeKeyEncryptingKey(fs, pathToKey, context);
+          DataOutputStream out = null;
+          try {
+            out = fs.create(pathToKey);
+            // Very important, lets hedge our bets
+            fs.setReplication(pathToKey, (short) 5);
+            SecureRandom random = DefaultCryptoModuleUtils.getSecureRandom(params.getRandomNumberGenerator(), params.getRandomNumberGeneratorProvider());
+            int keyLength = params.getKeyLength();
+            byte[] newRandomKeyEncryptionKey = new byte[keyLength / 8];
+            random.nextBytes(newRandomKeyEncryptionKey);
+            out.writeInt(newRandomKeyEncryptionKey.length);
+            out.write(newRandomKeyEncryptionKey);
+            out.flush();
+          } finally {
+            if (out != null) {
+              out.close();        
+            }
+          }
+
         }
       }
       in = fs.open(pathToKey);
-      
-      int numOfOpts = in.readInt();
-      Map<String, String> optsFromFile = new HashMap<String, String>();
-      
-      for (int i = 0; i < numOfOpts; i++) {
-        String key = in.readUTF();
-        String value = in.readUTF();
-        
-        optsFromFile.put(key, value);
-      }
-      
-      int ivLength = in.readInt();
-      byte[] iv = new byte[ivLength];
-      in.read(iv);
-      
-      
+            
       int keyEncryptionKeyLength = in.readInt();
       byte[] keyEncryptionKey = new byte[keyEncryptionKeyLength];
       in.read(keyEncryptionKey);
       
-      Cipher cipher = DefaultCryptoModuleUtils.getCipher(optsFromFile.get(Property.CRYPTO_CIPHER_SUITE.getKey()));
+      Cipher cipher = DefaultCryptoModuleUtils.getCipher(params.getAllOptions().get(Property.CRYPTO_DEFAULT_KEY_STRATEGY_CIPHER_SUITE.getKey()));
 
       try {
-        cipher.init(encryptionMode, new SecretKeySpec(keyEncryptionKey, optsFromFile.get(Property.CRYPTO_CIPHER_ALGORITHM_NAME.getKey())), new IvParameterSpec(iv));
+        cipher.init(encryptionMode, new SecretKeySpec(keyEncryptionKey, params.getAlgorithmName()));
       } catch (InvalidKeyException e) {
         log.error(e);
         throw new RuntimeException(e);
-      } catch (InvalidAlgorithmParameterException e) {
-        log.error(e);
-        throw new RuntimeException(e);
-      }
-
-      ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
-      CipherOutputStream cipherStream = new CipherOutputStream(byteArrayOutputStream, cipher);
-      
+      }      
       
-      if (Cipher.DECRYPT_MODE == encryptionMode) {
-        cipherStream.write(context.getEncryptedSecretKey());
-        cipherStream.flush();        
-        byte[] plaintextSecretKey = byteArrayOutputStream.toByteArray();
-
-        cipherStream.close();
-        
-        context.setPlaintextSecretKey(plaintextSecretKey);
+      if (Cipher.UNWRAP_MODE == encryptionMode) {
+        try {
+          Key plaintextKey = cipher.unwrap(params.getEncryptedKey(), params.getAlgorithmName(), Cipher.SECRET_KEY);
+          params.setPlaintextKey(plaintextKey.getEncoded());
+        } catch (InvalidKeyException e) {
+          log.error(e);
+          throw new RuntimeException(e);
+        } catch (NoSuchAlgorithmException e) {
+          log.error(e);
+          throw new RuntimeException(e);
+        }
       } else {
-        cipherStream.write(context.getPlaintextSecretKey());
-        cipherStream.flush();        
-        byte[] encryptedSecretKey = byteArrayOutputStream.toByteArray();
-
-        cipherStream.close();
+        Key plaintextKey = new SecretKeySpec(params.getPlaintextKey(), params.getAlgorithmName());
+        try {
+          byte[] encryptedSecretKey = cipher.wrap(plaintextKey);
+          params.setEncryptedKey(encryptedSecretKey);
+          params.setOpaqueKeyEncryptionKeyID(pathToKeyName);
+        } catch (InvalidKeyException e) {
+          log.error(e);
+          throw new RuntimeException(e);
+        } catch (IllegalBlockSizeException e) {
+          log.error(e);
+          throw new RuntimeException(e);
+        }
         
-        context.setEncryptedSecretKey(encryptedSecretKey);
-        context.setOpaqueKeyEncryptionKeyID(pathToKeyName);
       }
       
     } finally {
@@ -276,9 +118,71 @@ public class DefaultSecretKeyEncryptionStrategy implements SecretKeyEncryptionSt
     }
   }
 
+
+  private String getFullPathToKey(CryptoModuleParameters params) {
+    String pathToKeyName = params.getAllOptions().get(Property.CRYPTO_DEFAULT_KEY_STRATEGY_KEY_LOCATION.getKey());
+    String instanceDirectory = params.getAllOptions().get(Property.INSTANCE_DFS_DIR.getKey());
+    
+    
+    if (pathToKeyName == null) {
+      pathToKeyName = Property.CRYPTO_DEFAULT_KEY_STRATEGY_KEY_LOCATION.getDefaultValue();
+    }
+    
+    if (instanceDirectory == null) {
+      instanceDirectory = Property.INSTANCE_DFS_DIR.getDefaultValue();
+    }
+    
+    if (!pathToKeyName.startsWith("/")) {
+      pathToKeyName = "/" + pathToKeyName;
+    }
+    
+    String fullPath = instanceDirectory + pathToKeyName;
+    return fullPath;
+  }
+  
   @Override
-  public SecretKeyEncryptionStrategyContext getNewContext() {
-    return new DefaultSecretKeyEncryptionStrategyContext();
+  public CryptoModuleParameters encryptSecretKey(CryptoModuleParameters params) {
+    String hdfsURI = params.getAllOptions().get(Property.INSTANCE_DFS_URI.getKey());
+    if (hdfsURI == null) {
+      hdfsURI = Property.INSTANCE_DFS_URI.getDefaultValue();
+    }
+    
+    String fullPath = getFullPathToKey(params);
+    Path pathToKey = new Path(fullPath);
+    
+    try {
+      FileSystem fs = FileSystem.get(CachedConfiguration.getInstance());   
+      doKeyEncryptionOperation(Cipher.WRAP_MODE, params, fullPath, pathToKey, fs);
+      
+    } catch (IOException e) {
+      log.error(e);
+      throw new RuntimeException(e);
+    }
+    
+    return params;
+  }
+  
+  @Override
+  public CryptoModuleParameters decryptSecretKey(CryptoModuleParameters params) {
+    String hdfsURI = params.getAllOptions().get(Property.INSTANCE_DFS_URI.getKey());
+    if (hdfsURI == null) {
+      hdfsURI = Property.INSTANCE_DFS_URI.getDefaultValue(); 
+    }
+    
+    String pathToKeyName = getFullPathToKey(params);
+    Path pathToKey = new Path(pathToKeyName);
+    
+    try {
+      FileSystem fs = FileSystem.get(CachedConfiguration.getInstance());   
+      doKeyEncryptionOperation(Cipher.UNWRAP_MODE, params, pathToKeyName, pathToKey, fs);
+      
+      
+    } catch (IOException e) {
+      log.error(e);
+      throw new RuntimeException(e);
+    }
+        
+    return params;
   }
   
 }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/65b5a3a3/core/src/main/java/org/apache/accumulo/core/security/crypto/DiscardCloseOutputStream.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/crypto/DiscardCloseOutputStream.java b/core/src/main/java/org/apache/accumulo/core/security/crypto/DiscardCloseOutputStream.java
new file mode 100644
index 0000000..846cf35
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/security/crypto/DiscardCloseOutputStream.java
@@ -0,0 +1,39 @@
+/*
+ * 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.accumulo.core.security.crypto;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.log4j.Logger;
+
+public class DiscardCloseOutputStream extends FilterOutputStream {
+
+  private static final Logger log = Logger.getLogger(DiscardCloseOutputStream.class);
+  
+  public DiscardCloseOutputStream(OutputStream out) {
+    super(out);
+  }
+  
+  public void close() throws IOException {
+    // Discard
+    log.trace("Discarded close");
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/65b5a3a3/core/src/main/java/org/apache/accumulo/core/security/crypto/SecretKeyEncryptionStrategy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/security/crypto/SecretKeyEncryptionStrategy.java b/core/src/main/java/org/apache/accumulo/core/security/crypto/SecretKeyEncryptionStrategy.java
index aa3f76d..637ed4b 100644
--- a/core/src/main/java/org/apache/accumulo/core/security/crypto/SecretKeyEncryptionStrategy.java
+++ b/core/src/main/java/org/apache/accumulo/core/security/crypto/SecretKeyEncryptionStrategy.java
@@ -19,11 +19,10 @@ package org.apache.accumulo.core.security.crypto;
 /**
  * 
  */
-public interface SecretKeyEncryptionStrategy {
+public interface SecretKeyEncryptionStrategy {  
   
-  public SecretKeyEncryptionStrategyContext encryptSecretKey(SecretKeyEncryptionStrategyContext context);
-  public SecretKeyEncryptionStrategyContext decryptSecretKey(SecretKeyEncryptionStrategyContext context);
-  public SecretKeyEncryptionStrategyContext getNewContext();
+  public CryptoModuleParameters encryptSecretKey(CryptoModuleParameters params);
+  public CryptoModuleParameters decryptSecretKey(CryptoModuleParameters params);
   
   
 }


Mime
View raw message