You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by lm...@apache.org on 2013/09/16 21:11:10 UTC

git commit: KNOX-48 added the use of the CryptoService to encrypt and decrypt secure URL query strings.

Updated Branches:
  refs/heads/master ae535b2ed -> 1c2727cc2


KNOX-48 added the use of the CryptoService to encrypt and decrypt secure URL query strings.

Project: http://git-wip-us.apache.org/repos/asf/incubator-knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-knox/commit/1c2727cc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-knox/tree/1c2727cc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-knox/diff/1c2727cc

Branch: refs/heads/master
Commit: 1c2727cc27d851f9d97813cb056f85e3a6fb9526
Parents: ae535b2
Author: Larry McCay <lm...@hortonworks.com>
Authored: Mon Sep 16 15:08:53 2013 -0400
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Mon Sep 16 15:08:53 2013 -0400

----------------------------------------------------------------------
 .../pom.xml                                     |   6 +
 .../SecureQueryDecryptProcessor.java            |  22 +++-
 .../SecureQueryDeploymentContributor.java       |  11 +-
 .../SecureQueryEncryptProcessor.java            |  19 ++--
 .../SecureQueryDeploymentContributorTest.java   |  23 ++++
 .../SecureQueryEncryptDecryptProcessorTest.java | 111 +++++++++++++++++++
 .../apache/hadoop/gateway/GatewayMessages.java  |   3 +
 .../security/impl/DefaultCryptoService.java     |   5 +-
 .../services/security/EncryptionResult.java     |  42 +++++++
 9 files changed, 224 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/1c2727cc/gateway-provider-rewrite-step-secure-query/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-secure-query/pom.xml b/gateway-provider-rewrite-step-secure-query/pom.xml
index 8ac5cd3..77c7c3e 100644
--- a/gateway-provider-rewrite-step-secure-query/pom.xml
+++ b/gateway-provider-rewrite-step-secure-query/pom.xml
@@ -78,6 +78,12 @@
         </dependency>
 
         <dependency>
+            <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-server</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
             <groupId>org.hamcrest</groupId>
             <artifactId>hamcrest-core</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/1c2727cc/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDecryptProcessor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDecryptProcessor.java b/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDecryptProcessor.java
index 031e0fb..89ecd28 100644
--- a/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDecryptProcessor.java
+++ b/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDecryptProcessor.java
@@ -22,6 +22,9 @@ import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment;
 import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteContext;
 import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepProcessor;
 import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepStatus;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.security.CryptoService;
+import org.apache.hadoop.gateway.services.security.EncryptionResult;
 import org.apache.hadoop.gateway.util.urltemplate.Builder;
 import org.apache.hadoop.gateway.util.urltemplate.Query;
 import org.apache.hadoop.gateway.util.urltemplate.Template;
@@ -36,6 +39,7 @@ public class SecureQueryDecryptProcessor implements UrlRewriteStepProcessor<Secu
   private static final String ENCRYPTED_PARAMETER_NAME = "_";
 
   private String clusterName;
+  private CryptoService cryptoService;
 
   @Override
   public String getType() {
@@ -48,6 +52,8 @@ public class SecureQueryDecryptProcessor implements UrlRewriteStepProcessor<Secu
     if( values != null && values.size() > 0 ) {
       this.clusterName = environment.resolve( "cluster.name" ).get( 0 );
     }
+    GatewayServices services = environment.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+    cryptoService = (CryptoService) services.getService(GatewayServices.CRYPTO_SERVICE);
   }
 
   @Override
@@ -87,8 +93,18 @@ public class SecureQueryDecryptProcessor implements UrlRewriteStepProcessor<Secu
   public void destroy() {
   }
 
-  private static String decode( String string ) throws UnsupportedEncodingException {
-    return new String( Base64.decodeBase64( string ), "UTF-8" );
+  private String decode( String string ) throws UnsupportedEncodingException {
+    byte[] bytes = Base64.decodeBase64( string );
+    EncryptionResult result = EncryptionResult.fromByteArray(bytes);
+    byte[] clear = cryptoService.decryptForCluster(clusterName, 
+        "encryptQueryString", 
+        result.cipher, 
+        result.iv, 
+        result.salt);
+    if (clear != null) {
+      System.out.println(new String(clear));
+      return new String(clear);
+    }
+    return null;
   }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/1c2727cc/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributor.java b/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributor.java
index 2598eb2..b30a7b7 100644
--- a/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributor.java
+++ b/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributor.java
@@ -22,6 +22,7 @@ import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor;
 import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributorBase;
 import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor;
 import org.apache.hadoop.gateway.descriptor.ResourceDescriptor;
+import org.apache.hadoop.gateway.services.security.AliasService;
 import org.apache.hadoop.gateway.topology.Provider;
 import org.apache.hadoop.gateway.topology.Service;
 
@@ -33,6 +34,7 @@ public class SecureQueryDeploymentContributor
 
   public static final String PROVIDER_ROLE_NAME = "secure-query";
   public static final String PROVIDER_IMPL_NAME = "default";
+  private AliasService as;
 
   @Override
   public String getRole() {
@@ -43,11 +45,16 @@ public class SecureQueryDeploymentContributor
   public String getName() {
     return PROVIDER_IMPL_NAME;
   }
+  
+  public void setAliasService(AliasService as) {
+    this.as = as;
+  }
 
   @Override
   public void contributeProvider( DeploymentContext context, Provider provider ) {
     if( provider.isEnabled() ) {
-      //TODO: Do something with the keystore service.
+      String clusterName = context.getTopology().getName();
+      this.as.generateAliasForCluster(clusterName, "encryptQueryString");
 //      UrlRewriteRulesDescriptor rules = context.getDescriptor( REWRITE_ROLE_NAME );
 //      if( rules != null ) {
 //        HostmapFunctionDescriptor func = rules.addFunction( HostmapFunctionDescriptor.FUNCTION_NAME );
@@ -84,8 +91,6 @@ public class SecureQueryDeploymentContributor
       Service service,
       ResourceDescriptor resource,
       List<FilterParamDescriptor> params ) {
-    //TODO: Might need to add a filter as a way to propigate a keystore service to the processor.
-    // NoOp.
   }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/1c2727cc/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryEncryptProcessor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryEncryptProcessor.java b/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryEncryptProcessor.java
index df75a1b..e1ca48b 100644
--- a/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryEncryptProcessor.java
+++ b/gateway-provider-rewrite-step-secure-query/src/main/java/org/apache/hadoop/gateway/securequery/SecureQueryEncryptProcessor.java
@@ -22,6 +22,9 @@ import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment;
 import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteContext;
 import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepProcessor;
 import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepStatus;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.security.CryptoService;
+import org.apache.hadoop.gateway.services.security.EncryptionResult;
 import org.apache.hadoop.gateway.util.urltemplate.Parser;
 import org.apache.hadoop.gateway.util.urltemplate.Template;
 
@@ -34,6 +37,7 @@ public class SecureQueryEncryptProcessor
   private static final String ENCRYPTED_PARAMETER_NAME = "_";
 
   private String clusterName;
+  private CryptoService cryptoService = null;
 
   @Override
   public String getType() {
@@ -46,6 +50,8 @@ public class SecureQueryEncryptProcessor
     if( values != null && values.size() > 0 ) {
       this.clusterName = environment.resolve( "cluster.name" ).get( 0 );
     }
+    GatewayServices services = environment.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+    cryptoService = (CryptoService) services.getService(GatewayServices.CRYPTO_SERVICE);
   }
 
   @Override
@@ -75,17 +81,8 @@ public class SecureQueryEncryptProcessor
   }
 
   private String encode( String string ) throws UnsupportedEncodingException {
-    string = Base64.encodeBase64String( string.getBytes( "UTF-8" ) );
-    string = removeTrailingEquals( string );
+    EncryptionResult result = cryptoService.encryptForCluster(clusterName, "encryptQueryString", string.getBytes("UTF-8"));
+    string = Base64.encodeBase64String(result.toByteAray());
     return string;
   }
-
-  private static String removeTrailingEquals( String s ) {
-    int i = s.length()-1;
-    while( i > 0 && s.charAt( i ) == '=' ) {
-      i--;
-    }
-    return s.substring( 0, i+1 );
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/1c2727cc/gateway-provider-rewrite-step-secure-query/src/test/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-secure-query/src/test/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributorTest.java b/gateway-provider-rewrite-step-secure-query/src/test/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributorTest.java
index c337d7e..04946d6 100644
--- a/gateway-provider-rewrite-step-secure-query/src/test/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributorTest.java
+++ b/gateway-provider-rewrite-step-secure-query/src/test/java/org/apache/hadoop/gateway/securequery/SecureQueryDeploymentContributorTest.java
@@ -17,8 +17,16 @@
  */
 package org.apache.hadoop.gateway.securequery;
 
+import org.apache.hadoop.gateway.config.GatewayConfig;
 import org.apache.hadoop.gateway.deploy.DeploymentContext;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.ServiceLifecycleException;
+import org.apache.hadoop.gateway.services.security.AliasService;
+import org.apache.hadoop.gateway.services.security.CryptoService;
+import org.apache.hadoop.gateway.services.security.impl.DefaultCryptoService;
 import org.apache.hadoop.gateway.topology.Provider;
+import org.apache.hadoop.gateway.topology.Topology;
 import org.easymock.EasyMock;
 import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -46,12 +54,27 @@ public class SecureQueryDeploymentContributorTest {
     provider.setName( "secure-query" );
     provider.setParams(  providerParams );
 
+    Topology topology = new Topology();
+    topology.setName("Sample");
+    
     DeploymentContext context = EasyMock.createNiceMock( DeploymentContext.class );
 //    EasyMock.expect( context.getDescriptor( "rewrite" ) ).andReturn( rewriteRules ).anyTimes();
     EasyMock.expect( context.getWebArchive() ).andReturn( webArchive ).anyTimes();
+    EasyMock.expect( context.getTopology() ).andReturn( topology ).anyTimes();
     EasyMock.replay( context );
 
+    AliasService as = EasyMock.createNiceMock( AliasService.class );
+    CryptoService cryptoService = new DefaultCryptoService();
+    ((DefaultCryptoService)cryptoService).setAliasService(as);
+
+    GatewayServices gatewayServices = EasyMock.createNiceMock( GatewayServices.class );
+    EasyMock.expect( gatewayServices.getService( GatewayServices.CRYPTO_SERVICE ) ).andReturn( cryptoService ).anyTimes();
+
+    UrlRewriteEnvironment encEnvironment = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+    EasyMock.expect( encEnvironment.getAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE ) ).andReturn( gatewayServices ).anyTimes();    
+    
     SecureQueryDeploymentContributor contributor = new SecureQueryDeploymentContributor();
+    contributor.setAliasService(as);
 
     assertThat( contributor.getRole(), is( "secure-query" ) );
     assertThat( contributor.getName(), is( "default" ) );

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/1c2727cc/gateway-provider-rewrite-step-secure-query/src/test/java/org/apache/hadoop/gateway/securequery/SecureQueryEncryptDecryptProcessorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-secure-query/src/test/java/org/apache/hadoop/gateway/securequery/SecureQueryEncryptDecryptProcessorTest.java b/gateway-provider-rewrite-step-secure-query/src/test/java/org/apache/hadoop/gateway/securequery/SecureQueryEncryptDecryptProcessorTest.java
new file mode 100644
index 0000000..758c6fb
--- /dev/null
+++ b/gateway-provider-rewrite-step-secure-query/src/test/java/org/apache/hadoop/gateway/securequery/SecureQueryEncryptDecryptProcessorTest.java
@@ -0,0 +1,111 @@
+/**
+ * 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.securequery;
+
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteContext;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.security.AliasService;
+import org.apache.hadoop.gateway.services.security.CryptoService;
+import org.apache.hadoop.gateway.services.security.impl.DefaultCryptoService;
+import org.apache.hadoop.gateway.util.urltemplate.Params;
+import org.apache.hadoop.gateway.util.urltemplate.Parser;
+import org.apache.hadoop.gateway.util.urltemplate.Query;
+import org.apache.hadoop.gateway.util.urltemplate.Template;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import java.util.Arrays;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.nullValue;
+
+public class SecureQueryEncryptDecryptProcessorTest {
+
+  @Test
+  public void testEncryptDecrypt() throws Exception {
+    Query query;
+    Template origTemplate = Parser.parse( "http://host:0/path/file?query-param-name=query-param-value" );
+
+    // Test encryption.  Results are left in encTemplate
+
+    AliasService as = EasyMock.createNiceMock( AliasService.class );
+    String secret = "sdkjfhsdkjfhsdfs";
+    EasyMock.expect( as.getPasswordFromAliasForCluster("test-cluster-name", "encryptQueryString")).andReturn( secret.toCharArray() ).anyTimes();
+    CryptoService cryptoService = new DefaultCryptoService();
+    ((DefaultCryptoService)cryptoService).setAliasService(as);
+    GatewayServices gatewayServices = EasyMock.createNiceMock( GatewayServices.class );
+    EasyMock.expect( gatewayServices.getService( GatewayServices.CRYPTO_SERVICE ) ).andReturn( cryptoService );
+
+    UrlRewriteEnvironment encEnvironment = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+    EasyMock.expect( encEnvironment.getAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE ) ).andReturn( gatewayServices ).anyTimes();    
+    EasyMock.expect( encEnvironment.resolve( "cluster.name" ) ).andReturn( Arrays.asList( "test-cluster-name" ) ).anyTimes();
+    UrlRewriteContext encContext = EasyMock.createNiceMock( UrlRewriteContext.class );
+    EasyMock.expect( encContext.getCurrentUrl() ).andReturn( origTemplate );
+    Capture<Template> encTemplate = new Capture<Template>();
+    encContext.setCurrentUrl( EasyMock.capture( encTemplate ) );
+    EasyMock.replay( gatewayServices, as, encEnvironment, encContext );
+
+    SecureQueryEncryptDescriptor descriptor = new SecureQueryEncryptDescriptor();
+    SecureQueryEncryptProcessor processor = new SecureQueryEncryptProcessor();
+    processor.initialize( encEnvironment, descriptor );
+    processor.process( encContext );
+
+    assertThat( encTemplate, notNullValue() );
+    query = encTemplate.getValue().getQuery().get( "_" );
+    assertThat( query.getFirstValue().getPattern().length(), greaterThan( 1 ) );
+    query = encTemplate.getValue().getQuery().get( "query-param-name" );
+    assertThat( query, nullValue() );
+
+    // Test decryption.  Results are left in decTemplate.
+
+    gatewayServices = EasyMock.createNiceMock( GatewayServices.class );
+    EasyMock.expect( gatewayServices.getService( GatewayServices.CRYPTO_SERVICE ) ).andReturn( cryptoService );
+    as = EasyMock.createNiceMock( AliasService.class );
+    EasyMock.expect( as.getPasswordFromAliasForCluster("test-cluster-name", "encryptQueryString")).andReturn( secret.toCharArray() ).anyTimes();
+
+    UrlRewriteEnvironment decEnvironment = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+    EasyMock.expect( decEnvironment.getAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE ) ).andReturn( gatewayServices ).anyTimes();    
+    EasyMock.expect( decEnvironment.resolve( "cluster.name" ) ).andReturn( Arrays.asList( "test-cluster-name" ) ).anyTimes();
+    Params decParams = EasyMock.createNiceMock( Params.class );
+    EasyMock.expect( decParams.resolve( "cluster.name" ) ).andReturn( Arrays.asList("test-cluster-name") ).anyTimes();
+    UrlRewriteContext decContext = EasyMock.createNiceMock( UrlRewriteContext.class );
+    EasyMock.expect( decContext.getCurrentUrl() ).andReturn( encTemplate.getValue() );
+    EasyMock.expect( decContext.getParameters() ).andReturn( decParams );
+    Capture<Template> decTemplate = new Capture<Template>();
+    decContext.setCurrentUrl( EasyMock.capture( decTemplate ) );
+    EasyMock.replay( gatewayServices, as, decEnvironment, decParams, decContext );
+
+    SecureQueryDecryptDescriptor descriptor1 = new SecureQueryDecryptDescriptor();
+    SecureQueryDecryptProcessor decProcessor = new SecureQueryDecryptProcessor();
+    decProcessor.initialize( decEnvironment, descriptor1 );
+    decProcessor.process( decContext );
+
+    assertThat( decTemplate, notNullValue() );
+    assertThat( decTemplate.getValue(), notNullValue() );
+    query = decTemplate.getValue().getQuery().get( "query-param-name" );
+    assertThat( query.getFirstValue().getPattern(), is( "query-param-value" ) );
+    query = decTemplate.getValue().getQuery().get( "_" );
+    assertThat( query, nullValue() );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/1c2727cc/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
index ff102a9..8718464 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/GatewayMessages.java
@@ -269,4 +269,7 @@ public interface GatewayMessages {
 
   @Message( level = MessageLevel.DEBUG, text = "Status Code Returned from Request Dispatch: {0}" )
   void dispatchResponseStatusCode(int statusCode);
+
+  @Message( level = MessageLevel.ERROR, text = "Failed to decrypt cipher text for cluster {0}: due to inability to retrieve the password" )
+  void failedToDecryptCipherForClusterNullPassword(String clusterName);
 }

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/1c2727cc/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultCryptoService.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultCryptoService.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultCryptoService.java
index f8323bc..1235e1d 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultCryptoService.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultCryptoService.java
@@ -109,7 +109,7 @@ public class DefaultCryptoService implements CryptoService {
   @Override
   public byte[] decryptForCluster(String clusterName, String alias, byte[] cipherText, byte[] iv, byte[] salt) {
   char[] password = as.getPasswordFromAliasForCluster(clusterName, alias);
-  if (password != null) {
+    if (password != null) {
       AESEncryptor aes = new AESEncryptor(new String(password));
       try {
         return aes.decrypt(salt, iv, cipherText);
@@ -117,6 +117,9 @@ public class DefaultCryptoService implements CryptoService {
         LOG.failedToDecryptPasswordForCluster( clusterName, e );
       }
     }
+    else {
+      LOG.failedToDecryptCipherForClusterNullPassword( clusterName );
+    }
     return null;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-knox/blob/1c2727cc/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/EncryptionResult.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/EncryptionResult.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/EncryptionResult.java
index 4d3a7c3..7d95e7d 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/EncryptionResult.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/EncryptionResult.java
@@ -17,13 +17,55 @@
  */
 package org.apache.hadoop.gateway.services.security;
 
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+
 public class EncryptionResult {
   public byte[] salt;
   public byte[] iv;
   public byte[] cipher;
+  
+  public EncryptionResult() {
+    
+  }
+  
   public EncryptionResult(byte[] salt, byte[] iv, byte[] cipher) {
     this.salt = salt;
     this.iv = iv;
     this.cipher = cipher;
   }
+  
+  public byte[] toByteAray() {
+    int headerLength = 12;
+    ByteBuffer bb = ByteBuffer.allocate(salt.length + iv.length + cipher.length + headerLength);
+    bb.putInt(salt.length)
+      .putInt(iv.length)
+      .putInt(cipher.length)
+      .put(salt)
+      .put(iv)
+      .put(cipher);
+    bb.flip();
+    
+    return bb.array();
+  }
+  
+  public static EncryptionResult fromByteArray(byte[] array) {
+    EncryptionResult result = new EncryptionResult();
+    
+    ByteBuffer bb = ByteBuffer.wrap(array);
+    
+    int saltSize = bb.getInt();
+    int ivSize = bb.getInt();
+    int cipherSize = bb.getInt();
+
+    result.salt = new byte[saltSize];
+    result.iv = new byte[ivSize];
+    result.cipher = new byte[cipherSize];
+    
+    bb.get(result.salt);
+    bb.get(result.iv);
+    bb.get(result.cipher);
+    
+    return result;
+  }
 }