You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2014/12/02 23:40:06 UTC
cxf git commit: Prototyping support for JWKs with the certificate info
Repository: cxf
Updated Branches:
refs/heads/master 1baae6959 -> a9555675b
Prototyping support for JWKs with the certificate info
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/a9555675
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/a9555675
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/a9555675
Branch: refs/heads/master
Commit: a9555675b829acdfb1672bc2157d6f3c08fdd652
Parents: 1baae69
Author: Sergey Beryozkin <sb...@talend.com>
Authored: Tue Dec 2 22:39:47 2014 +0000
Committer: Sergey Beryozkin <sb...@talend.com>
Committed: Tue Dec 2 22:39:47 2014 +0000
----------------------------------------------------------------------
.../cxf/common/util/crypto/CryptoUtils.java | 18 ++++++
.../cxf/rs/security/jose/JoseHeaders.java | 8 +--
.../security/jose/jaxrs/KeyManagementUtils.java | 31 ++++++++++
.../cxf/rs/security/jose/jwe/JweUtils.java | 4 +-
.../cxf/rs/security/jose/jwk/JsonWebKey.java | 6 +-
.../cxf/rs/security/jose/jwk/JwkUtils.java | 62 ++++++++++++++------
.../cxf/rs/security/jose/jws/JwsUtils.java | 4 +-
.../rs/security/jose/jwk/JsonWebKeyTest.java | 10 +++-
.../cxf/rs/security/jose/jwk/jwkPublicSet.txt | 12 +++-
.../jaxrs/security/jwt/JAXRSJweJwsTest.java | 39 ++++++++++++
.../cxf/systest/jaxrs/security/jwt/server.xml | 21 +++++++
.../jaxrs/security/certs/jwkPublicSet.txt | 17 ++++++
.../jaxrs/security/public.jwk.properties | 23 ++++++++
13 files changed, 224 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/core/src/main/java/org/apache/cxf/common/util/crypto/CryptoUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/cxf/common/util/crypto/CryptoUtils.java b/core/src/main/java/org/apache/cxf/common/util/crypto/CryptoUtils.java
index 184f69f..b3017cb 100644
--- a/core/src/main/java/org/apache/cxf/common/util/crypto/CryptoUtils.java
+++ b/core/src/main/java/org/apache/cxf/common/util/crypto/CryptoUtils.java
@@ -19,6 +19,7 @@
package org.apache.cxf.common.util.crypto;
+import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.Key;
@@ -31,6 +32,7 @@ import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPrivateKey;
@@ -53,6 +55,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.common.util.CompressionUtils;
import org.apache.cxf.helpers.IOUtils;
@@ -628,6 +631,21 @@ public final class CryptoUtils {
throw new SecurityException(ex);
}
}
+ public static String encodeCertificate(Certificate cert) {
+ try {
+ return Base64Utility.encode(cert.getEncoded());
+ } catch (Exception ex) {
+ throw new SecurityException(ex);
+ }
+ }
+ public static Certificate decodeCertificate(String encodedCert) {
+ try {
+ byte[] decoded = Base64Utility.decode(encodedCert);
+ return CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(decoded));
+ } catch (Exception ex) {
+ throw new SecurityException(ex);
+ }
+ }
public static PublicKey loadPublicKey(InputStream storeLocation, char[] storePassword, String alias,
String storeType) {
return loadCertificate(storeLocation, storePassword, alias, storeType).getPublicKey();
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java
index 60ce970..ac186d2 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java
@@ -78,12 +78,12 @@ public class JoseHeaders extends JsonMapObject {
return (String)getHeader(JoseConstants.HEADER_X509_URL);
}
- public void setX509Chain(String x509Chain) {
- setHeader(JoseConstants.HEADER_X509_CHAIN, x509Chain);
+ public void setX509Chain(List<String> x509Chain) {
+ setProperty(JoseConstants.HEADER_X509_CHAIN, x509Chain);
}
- public String getX509Chain() {
- return (String)getHeader(JoseConstants.HEADER_X509_CHAIN);
+ public List<String> getX509Chain() {
+ return CastUtils.cast((List<?>)getProperty(JoseConstants.HEADER_X509_CHAIN));
}
public void setX509Thumbprint(String x509Thumbprint) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java
index 88fcb3a..cc69b84 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/KeyManagementUtils.java
@@ -24,6 +24,9 @@ import java.security.KeyStore;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
import org.apache.cxf.Bus;
@@ -143,4 +146,32 @@ public final class KeyManagementUtils {
throw new SecurityException(ex);
}
}
+
+ public static List<String> encodeX509CertificateChain(List<X509Certificate> chain) {
+ List<String> encodedChain = new ArrayList<String>(chain.size());
+ for (X509Certificate cert : chain) {
+ try {
+ encodedChain.add(CryptoUtils.encodeCertificate(cert));
+ } catch (Exception ex) {
+ throw new SecurityException(ex);
+ }
+ }
+ return encodedChain;
+ }
+ public static List<X509Certificate> toX509CertificateChain(List<String> base64EncodedChain) {
+ if (base64EncodedChain != null) {
+ List<X509Certificate> certs = new ArrayList<X509Certificate>(base64EncodedChain.size());
+ for (String encodedCert : base64EncodedChain) {
+ try {
+ certs.add((X509Certificate)CryptoUtils.decodeCertificate(encodedCert));
+ } catch (Exception ex) {
+ throw new SecurityException(ex);
+ }
+ }
+ //TODO: validate the chain
+ return certs;
+ } else {
+ return null;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
index 7f9a8aa..06859f3 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
@@ -112,7 +112,7 @@ public final class JweUtils {
String keyEncryptionAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm : jwk.getAlgorithm();
KeyEncryptionAlgorithm keyEncryptionProvider = null;
if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) {
- keyEncryptionProvider = getRSAKeyEncryptionAlgorithm(JwkUtils.toRSAPublicKey(jwk),
+ keyEncryptionProvider = getRSAKeyEncryptionAlgorithm(JwkUtils.toRSAPublicKey(jwk, true),
keyEncryptionAlgo);
} else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType())) {
keyEncryptionProvider = getSecretKeyEncryptionAlgorithm(JwkUtils.toSecretKey(jwk),
@@ -287,7 +287,7 @@ public final class JweUtils {
SecretKey ctDecryptionKey = null;
String keyEncryptionAlgo = getKeyEncryptionAlgo(props, null);
if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
- JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_ENCRYPT);
+ JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_DECRYPT);
keyEncryptionAlgo = getKeyEncryptionAlgo(props, jwk.getAlgorithm());
if ("direct".equals(keyEncryptionAlgo)) {
contentEncryptionAlgo = getContentEncryptionAlgo(props, contentEncryptionAlgo);
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKey.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKey.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKey.java
index 025b248..8566dea 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKey.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKey.java
@@ -124,12 +124,12 @@ public class JsonWebKey extends JsonMapObject {
return (String)getProperty(X509_URL);
}
- public void setX509Chain(String x509Chain) {
+ public void setX509Chain(List<String> x509Chain) {
setProperty(X509_CHAIN, x509Chain);
}
- public String getX509Chain() {
- return (String)getProperty(X509_CHAIN);
+ public List<String> getX509Chain() {
+ return CastUtils.cast((List<?>)getProperty(X509_CHAIN));
}
public void setX509Thumbprint(String x509Thumbprint) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JwkUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JwkUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JwkUtils.java
index 6d0a2fe..817bdcd 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JwkUtils.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwk/JwkUtils.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.URI;
+import java.security.cert.X509Certificate;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPrivateKey;
@@ -40,6 +41,7 @@ import org.apache.cxf.common.util.crypto.CryptoUtils;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.utils.ResourceUtils;
import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.rs.security.jose.JoseConstants;
import org.apache.cxf.rs.security.jose.JoseUtils;
import org.apache.cxf.rs.security.jose.jaxrs.KeyManagementUtils;
@@ -256,7 +258,7 @@ public final class JwkUtils {
public static JsonWebKey loadJsonWebKey(Message m, Properties props, String keyOper, JwkReaderWriter reader) {
PrivateKeyPasswordProvider cb = loadPasswordProvider(m, props, keyOper);
JsonWebKeys jwkSet = loadJwkSet(m, props, cb, reader);
- String kid = getKeyId(props, KeyManagementUtils.RSSEC_KEY_STORE_ALIAS, keyOper);
+ String kid = getKeyId(m, props, KeyManagementUtils.RSSEC_KEY_STORE_ALIAS, keyOper);
if (kid != null) {
return jwkSet.getKey(kid);
} else if (keyOper != null) {
@@ -275,11 +277,11 @@ public final class JwkUtils {
JwkReaderWriter reader) {
PrivateKeyPasswordProvider cb = loadPasswordProvider(m, props, keyOper);
JsonWebKeys jwkSet = loadJwkSet(m, props, cb, reader);
- String kid = getKeyId(props, KeyManagementUtils.RSSEC_KEY_STORE_ALIAS, keyOper);
+ String kid = getKeyId(m, props, KeyManagementUtils.RSSEC_KEY_STORE_ALIAS, keyOper);
if (kid != null) {
return Collections.singletonList(jwkSet.getKey(kid));
}
- String kids = getKeyId(props, KeyManagementUtils.RSSEC_KEY_STORE_ALIASES, keyOper);
+ String kids = getKeyId(m, props, KeyManagementUtils.RSSEC_KEY_STORE_ALIASES, keyOper);
if (kids != null) {
String[] values = kids.split(",");
List<JsonWebKey> keys = new ArrayList<JsonWebKey>(values.length);
@@ -297,9 +299,22 @@ public final class JwkUtils {
return null;
}
public static RSAPublicKey toRSAPublicKey(JsonWebKey jwk) {
+ return toRSAPublicKey(jwk, false);
+ }
+ public static RSAPublicKey toRSAPublicKey(JsonWebKey jwk, boolean checkX509) {
String encodedModulus = (String)jwk.getProperty(JsonWebKey.RSA_MODULUS);
String encodedPublicExponent = (String)jwk.getProperty(JsonWebKey.RSA_PUBLIC_EXP);
- return CryptoUtils.getRSAPublicKey(encodedModulus, encodedPublicExponent);
+ if (encodedModulus != null) {
+ return CryptoUtils.getRSAPublicKey(encodedModulus, encodedPublicExponent);
+ } else if (checkX509) {
+ List<X509Certificate> chain = toX509CertificateChain(jwk);
+ return (RSAPublicKey)chain.get(0).getPublicKey();
+ }
+ return null;
+ }
+ public static List<X509Certificate> toX509CertificateChain(JsonWebKey jwk) {
+ List<String> base64EncodedChain = jwk.getX509Chain();
+ return KeyManagementUtils.toX509CertificateChain(base64EncodedChain);
}
public static JsonWebKey fromRSAPublicKey(RSAPublicKey pk, String algo) {
JsonWebKey jwk = prepareRSAJwk(pk.getModulus(), algo);
@@ -307,6 +322,14 @@ public final class JwkUtils {
jwk.setProperty(JsonWebKey.RSA_PUBLIC_EXP, encodedPublicExponent);
return jwk;
}
+ public static JsonWebKey fromX509CertificateChain(List<X509Certificate> chain, String algo) {
+ JsonWebKey jwk = new JsonWebKey();
+ jwk.setAlgorithm(algo);
+ List<String> encodedChain = KeyManagementUtils.encodeX509CertificateChain(chain);
+ jwk.setX509Chain(encodedChain);
+ return jwk;
+ }
+
public static RSAPrivateKey toRSAPrivateKey(JsonWebKey jwk) {
String encodedModulus = (String)jwk.getProperty(JsonWebKey.RSA_MODULUS);
String encodedPrivateExponent = (String)jwk.getProperty(JsonWebKey.RSA_PRIVATE_EXP);
@@ -363,19 +386,24 @@ public final class JwkUtils {
return jwk;
}
- private static String getKeyId(Properties props, String propertyName, String keyOper) {
- String kid = props.getProperty(propertyName);
- if (kid == null && keyOper != null) {
- String keyIdProp = null;
- if (keyOper.equals(JsonWebKey.KEY_OPER_ENCRYPT)) {
- keyIdProp = propertyName + ".jwe";
- } else if (keyOper.equals(JsonWebKey.KEY_OPER_SIGN)
- || keyOper.equals(JsonWebKey.KEY_OPER_VERIFY)) {
- keyIdProp = propertyName + ".jws";
- }
- if (keyIdProp != null) {
- kid = props.getProperty(keyIdProp);
+ private static String getKeyId(Message m, Properties props, String preferredPropertyName, String keyOper) {
+ String kid = null;
+ String altPropertyName = null;
+ if (keyOper != null) {
+ if (keyOper.equals(JsonWebKey.KEY_OPER_ENCRYPT) || keyOper.equals(JsonWebKey.KEY_OPER_DECRYPT)) {
+ altPropertyName = preferredPropertyName + ".jwe";
+ } else if (keyOper.equals(JsonWebKey.KEY_OPER_SIGN) || keyOper.equals(JsonWebKey.KEY_OPER_VERIFY)) {
+ altPropertyName = preferredPropertyName + ".jws";
}
+ String direction = m.getExchange().getOutMessage() == m ? ".out" : ".in";
+ kid = (String)MessageUtils.getContextualProperty(m, altPropertyName, altPropertyName + direction);
+ }
+
+ if (kid == null) {
+ kid = props.getProperty(preferredPropertyName);
+ }
+ if (kid == null && altPropertyName != null) {
+ kid = props.getProperty(altPropertyName);
}
return kid;
}
@@ -384,7 +412,7 @@ public final class JwkUtils {
(PrivateKeyPasswordProvider)m.getContextualProperty(KeyManagementUtils.RSSEC_KEY_PSWD_PROVIDER);
if (cb == null && keyOper != null) {
String propName = keyOper.equals(JsonWebKey.KEY_OPER_SIGN) ? KeyManagementUtils.RSSEC_SIG_KEY_PSWD_PROVIDER
- : keyOper.equals(JsonWebKey.KEY_OPER_ENCRYPT)
+ : keyOper.equals(JsonWebKey.KEY_OPER_DECRYPT)
? KeyManagementUtils.RSSEC_DECRYPT_KEY_PSWD_PROVIDER : null;
if (propName != null) {
cb = (PrivateKeyPasswordProvider)m.getContextualProperty(propName);
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
index 8bab845..e9d228a 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
@@ -105,7 +105,7 @@ public final class JwsUtils {
String rsaSignatureAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm : jwk.getAlgorithm();
JwsSignatureVerifier theVerifier = null;
if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) {
- theVerifier = getRSAKeySignatureVerifier(JwkUtils.toRSAPublicKey(jwk), rsaSignatureAlgo);
+ theVerifier = getRSAKeySignatureVerifier(JwkUtils.toRSAPublicKey(jwk, true), rsaSignatureAlgo);
} else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType())) {
byte[] key = JoseUtils.decode((String)jwk.getProperty(JsonWebKey.OCTET_KEY_VALUE));
theVerifier = getHmacSignatureVerifier(key, rsaSignatureAlgo);
@@ -195,7 +195,7 @@ public final class JwsUtils {
}
List<JwsSignatureVerifier> theVerifiers = null;
if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(KeyManagementUtils.RSSEC_KEY_STORE_TYPE))) {
- List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, JsonWebKey.KEY_OPER_SIGN);
+ List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, JsonWebKey.KEY_OPER_VERIFY);
if (jwks != null) {
theVerifiers = new ArrayList<JwsSignatureVerifier>(jwks.size());
for (JsonWebKey jwk : jwks) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKeyTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKeyTest.java b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKeyTest.java
index eb660ae..15ade7d 100644
--- a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKeyTest.java
+++ b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/JsonWebKeyTest.java
@@ -20,6 +20,7 @@ package org.apache.cxf.rs.security.jose.jwk;
import java.io.InputStream;
import java.security.Security;
+import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
@@ -73,7 +74,7 @@ public class JsonWebKeyTest extends Assert {
public void testPublicSetAsList() throws Exception {
JsonWebKeys jwks = readKeySet("jwkPublicSet.txt");
List<JsonWebKey> keys = jwks.getKeys();
- assertEquals(2, keys.size());
+ assertEquals(3, keys.size());
JsonWebKey ecKey = keys.get(0);
assertEquals(6, ecKey.asMap().size());
@@ -81,13 +82,18 @@ public class JsonWebKeyTest extends Assert {
JsonWebKey rsaKey = keys.get(1);
assertEquals(5, rsaKey.asMap().size());
validatePublicRsaKey(rsaKey);
+ JsonWebKey rsaKeyCert = keys.get(2);
+ assertEquals(3, rsaKeyCert.asMap().size());
+ assertEquals(3, rsaKeyCert.getX509Chain().size());
+ List<X509Certificate> certs = JwkUtils.toX509CertificateChain(rsaKeyCert);
+ assertEquals(3, certs.size());
}
@Test
public void testPublicSetAsMap() throws Exception {
JsonWebKeys jwks = readKeySet("jwkPublicSet.txt");
Map<String, JsonWebKey> keysMap = jwks.getKeyIdMap();
- assertEquals(2, keysMap.size());
+ assertEquals(3, keysMap.size());
JsonWebKey rsaKey = keysMap.get(RSA_KID_VALUE);
assertEquals(5, rsaKey.asMap().size());
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/jwkPublicSet.txt
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/jwkPublicSet.txt b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/jwkPublicSet.txt
index 5a4a839..2fd93f6 100644
--- a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/jwkPublicSet.txt
+++ b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwk/jwkPublicSet.txt
@@ -11,7 +11,17 @@
"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
"e":"AQAB",
"alg":"RS256",
- "kid":"2011-04-29"}
+ "kid":"2011-04-29"},
+
+ {
+ "kty":"RSA",
+ "kid":"RSACerts",
+ "x5c": [
+ "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
tdEy8W9ViH0Pd"
+ ]
+ }
]
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JAXRSJweJwsTest.java
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JAXRSJweJwsTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JAXRSJweJwsTest.java
index c451657..08ea2cc 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JAXRSJweJwsTest.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/JAXRSJweJwsTest.java
@@ -33,6 +33,7 @@ import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBusFactory;
import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
+import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.rs.security.jose.jaxrs.JweClientResponseFilter;
import org.apache.cxf.rs.security.jose.jaxrs.JweWriterInterceptor;
import org.apache.cxf.rs.security.jose.jaxrs.JwsClientResponseFilter;
@@ -59,6 +60,8 @@ public class JAXRSJweJwsTest extends AbstractBusClientServerTestBase {
"org/apache/cxf/systest/jaxrs/security/bob.rs.properties";
private static final String SERVER_JWEJWS_PROPERTIES =
"org/apache/cxf/systest/jaxrs/security/alice.rs.properties";
+ private static final String PUBLIC_JWEJWS_PROPERTIES =
+ "org/apache/cxf/systest/jaxrs/security/public.jwk.properties";
private static final String ENCODED_MAC_KEY = "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75"
+ "aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow";
@BeforeClass
@@ -182,6 +185,42 @@ public class JAXRSJweJwsTest extends AbstractBusClientServerTestBase {
assertEquals("book", text);
}
@Test
+ public void testJweRsaJwsRsaCert() throws Exception {
+ String address = "https://localhost:" + PORT + "/jwejwsrsacert";
+
+ JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = JAXRSJweJwsTest.class.getResource("client.xml");
+ Bus springBus = bf.createBus(busFile.toString());
+ bean.setBus(springBus);
+ bean.setServiceClass(BookStore.class);
+ bean.setAddress(address);
+ List<Object> providers = new LinkedList<Object>();
+ JweWriterInterceptor jweWriter = new JweWriterInterceptor();
+ jweWriter.setUseJweOutputStream(true);
+ providers.add(jweWriter);
+ providers.add(new JweClientResponseFilter());
+ JwsWriterInterceptor jwsWriter = new JwsWriterInterceptor();
+ jwsWriter.setUseJwsOutputStream(true);
+ providers.add(jwsWriter);
+ providers.add(new JwsClientResponseFilter());
+
+ bean.setProviders(providers);
+ bean.getProperties(true).put("rs.security.encryption.out.properties", PUBLIC_JWEJWS_PROPERTIES);
+ bean.getProperties(true).put("rs.security.signature.out.properties", CLIENT_JWEJWS_PROPERTIES);
+ bean.getProperties(true).put("rs.security.encryption.in.properties", CLIENT_JWEJWS_PROPERTIES);
+ bean.getProperties(true).put("rs.security.signature.in.properties", PUBLIC_JWEJWS_PROPERTIES);
+ PrivateKeyPasswordProvider provider = new PrivateKeyPasswordProviderImpl();
+ bean.getProperties(true).put("rs.security.signature.key.password.provider", provider);
+ bean.getProperties(true).put("rs.security.decryption.key.password.provider", provider);
+ BookStore bs = bean.create(BookStore.class);
+
+ WebClient.getConfig(bs).getRequestContext().put("rs.security.keystore.alias.jwe.out", "AliceCert");
+ WebClient.getConfig(bs).getRequestContext().put("rs.security.keystore.alias.jws.in", "AliceCert");
+ String text = bs.echoText("book");
+ assertEquals("book", text);
+ }
+ @Test
public void testJweRsaJwsPlainTextHMac() throws Exception {
String address = "https://localhost:" + PORT + "/jwejwshmac";
HmacJwsSignatureProvider hmacProvider =
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/server.xml
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/server.xml b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/server.xml
index 0ba3a5a..d357cb9 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/server.xml
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jwt/server.xml
@@ -98,6 +98,27 @@ under the License.
<entry key="rs.security.decryption.key.password.provider" value-ref="keyPasswordProvider"/>
</jaxrs:properties>
</jaxrs:server>
+ <jaxrs:server address="https://localhost:${testutil.ports.jaxrs-jwt}/jwejwsrsacert">
+ <jaxrs:serviceBeans>
+ <ref bean="serviceBean"/>
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <ref bean="jweInFilter"/>
+ <ref bean="jweOutFilter"/>
+ <ref bean="jwsInFilter"/>
+ <ref bean="jwsOutFilter"/>
+ </jaxrs:providers>
+ <jaxrs:properties>
+ <entry key="rs.security.encryption.in.properties" value="org/apache/cxf/systest/jaxrs/security/alice.rs.properties"/>
+ <entry key="rs.security.signature.in.properties" value="org/apache/cxf/systest/jaxrs/security/public.jwk.properties"/>
+ <entry key="rs.security.encryption.out.properties" value="org/apache/cxf/systest/jaxrs/security/public.jwk.properties"/>
+ <entry key="rs.security.signature.out.properties" value="org/apache/cxf/systest/jaxrs/security/alice.rs.properties"/>
+ <entry key="rs.security.keystore.alias.jwe.out" value="BobCert"/>
+ <entry key="rs.security.keystore.alias.jws.in" value="BobCert"/>
+ <entry key="rs.security.signature.key.password.provider" value-ref="keyPasswordProvider"/>
+ <entry key="rs.security.decryption.key.password.provider" value-ref="keyPasswordProvider"/>
+ </jaxrs:properties>
+ </jaxrs:server>
<bean id="jackson" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
<jaxrs:server address="https://localhost:${testutil.ports.jaxrs-jwt}/jwejwkrsa">
<jaxrs:serviceBeans>
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/jwkPublicSet.txt
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/jwkPublicSet.txt b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/jwkPublicSet.txt
index 6ecc25e..3e1f6a2 100644
--- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/jwkPublicSet.txt
+++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/certs/jwkPublicSet.txt
@@ -10,5 +10,22 @@
"y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
"use":"enc",
"kid":"ECKey"},
+
+ {
+ "kty":"RSA",
+ "kid":"AliceCert",
+ "x5c": [
+ "MIICGjCCAYOgAwIBAgIESVRgATANBgkqhkiG9w0BAQUFADAzMRMwEQYDVQQKEwphcGFjaGUub3JnMQwwCgYDVQQLEwNlbmcxDjAMBgNVBAMTBWN4ZmNhMB4XDTcwMDEwMTAwMDAwMFoXDTM4MDExOTAzMTQwN1owMzETMBEGA1UEChMKYXBhY2hlLm9yZzEMMAoGA1UECxMDZW5nMQ4wDAYDVQQDEwVhbGljZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvu747/VShQ85f16DGSc4Ixh9PVpGguyEqrCsK8q9XHOYX9l9/g5wEC6ZcR2FwfNsoaHcKNPjd5sSTzVtBWmQjfBEfIqwTR7vuihOxyNTwEzVwIJzvo7p8/aYxk+VdBtQxq4UweIcf/iFkUbM1cZ1oiXRQzciRBi+C1BQCQE0qzsCAwEAAaM7MDkwIQYDVR0SBBowGIIWTk9UX0ZPUl9QUk9EVUNUSU9OX1VTRTAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQEFBQADgYEAhLwkm+8psKt4gnbikGzV0TgpSWGcWxWKBi+z8tI2n6hFA5v1jVHHa4G9h3s0nxQ2TewzeR/k7gmgV2sI483NgrYHmTmLKaDBWza2pAuZuDhQH8GAEhJakFtKBP++EC9rNNpZnqqHxx3qb2tW25qRtBzDmK921gg9PMomMc7uqRQ="
+ ]
+ },
+
+ {
+ "kty":"RSA",
+ "kid":"BobCert",
+ "x5c": [
+ "MIICGDCCAYGgAwIBAgIESVRgAjANBgkqhkiG9w0BAQUFADAzMRMwEQYDVQQKEwphcGFjaGUub3JnMQwwCgYDVQQLEwNlbmcxDjAMBgNVBAMTBWN4ZmNhMB4XDTcwMDEwMTAwMDAwMFoXDTM4MDExOTAzMTQwN1owMTETMBEGA1UEChMKYXBhY2hlLm9yZzEMMAoGA1UECxMDZW5nMQwwCgYDVQQDEwNib2IwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIUcy5V9ow7xb1GOI+5ub1YIApEvw7JSySBdYv9eeVFVG/c0Sxoqcwmlc0tJcxF1K2hEcXL4Na9hWkzmLO3QAzEKGseLsXXTGinFaXW3RL7lOXuJ6bbWsosF+YIv0fHqS1ZHREd2KAou1GWiAP9Stu0JiOQF211eRo+RZisQkDwvAgMBAAGjOzA5MCEGA1UdEgQaMBiCFk5PVF9GT1JfUFJPRFVDVElPTl9VU0UwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBBQUAA4GBAFncwiuc44aCHD8IJ8/t4hmCZzqi+2O33E7OkHQz83R5Vs9YHt+ZkIO9vvnwhq1vcq68HNlG1e+wbeIyde58zYLcUZN5qZxHNchj0Hb70BmBQqYEd7C9SXtluJDguinQpkSTyJ1Nt0tx7ropBq/l43LGuca5isD4yx/JAhnm1469"
+ ]
+ }
+
]
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/a9555675/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/public.jwk.properties
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/public.jwk.properties b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/public.jwk.properties
new file mode 100644
index 0000000..6cb973e
--- /dev/null
+++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/public.jwk.properties
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+rs.security.keystore.type=jwk
+rs.security.keystore.file=org/apache/cxf/systest/jaxrs/security/certs/jwkPublicSet.txt
+rs.security.jwe.content.encryption.algorithm=A128GCM
+rs.security.jwe.key.encryption.algorithm=RSA-OAEP
+rs.security.jws.content.signature.algorithm=RS256