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 2016/03/16 02:23:38 UTC
knox git commit: KNOX-631 - Config Driven Keystore for Signing and
Validation Certs in KnoxSSO
Repository: knox
Updated Branches:
refs/heads/master 7edeac5d8 -> 51194fbbe
KNOX-631 - Config Driven Keystore for Signing and Validation Certs in KnoxSSO
Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/51194fbb
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/51194fbb
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/51194fbb
Branch: refs/heads/master
Commit: 51194fbbe5662b16bd644d64faa450e43f771c80
Parents: 7edeac5
Author: Larry McCay <lm...@hortonworks.com>
Authored: Tue Mar 15 21:23:22 2016 -0400
Committer: Larry McCay <lm...@hortonworks.com>
Committed: Tue Mar 15 21:23:22 2016 -0400
----------------------------------------------------------------------
.../gateway/config/impl/GatewayConfigImpl.java | 9 +++
.../security/impl/DefaultKeystoreService.java | 72 +++++++++++++++++++-
.../impl/DefaultTokenAuthorityService.java | 47 +++++++++++--
.../hadoop/gateway/config/GatewayConfig.java | 6 ++
.../services/ServiceLifecycleException.java | 1 -
.../services/security/KeystoreService.java | 6 +-
.../security/KeystoreServiceException.java | 3 +
.../hadoop/gateway/GatewayTestConfig.java | 16 +++++
.../hadoop/gateway/GatewayTestConfig.java | 16 +++++
9 files changed, 166 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/knox/blob/51194fbb/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
index 4c0d769..711efc8 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/config/impl/GatewayConfigImpl.java
@@ -563,4 +563,13 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
return d;
}
+ @Override
+ public String getSigningKeystoreName() {
+ return get(SIGNING_KEYSTORE_NAME);
+ }
+
+ @Override
+ public String getSigningKeyAlias() {
+ return get(SIGNING_KEY_ALIAS);
+ }
}
http://git-wip-us.apache.org/repos/asf/knox/blob/51194fbb/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultKeystoreService.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultKeystoreService.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultKeystoreService.java
index 4500230..e70da53 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultKeystoreService.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/security/impl/DefaultKeystoreService.java
@@ -55,6 +55,9 @@ public class DefaultKeystoreService extends BaseKeystoreService implements Keyst
private static GatewayMessages LOG = MessagesFactory.get( GatewayMessages.class );
private static GatewayResources RES = ResourcesFactory.get( GatewayResources.class );
+ private String signingKeystoreName = null;
+ private String signingKeyAlias = null;
+
@Override
public void init(GatewayConfig config, Map<String, String> options)
throws ServiceLifecycleException {
@@ -65,6 +68,32 @@ public class DefaultKeystoreService extends BaseKeystoreService implements Keyst
throw new ServiceLifecycleException( RES.failedToCreateKeyStoreDirectory( ksd.getAbsolutePath() ) );
}
}
+
+ signingKeystoreName = config.getSigningKeystoreName();
+ // ensure that the keystore actually exists and fail to start if not
+ if (signingKeystoreName != null) {
+ File sks = new File(this.keyStoreDir, signingKeystoreName);
+ if (!sks.exists()) {
+ throw new ServiceLifecycleException("Configured signing keystore does not exist.");
+ }
+ signingKeyAlias = config.getSigningKeyAlias();
+ if (signingKeyAlias != null) {
+ // ensure that the signing key alias exists in the configured keystore
+ KeyStore ks;
+ try {
+ ks = getSigningKeystore();
+ if (ks != null) {
+ if (!ks.containsAlias(signingKeyAlias)) {
+ throw new ServiceLifecycleException("Configured signing key alias does not exist.");
+ }
+ }
+ } catch (KeystoreServiceException e) {
+ throw new ServiceLifecycleException("Unable to get the configured signing keystore.", e);
+ } catch (KeyStoreException e) {
+ throw new ServiceLifecycleException("Signing keystore has not been loaded.", e);
+ }
+ }
+ }
}
@Override
@@ -86,7 +115,24 @@ public class DefaultKeystoreService extends BaseKeystoreService implements Keyst
final File keyStoreFile = new File( keyStoreDir + GATEWAY_KEYSTORE );
return getKeystore(keyStoreFile, "JKS");
}
-
+
+ @Override
+ public KeyStore getSigningKeystore() throws KeystoreServiceException {
+ File keyStoreFile = null;
+
+ if (signingKeystoreName == null) {
+ keyStoreFile = new File(keyStoreDir + GATEWAY_KEYSTORE);
+ }
+ else {
+ keyStoreFile = new File(keyStoreDir + signingKeystoreName);
+ // make sure the keystore exists
+ if (!keyStoreFile.exists()) {
+ throw new KeystoreServiceException("Configured signing keystore does not exist.");
+ }
+ }
+ return getKeystore(keyStoreFile, "JKS");
+ }
+
@Override
public void addSelfSignedCertForGateway(String alias, char[] passphrase) throws KeystoreServiceException {
addSelfSignedCertForGateway(alias, passphrase, null);
@@ -196,7 +242,29 @@ public class DefaultKeystoreService extends BaseKeystoreService implements Keyst
}
return key;
}
-
+
+ @Override
+ public Key getSigningKey(String alias, char[] passphrase) throws KeystoreServiceException {
+ Key key = null;
+ KeyStore ks = getSigningKeystore();
+ if (passphrase == null) {
+ passphrase = masterService.getMasterSecret();
+ LOG.assumingKeyPassphraseIsMaster();
+ }
+ if (ks != null) {
+ try {
+ key = ks.getKey(alias, passphrase);
+ } catch (UnrecoverableKeyException e) {
+ LOG.failedToGetKeyForGateway( alias, e );
+ } catch (KeyStoreException e) {
+ LOG.failedToGetKeyForGateway( alias, e );
+ } catch (NoSuchAlgorithmException e) {
+ LOG.failedToGetKeyForGateway( alias, e );
+ }
+ }
+ return key;
+ }
+
public KeyStore getCredentialStoreForCluster(String clusterName)
throws KeystoreServiceException {
final File keyStoreFile = new File( keyStoreDir + clusterName + CREDENTIALS_SUFFIX );
http://git-wip-us.apache.org/repos/asf/knox/blob/51194fbb/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java
----------------------------------------------------------------------
diff --git a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java
index 3fbc789..bd54956 100644
--- a/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java
+++ b/gateway-server/src/main/java/org/apache/hadoop/gateway/services/token/impl/DefaultTokenAuthorityService.java
@@ -45,9 +45,11 @@ import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.RSASSAVerifier;
public class DefaultTokenAuthorityService implements JWTokenAuthority, Service {
-
+
+ private static String SIGNING_KEY_PASSPHRASE = "signing.key.passphrase";
private AliasService as = null;
private KeystoreService ks = null;
+ String signingKeyAlias = null;
public void setKeystoreService(KeystoreService ks) {
this.ks = ks;
@@ -108,7 +110,6 @@ public class DefaultTokenAuthorityService implements JWTokenAuthority, Service {
claimArray[0] = "KNOXSSO";
claimArray[1] = p.getName();
claimArray[2] = null;
- // TODO: make the validity period configurable
if (expires == -1) {
claimArray[3] = Long.toString( ( System.currentTimeMillis() ) + 30000);
}
@@ -122,12 +123,12 @@ public class DefaultTokenAuthorityService implements JWTokenAuthority, Service {
RSAPrivateKey key;
char[] passphrase = null;
try {
- passphrase = as.getGatewayIdentityPassphrase();
+ passphrase = getSigningKeyPassphrase();
} catch (AliasServiceException e) {
throw new TokenServiceException(e);
}
try {
- key = (RSAPrivateKey) ks.getKeyForGateway("gateway-identity",
+ key = (RSAPrivateKey) ks.getSigningKey(getSigningKeyAlias(),
passphrase);
JWSSigner signer = new RSASSASigner(key);
token.sign(signer);
@@ -138,17 +139,32 @@ public class DefaultTokenAuthorityService implements JWTokenAuthority, Service {
else {
throw new TokenServiceException("Cannot issue token - Unsupported algorithm");
}
-
+
return token;
}
+ private char[] getSigningKeyPassphrase() throws AliasServiceException {
+ char[] phrase = as.getPasswordFromAliasForGateway(SIGNING_KEY_PASSPHRASE);
+ if (phrase == null) {
+ phrase = as.getGatewayIdentityPassphrase();
+ }
+ return phrase;
+ }
+
+ private String getSigningKeyAlias() {
+ if (signingKeyAlias == null) {
+ return "gateway-identity";
+ }
+ return signingKeyAlias;
+ }
+
@Override
public boolean verifyToken(JWTToken token)
throws TokenServiceException {
boolean rc = false;
PublicKey key;
try {
- key = ks.getKeystoreForGateway().getCertificate("gateway-identity").getPublicKey();
+ key = ks.getSigningKeystore().getCertificate(getSigningKeyAlias()).getPublicKey();
JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) key);
// TODO: interrogate the token for issuer claim in order to determine the public key to use for verification
// consider jwk for specifying the key too
@@ -167,6 +183,25 @@ public class DefaultTokenAuthorityService implements JWTokenAuthority, Service {
if (as == null || ks == null) {
throw new ServiceLifecycleException("Alias or Keystore service is not set");
}
+ signingKeyAlias = config.getSigningKeyAlias();
+
+ @SuppressWarnings("unused")
+ RSAPrivateKey key;
+ char[] passphrase = null;
+ try {
+ passphrase = as.getPasswordFromAliasForGateway(SIGNING_KEY_PASSPHRASE);
+ if (passphrase != null) {
+ key = (RSAPrivateKey) ks.getSigningKey(getSigningKeyAlias(),
+ passphrase);
+ if (key == null) {
+ throw new ServiceLifecycleException("Provisioned passphrase cannot be used to acquire signing key.");
+ }
+ }
+ } catch (AliasServiceException e) {
+ throw new ServiceLifecycleException("Provisioned signing key passphrase cannot be acquired.", e);
+ } catch (KeystoreServiceException e) {
+ throw new ServiceLifecycleException("Provisioned signing key passphrase cannot be acquired.", e);
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/knox/blob/51194fbb/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
index 91bd64c..5558578 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/config/GatewayConfig.java
@@ -38,6 +38,8 @@ public interface GatewayConfig {
public static final String KRB5_DEBUG = "sun.security.krb5.debug";
public static final String KRB5_LOGIN_CONFIG = "java.security.auth.login.config";
public static final String KRB5_USE_SUBJECT_CREDS_ONLY = "javax.security.auth.useSubjectCredsOnly";
+ public static final String SIGNING_KEYSTORE_NAME = "gateway.signing.keystore.name";
+ public static final String SIGNING_KEY_ALIAS = "gateway.signing.key.alias";
/**
* The location of the gateway configuration.
@@ -133,4 +135,8 @@ public interface GatewayConfig {
long getGatewayDeploymentsBackupAgeLimit();
+ String getSigningKeystoreName();
+
+ String getSigningKeyAlias();
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/51194fbb/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/ServiceLifecycleException.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/ServiceLifecycleException.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/ServiceLifecycleException.java
index 11dd81f..a7f2a3c 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/ServiceLifecycleException.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/ServiceLifecycleException.java
@@ -27,5 +27,4 @@ public class ServiceLifecycleException extends Exception {
public ServiceLifecycleException(String message, Exception e) {
super(message, e);
}
-
}
http://git-wip-us.apache.org/repos/asf/knox/blob/51194fbb/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreService.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreService.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreService.java
index 6ed8990..f85dd35 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreService.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreService.java
@@ -29,9 +29,13 @@ public interface KeystoreService {
void addSelfSignedCertForGateway(String alias, char[] passphrase, String hostname) throws KeystoreServiceException;
public KeyStore getKeystoreForGateway() throws KeystoreServiceException;
-
+
+ public KeyStore getSigningKeystore() throws KeystoreServiceException;
+
public Key getKeyForGateway(String alias, char[] passphrase) throws KeystoreServiceException;
+ public Key getSigningKey(String alias, char[] passphrase) throws KeystoreServiceException;
+
public void createCredentialStoreForCluster(String clusterName) throws KeystoreServiceException;
public boolean isCredentialStoreForClusterAvailable(String clusterName) throws KeystoreServiceException;
http://git-wip-us.apache.org/repos/asf/knox/blob/51194fbb/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreServiceException.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreServiceException.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreServiceException.java
index 52fd26a..ef8d704 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreServiceException.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/services/security/KeystoreServiceException.java
@@ -24,4 +24,7 @@ public class KeystoreServiceException extends Exception {
super(e);
}
+ public KeystoreServiceException(String message) {
+ super(message);
+ }
}
http://git-wip-us.apache.org/repos/asf/knox/blob/51194fbb/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
----------------------------------------------------------------------
diff --git a/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java b/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
index 03ce5dc..e5be4be 100644
--- a/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
+++ b/gateway-test-release/webhdfs-kerb-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
@@ -319,4 +319,20 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
return Long.MAX_VALUE;
}
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.config.GatewayConfig#getSigningKeystoreName()
+ */
+ @Override
+ public String getSigningKeystoreName() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.config.GatewayConfig#getSigningKeyAlias()
+ */
+ @Override
+ public String getSigningKeyAlias() {
+ return null;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/knox/blob/51194fbb/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
index 1d97a54..cd71e7f 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
@@ -371,4 +371,20 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
backupAgeLimit = newBackupAgeLimit;
}
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.config.GatewayConfig#getSigningKeystoreName()
+ */
+ @Override
+ public String getSigningKeystoreName() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.hadoop.gateway.config.GatewayConfig#getSigningKeyAlias()
+ */
+ @Override
+ public String getSigningKeyAlias() {
+ return null;
+ }
+
}