You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pl...@apache.org on 2015/11/04 09:26:02 UTC
[36/48] directory-kerby git commit: Add support for decrypting JWT
tokens in the KDC
Add support for decrypting JWT tokens in the KDC
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/b58fb7f6
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/b58fb7f6
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/b58fb7f6
Branch: refs/heads/pkinit-support
Commit: b58fb7f69935f404e78f195892a193c8e89760e3
Parents: c3ada0c
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Thu Oct 22 11:26:57 2015 +0100
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Thu Oct 22 11:26:57 2015 +0100
----------------------------------------------------------------------
.../kerberos/kdc/WithAccessTokenKdcTest.java | 23 +++++-
.../kerberos/kdc/WithIdentityTokenKdcTest.java | 23 +++++-
.../kerberos/kdc/WithTokenKdcTestBase.java | 12 ++-
.../kerby/kerberos/kerb/server/KdcConfig.java | 4 +
.../kerberos/kerb/server/KdcConfigKey.java | 1 +
.../kerb/server/preauth/token/TokenPreauth.java | 87 +++++++++++++-------
6 files changed, 112 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b58fb7f6/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithAccessTokenKdcTest.java
----------------------------------------------------------------------
diff --git a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithAccessTokenKdcTest.java b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithAccessTokenKdcTest.java
index 544923d..0664529 100644
--- a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithAccessTokenKdcTest.java
+++ b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithAccessTokenKdcTest.java
@@ -23,9 +23,11 @@ import java.io.InputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
+import java.security.PublicKey;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.common.PrivateKeyReader;
+import org.apache.kerby.kerberos.kerb.common.PublicKeyReader;
import org.apache.kerby.kerberos.kerb.server.TestKdcServer;
import org.apache.kerby.kerberos.kerb.spec.ticket.ServiceTicket;
import org.junit.Assert;
@@ -43,7 +45,7 @@ public class WithAccessTokenKdcTest extends WithTokenKdcTestBase {
public void testBadIssuer() throws Exception {
InputStream is = WithTokenKdcTestBase.class.getResourceAsStream("/private_key.pem");
PrivateKey privateKey = PrivateKeyReader.loadPrivateKey(is);
- prepareToken(getServerPrincipal(), "oauth1.com", AUDIENCE, privateKey);
+ prepareToken(getServerPrincipal(), "oauth1.com", AUDIENCE, privateKey, null);
try {
performTest();
@@ -59,7 +61,7 @@ public class WithAccessTokenKdcTest extends WithTokenKdcTestBase {
InputStream is = WithTokenKdcTestBase.class.getResourceAsStream("/private_key.pem");
PrivateKey privateKey = PrivateKeyReader.loadPrivateKey(is);
prepareToken("bad-service" + "/" + getHostname() + "@" + TestKdcServer.KDC_REALM,
- ISSUER, AUDIENCE, privateKey);
+ ISSUER, AUDIENCE, privateKey, null);
try {
performTest();
@@ -74,7 +76,7 @@ public class WithAccessTokenKdcTest extends WithTokenKdcTestBase {
@Test
@org.junit.Ignore
public void testUnsignedToken() throws Exception {
- prepareToken(getServerPrincipal(), ISSUER, AUDIENCE, null);
+ prepareToken(getServerPrincipal(), ISSUER, AUDIENCE, null, null);
try {
performTest();
@@ -89,7 +91,7 @@ public class WithAccessTokenKdcTest extends WithTokenKdcTestBase {
public void testSignedTokenWithABadKey() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyGen.generateKeyPair();
- prepareToken(getServerPrincipal(), ISSUER, AUDIENCE, keyPair.getPrivate());
+ prepareToken(getServerPrincipal(), ISSUER, AUDIENCE, keyPair.getPrivate(), null);
try {
performTest();
@@ -100,6 +102,19 @@ public class WithAccessTokenKdcTest extends WithTokenKdcTestBase {
}
}
+ @Test
+ public void testSignedEncryptedToken() throws Exception {
+ InputStream is = WithTokenKdcTestBase.class.getResourceAsStream("/private_key.pem");
+ PrivateKey privateKey = PrivateKeyReader.loadPrivateKey(is);
+
+ is = WithTokenKdcTestBase.class.getResourceAsStream("/oauth2.com_public_key.pem");
+ PublicKey publicKey = PublicKeyReader.loadPublicKey(is);
+
+ prepareToken(getServerPrincipal(), ISSUER, AUDIENCE, privateKey, publicKey);
+
+ performTest();
+ }
+
private void performTest() throws Exception {
createCredentialCache(getClientPrincipal(), getClientPassword());
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b58fb7f6/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithIdentityTokenKdcTest.java
----------------------------------------------------------------------
diff --git a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithIdentityTokenKdcTest.java b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithIdentityTokenKdcTest.java
index 71f9da7..eb89df6 100644
--- a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithIdentityTokenKdcTest.java
+++ b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithIdentityTokenKdcTest.java
@@ -21,6 +21,7 @@ package org.apache.kerby.kerberos.kdc;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.common.PrivateKeyReader;
+import org.apache.kerby.kerberos.kerb.common.PublicKeyReader;
import org.apache.kerby.kerberos.kerb.spec.ticket.ServiceTicket;
import org.apache.kerby.kerberos.kerb.spec.ticket.TgtTicket;
import org.junit.Assert;
@@ -30,6 +31,7 @@ import java.io.InputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
+import java.security.PublicKey;
public class WithIdentityTokenKdcTest extends WithTokenKdcTestBase {
@@ -44,7 +46,7 @@ public class WithIdentityTokenKdcTest extends WithTokenKdcTestBase {
public void testBadIssuer() throws Exception {
InputStream is = WithTokenKdcTestBase.class.getResourceAsStream("/private_key.pem");
PrivateKey privateKey = PrivateKeyReader.loadPrivateKey(is);
- prepareToken(null, "oauth1.com", AUDIENCE, privateKey);
+ prepareToken(null, "oauth1.com", AUDIENCE, privateKey, null);
try {
performTest();
@@ -61,7 +63,7 @@ public class WithIdentityTokenKdcTest extends WithTokenKdcTestBase {
public void testBadAudienceRestriction() throws Exception {
InputStream is = WithTokenKdcTestBase.class.getResourceAsStream("/private_key.pem");
PrivateKey privateKey = PrivateKeyReader.loadPrivateKey(is);
- prepareToken(null, ISSUER, "krbtgt2@EXAMPLE.COM", privateKey);
+ prepareToken(null, ISSUER, "krbtgt2@EXAMPLE.COM", privateKey, null);
try {
performTest();
@@ -76,7 +78,7 @@ public class WithIdentityTokenKdcTest extends WithTokenKdcTestBase {
@Test
@org.junit.Ignore
public void testUnsignedToken() throws Exception {
- prepareToken(null, ISSUER, "krbtgt2@EXAMPLE.COM", null);
+ prepareToken(null, ISSUER, "krbtgt2@EXAMPLE.COM", null, null);
try {
performTest();
@@ -91,7 +93,7 @@ public class WithIdentityTokenKdcTest extends WithTokenKdcTestBase {
public void testSignedTokenWithABadKey() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyGen.generateKeyPair();
- prepareToken(null, ISSUER, AUDIENCE, keyPair.getPrivate());
+ prepareToken(null, ISSUER, AUDIENCE, keyPair.getPrivate(), null);
try {
performTest();
@@ -102,6 +104,19 @@ public class WithIdentityTokenKdcTest extends WithTokenKdcTestBase {
}
}
+ @Test
+ public void testSignedEncryptedToken() throws Exception {
+ InputStream is = WithTokenKdcTestBase.class.getResourceAsStream("/private_key.pem");
+ PrivateKey privateKey = PrivateKeyReader.loadPrivateKey(is);
+
+ is = WithTokenKdcTestBase.class.getResourceAsStream("/oauth2.com_public_key.pem");
+ PublicKey publicKey = PublicKeyReader.loadPublicKey(is);
+
+ prepareToken(null, ISSUER, AUDIENCE, privateKey, publicKey);
+
+ performTest();
+ }
+
private void performTest() throws Exception {
createCredentialCache(getClientPrincipal(), getClientPassword());
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b58fb7f6/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTestBase.java
----------------------------------------------------------------------
diff --git a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTestBase.java b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTestBase.java
index 8db50f9..0b94be5 100644
--- a/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTestBase.java
+++ b/kerby-kdc-test/src/test/java/org/apache/kerby/kerberos/kdc/WithTokenKdcTestBase.java
@@ -39,7 +39,9 @@ import org.junit.Before;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.security.PrivateKey;
+import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -66,6 +68,9 @@ public class WithTokenKdcTestBase extends KdcTestBase {
super.configKdcSeverAndClient();
String verifyKeyPath = this.getClass().getResource("/").getPath();
getKdcServer().getKdcConfig().setString(KdcConfigKey.VERIFY_KEY, verifyKeyPath);
+
+ URL privateKeyPath = WithTokenKdcTestBase.class.getResource("/private_key.pem");
+ getKdcServer().getKdcConfig().setString(KdcConfigKey.DECRYPTION_KEY, privateKeyPath.getPath());
getKdcServer().getKdcConfig().setString(KdcConfigKey.ISSUERS, ISSUER);
}
@@ -86,11 +91,11 @@ public class WithTokenKdcTestBase extends KdcTestBase {
e.printStackTrace();
}
- return prepareToken(servicePrincipal, ISSUER, AUDIENCE, privateKey);
+ return prepareToken(servicePrincipal, ISSUER, AUDIENCE, privateKey, null);
}
protected AuthToken prepareToken(String servicePrincipal, String issuer, String audience,
- PrivateKey signingKey) {
+ PrivateKey signingKey, PublicKey encryptionKey) {
AuthToken authToken = KrbRuntime.getTokenProvider().createTokenFactory().createToken();
authToken.setIssuer(issuer);
authToken.setSubject(SUBJECT);
@@ -121,6 +126,9 @@ public class WithTokenKdcTestBase extends KdcTestBase {
if (tokenEncoder instanceof JwtTokenEncoder && signingKey != null) {
((JwtTokenEncoder) tokenEncoder).setSignKey(signingKey);
}
+ if (tokenEncoder instanceof JwtTokenEncoder && encryptionKey != null) {
+ ((JwtTokenEncoder) tokenEncoder).setEncryptionKey(encryptionKey);
+ }
krbToken = new KrbToken();
krbToken.setInnerToken(authToken);
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b58fb7f6/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java
index dc2fc78..82b8dfd 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfig.java
@@ -167,6 +167,10 @@ public class KdcConfig extends Conf {
return KrbConfHelper.getStringUnderSection(this, KdcConfigKey.VERIFY_KEY);
}
+ public String getDecryptionKeyConfig() {
+ return KrbConfHelper.getStringUnderSection(this, KdcConfigKey.DECRYPTION_KEY);
+ }
+
public List<String> getIssuers() {
return Arrays.asList(KrbConfHelper.getStringArrayUnderSection(this, KdcConfigKey.ISSUERS));
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b58fb7f6/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java
index 771c781..178d19d 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/KdcConfigKey.java
@@ -50,6 +50,7 @@ public enum KdcConfigKey implements SectionConfigKey {
RESTRICT_ANONYMOUS_TO_TGT(false, "kdcdefaults"),
KDC_MAX_DGRAM_REPLY_SIZE(4096, "kdcdefaults"),
VERIFY_KEY(null, "kdcdefaults"),
+ DECRYPTION_KEY(null, "kdcdefaults"),
ISSUERS(null, "kdcdefaults");
private Object defaultValue;
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/b58fb7f6/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/token/TokenPreauth.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/token/TokenPreauth.java b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/token/TokenPreauth.java
index 2de66b5..f3c8741 100644
--- a/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/token/TokenPreauth.java
+++ b/kerby-kerb/kerb-server/src/main/java/org/apache/kerby/kerberos/kerb/server/preauth/token/TokenPreauth.java
@@ -23,6 +23,7 @@ import org.apache.kerby.kerberos.kerb.KrbCodec;
import org.apache.kerby.kerberos.kerb.KrbException;
import org.apache.kerby.kerberos.kerb.KrbRuntime;
import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerby.kerberos.kerb.common.PrivateKeyReader;
import org.apache.kerby.kerberos.kerb.common.PublicKeyReader;
import org.apache.kerby.kerberos.kerb.preauth.PluginRequestContext;
import org.apache.kerby.kerberos.kerb.preauth.token.TokenPreauthMeta;
@@ -47,6 +48,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.List;
@@ -78,25 +80,11 @@ public class TokenPreauth extends AbstractPreauthPlugin {
if (!(issuers.contains(issuer))) {
throw new KrbException("Unconfigured issuer: " + issuer);
}
+
+ // Configure keys
TokenDecoder tokenDecoder = KrbRuntime.getTokenProvider().createTokenDecoder();
- if (tokenDecoder instanceof JwtTokenDecoder) {
- String verifyKeyPath = kdcRequest.getKdcContext().getConfig().getVerifyKeyConfig();
- if (verifyKeyPath != null) {
- File verifyKeyFile = getVerifyKeyFile(verifyKeyPath, issuer);
- if (verifyKeyFile != null) {
- PublicKey verifyKey = null;
- try {
- FileInputStream fis = new FileInputStream(verifyKeyFile);
- verifyKey = PublicKeyReader.loadPublicKey(fis);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- ((JwtTokenDecoder) tokenDecoder).setVerifyKey(verifyKey);
- }
- }
- }
+ configureKeys(tokenDecoder, kdcRequest, issuer);
+
AuthToken authToken = null;
try {
authToken = tokenDecoder.decodeFromBytes(token.getTokenValue());
@@ -127,18 +115,61 @@ public class TokenPreauth extends AbstractPreauthPlugin {
return false;
}
}
+
+ private void configureKeys(TokenDecoder tokenDecoder, KdcRequest kdcRequest, String issuer) {
+ if (tokenDecoder instanceof JwtTokenDecoder) {
+ String verifyKeyPath = kdcRequest.getKdcContext().getConfig().getVerifyKeyConfig();
+ if (verifyKeyPath != null) {
+ File verifyKeyFile = getKeyFile(verifyKeyPath, issuer);
+ if (verifyKeyFile != null) {
+ PublicKey verifyKey = null;
+ try {
+ FileInputStream fis = new FileInputStream(verifyKeyFile);
+ verifyKey = PublicKeyReader.loadPublicKey(fis);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ ((JwtTokenDecoder) tokenDecoder).setVerifyKey(verifyKey);
+ }
+ }
+ String decryptionKeyPath = kdcRequest.getKdcContext().getConfig().getDecryptionKeyConfig();
+ if (decryptionKeyPath != null) {
+ File decryptionKeyFile = getKeyFile(decryptionKeyPath, issuer);
+ if (decryptionKeyFile != null) {
+ PrivateKey decryptionKey = null;
+ try {
+ FileInputStream fis = new FileInputStream(decryptionKeyFile);
+ decryptionKey = PrivateKeyReader.loadPrivateKey(fis);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ ((JwtTokenDecoder) tokenDecoder).setDecryptionKey(decryptionKey);
+ }
+ }
+ }
+ }
- private File getVerifyKeyFile(String path, String issuer) {
- File folder = new File(path);
- File[] listOfFiles = folder.listFiles();
- File verifyKeyFile = null;
-
- for (int i = 0; i < listOfFiles.length; i++) {
- if (listOfFiles[i].isFile() && listOfFiles[i].getName().contains(issuer)) {
- verifyKeyFile = listOfFiles[i];
- break;
+ private File getKeyFile(String path, String issuer) {
+ File file = new File(path);
+ if (file.isDirectory()) {
+ File[] listOfFiles = file.listFiles();
+ File verifyKeyFile = null;
+
+ for (int i = 0; i < listOfFiles.length; i++) {
+ if (listOfFiles[i].isFile() && listOfFiles[i].getName().contains(issuer)) {
+ verifyKeyFile = listOfFiles[i];
+ break;
+ }
}
+ return verifyKeyFile;
+ } else if (file.isFile()) {
+ return file;
}
- return verifyKeyFile;
+
+ return null;
}
}