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 2017/06/30 14:17:56 UTC
[2/2] cxf git commit: [CXF-7434] JweJson and other related
improvements
[CXF-7434] JweJson and other related improvements
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/33eb378e
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/33eb378e
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/33eb378e
Branch: refs/heads/master
Commit: 33eb378e47cee7d9c2ce0f7cb04cf0d5bcce4ad7
Parents: e4328f8
Author: Sergey Beryozkin <sb...@gmail.com>
Authored: Fri Jun 30 15:17:38 2017 +0100
Committer: Sergey Beryozkin <sb...@gmail.com>
Committed: Fri Jun 30 15:17:38 2017 +0100
----------------------------------------------------------------------
.../cxf/jaxrs/json/basic/JsonMapObject.java | 4 +
.../jaxrs/AbstractJweJsonWriterProvider.java | 102 ++++++-
.../jaxrs/AbstractJwsJsonWriterProvider.java | 29 +-
.../jose/jaxrs/JweJsonWriterInterceptor.java | 38 +--
.../jose/jaxrs/JwsJsonWriterInterceptor.java | 39 ++-
.../JwsMultipartSignatureInFilter.java | 2 +-
.../cxf/rs/security/jose/common/JoseUtils.java | 12 +
.../jose/common/KeyManagementUtils.java | 13 +
.../cxf/rs/security/jose/jwa/KeyAlgorithm.java | 3 +
.../jose/jwe/DirectKeyDecryptionAlgorithm.java | 2 +-
.../jose/jwe/DirectKeyEncryptionAlgorithm.java | 5 +-
.../rs/security/jose/jwe/JweJsonConsumer.java | 3 +-
.../jose/jwe/JweJsonEncryptionEntry.java | 2 +-
.../rs/security/jose/jwe/JweJsonProducer.java | 9 +-
.../cxf/rs/security/jose/jwe/JweUtils.java | 277 ++++++++++---------
.../cxf/rs/security/jose/jws/JwsUtils.java | 115 ++------
.../security/jose/jwe/JweJsonConsumerTest.java | 8 +-
.../cxf/rs/security/jose/jws/JwsUtilsTest.java | 3 +-
.../token/provider/jwt/JWTTokenProvider.java | 2 +-
.../token/provider/JWTTokenProviderTest.java | 6 +-
.../jaxrs/JAXRSClientServerBookTest.java | 2 +-
.../systest/jaxrs/security/jose/BookStore.java | 50 +++-
.../security/jose/jwejws/JAXRSJweJsonTest.java | 59 ++--
.../security/jose/jwejws/JAXRSJweJwsTest.java | 29 ++
.../security/jose/jwejws/JAXRSJwsJsonTest.java | 17 +-
.../jaxrs/security/certs/jwkPrivateSet.txt | 11 +
.../jaxrs/security/jose/jwejws/server.xml | 12 +
.../security/jose/jwejws/serverJweJson.xml | 25 +-
.../jaxrs/security/jwe.direct.properties | 21 ++
.../systest/jaxrs/security/jwejson1.properties | 22 ++
.../systest/jaxrs/security/jwejson2.properties | 22 ++
.../jaxrs/security/secret.jwk.hmac2.properties | 19 --
32 files changed, 607 insertions(+), 356 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java
----------------------------------------------------------------------
diff --git a/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java b/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java
index 184b525..e1bf0bb 100644
--- a/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java
+++ b/rt/rs/extensions/json-basic/src/main/java/org/apache/cxf/jaxrs/json/basic/JsonMapObject.java
@@ -121,4 +121,8 @@ public class JsonMapObject implements Serializable {
public Map<String, Object> getUpdateCount() {
return updateCount == null ? null : Collections.<String, Object>unmodifiableMap(updateCount);
}
+
+ public Object removeProperty(String name) {
+ return values.remove(name);
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java
index d131c8d..8e41ac4 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweJsonWriterProvider.java
@@ -21,10 +21,14 @@ package org.apache.cxf.rs.security.jose.jaxrs;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Properties;
+import java.util.Set;
import java.util.logging.Logger;
import org.apache.cxf.common.logging.LogUtils;
@@ -35,9 +39,18 @@ import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.rs.security.jose.common.JoseConstants;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+import org.apache.cxf.rs.security.jose.jwe.ContentEncryptionProvider;
+import org.apache.cxf.rs.security.jose.jwe.JweEncryption;
import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider;
+import org.apache.cxf.rs.security.jose.jwe.JweException;
+import org.apache.cxf.rs.security.jose.jwe.JweHeaders;
import org.apache.cxf.rs.security.jose.jwe.JweUtils;
-import org.apache.cxf.rs.security.jose.jws.JwsException;
+import org.apache.cxf.rs.security.jose.jwe.KeyEncryptionProvider;
+import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
+import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
+import org.apache.cxf.rs.security.jose.jwk.KeyOperation;
import org.apache.cxf.rs.security.jose.jws.JwsJsonProducer;
public class AbstractJweJsonWriterProvider {
@@ -52,17 +65,18 @@ public class AbstractJweJsonWriterProvider {
this.encProviders = providers;
}
- protected List<JweEncryptionProvider> getInitializedEncryptionProviders() {
- if (encProviders != null) {
- return encProviders;
- }
+ protected List<String> getPropertyLocations() {
Message m = JAXRSUtils.getCurrentMessage();
Object propLocsProp =
MessageUtils.getContextualProperty(m, JoseConstants.RSSEC_ENCRYPTION_OUT_PROPS,
JoseConstants.RSSEC_ENCRYPTION_PROPS);
if (propLocsProp == null) {
- LOG.warning("JWE JSON init properties resource is not identified");
- throw new JwsException(JwsException.Error.NO_INIT_PROPERTIES);
+ if (encProviders == null) {
+ LOG.warning("JWE JSON init properties resource is not identified");
+ throw new JweException(JweException.Error.NO_INIT_PROPERTIES);
+ } else {
+ return Collections.emptyList();
+ }
}
List<String> propLocs = null;
if (propLocsProp instanceof String) {
@@ -71,9 +85,79 @@ public class AbstractJweJsonWriterProvider {
} else {
propLocs = CastUtils.cast((List<?>)propLocsProp);
}
+ return propLocs;
+ }
+
+ protected List<JweEncryptionProvider> getInitializedEncryptionProviders(List<String> propLocs,
+ JweHeaders sharedProtectedHeaders,
+ List<JweHeaders> perRecipientUnprotectedHeaders) {
+ if (encProviders != null) {
+ return encProviders;
+ }
+ // The task is to have a single ContentEncryptionProvider instance,
+ // configured to generate CEK only once, paired with all the loaded
+ // KeyEncryptionProviders to have JweEncryptionProviders initialized
+
+ Message m = JAXRSUtils.getCurrentMessage();
+ // Load all the properties
+ List<Properties> propsList = new ArrayList<Properties>(propLocs.size());
+ for (int i = 0; i < propLocs.size(); i++) {
+ propsList.add(JweUtils.loadJweProperties(m, propLocs.get(i)));
+ }
+
+
+ ContentAlgorithm ctAlgo = null;
+ // This set is to find out how many key encryption algorithms are used
+ // If only one then save it in the shared protected headers as opposed to
+ // per-recipient specific not protected ones
+ Set<KeyAlgorithm> keyAlgos = new HashSet<KeyAlgorithm>();
+
+ List<KeyEncryptionProvider> keyProviders = new LinkedList<KeyEncryptionProvider>();
+ for (int i = 0; i < propLocs.size(); i++) {
+ Properties props = propsList.get(i);
+ ContentAlgorithm currentCtAlgo = JweUtils.getContentEncryptionAlgorithm(m, props, ContentAlgorithm.A128GCM);
+ if (ctAlgo == null) {
+ ctAlgo = currentCtAlgo;
+ } else if (currentCtAlgo != null && !ctAlgo.equals(currentCtAlgo)) {
+ // ctAlgo must be the same for all the recipients
+ throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+ }
+
+ JweHeaders perRecipientUnprotectedHeader = perRecipientUnprotectedHeaders.get(i);
+ KeyEncryptionProvider keyEncryptionProvider =
+ JweUtils.loadKeyEncryptionProvider(props, m, perRecipientUnprotectedHeader);
+ if (keyEncryptionProvider.getAlgorithm() == KeyAlgorithm.DIRECT && propLocs.size() > 1) {
+ throw new JweException(JweException.Error.INVALID_JSON_JWE);
+ }
+ keyProviders.add(keyEncryptionProvider);
+
+ keyAlgos.add(perRecipientUnprotectedHeader.getKeyEncryptionAlgorithm());
+ }
+ if (ctAlgo == null) {
+ throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+ }
+ sharedProtectedHeaders.setContentEncryptionAlgorithm(ctAlgo);
+
List<JweEncryptionProvider> theEncProviders = new LinkedList<JweEncryptionProvider>();
- for (String propLoc : propLocs) {
- theEncProviders.addAll(JweUtils.loadJweEncryptionProviders(propLoc, m));
+ if (keyProviders.size() == 1 && keyProviders.get(0).getAlgorithm() == KeyAlgorithm.DIRECT) {
+ JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, propsList.get(0), KeyOperation.ENCRYPT);
+ if (jwk != null) {
+ ContentEncryptionProvider ctProvider = JweUtils.getContentEncryptionProvider(jwk, ctAlgo);
+ JweEncryptionProvider encProvider = new JweEncryption(keyProviders.get(0), ctProvider);
+ theEncProviders.add(encProvider);
+ }
+ } else {
+ ContentEncryptionProvider ctProvider = JweUtils.getContentEncryptionProvider(ctAlgo, true);
+ for (int i = 0; i < keyProviders.size(); i++) {
+ JweEncryptionProvider encProvider = new JweEncryption(keyProviders.get(0), ctProvider);
+ theEncProviders.add(encProvider);
+ }
+ }
+ if (keyAlgos.size() == 1) {
+ sharedProtectedHeaders.setKeyEncryptionAlgorithm(keyAlgos.iterator().next());
+ for (int i = 0; i < perRecipientUnprotectedHeaders.size(); i++) {
+ perRecipientUnprotectedHeaders.get(i).removeProperty(JoseConstants.JWE_HEADER_KEY_ENC_ALGORITHM);
+ }
}
return theEncProviders;
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
index 31db16d..d2f10c3 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsJsonWriterProvider.java
@@ -25,6 +25,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Properties;
import java.util.logging.Logger;
import org.apache.cxf.common.logging.LogUtils;
@@ -36,6 +37,7 @@ import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.rs.security.jose.common.JoseConstants;
import org.apache.cxf.rs.security.jose.jws.JwsException;
+import org.apache.cxf.rs.security.jose.jws.JwsHeaders;
import org.apache.cxf.rs.security.jose.jws.JwsJsonProducer;
import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider;
import org.apache.cxf.rs.security.jose.jws.JwsUtils;
@@ -52,17 +54,18 @@ public class AbstractJwsJsonWriterProvider {
this.sigProviders = signatureProviders;
}
- protected List<JwsSignatureProvider> getInitializedSigProviders() {
- if (sigProviders != null) {
- return sigProviders;
- }
+ protected List<String> getPropertyLocations() {
Message m = JAXRSUtils.getCurrentMessage();
Object propLocsProp =
MessageUtils.getContextualProperty(m, JoseConstants.RSSEC_SIGNATURE_OUT_PROPS,
JoseConstants.RSSEC_SIGNATURE_PROPS);
if (propLocsProp == null) {
- LOG.warning("JWS JSON init properties resource is not identified");
- throw new JwsException(JwsException.Error.NO_INIT_PROPERTIES);
+ if (sigProviders == null) {
+ LOG.warning("JWS JSON init properties resource is not identified");
+ throw new JwsException(JwsException.Error.NO_INIT_PROPERTIES);
+ } else {
+ return Collections.emptyList();
+ }
}
List<String> propLocs = null;
if (propLocsProp instanceof String) {
@@ -71,9 +74,19 @@ public class AbstractJwsJsonWriterProvider {
} else {
propLocs = CastUtils.cast((List<?>)propLocsProp);
}
+ return propLocs;
+ }
+
+ protected List<JwsSignatureProvider> getInitializedSigProviders(
+ List<String> propLocs, List<JwsHeaders> protectedHeaders) {
+ if (sigProviders != null) {
+ return sigProviders;
+ }
+ Message m = JAXRSUtils.getCurrentMessage();
List<JwsSignatureProvider> theSigProviders = new LinkedList<JwsSignatureProvider>();
- for (String propLoc : propLocs) {
- theSigProviders.addAll(JwsUtils.loadSignatureProviders(propLoc, m));
+ for (int i = 0; i < propLocs.size(); i++) {
+ Properties props = JwsUtils.loadJwsProperties(m, propLocs.get(i));
+ theSigProviders.add(JwsUtils.loadSignatureProvider(props, protectedHeaders.get(i)));
}
return theSigProviders;
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
index 9d0926f..9405a2c 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweJsonWriterInterceptor.java
@@ -36,8 +36,6 @@ import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.rs.security.jose.common.JoseConstants;
-import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
-import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider;
import org.apache.cxf.rs.security.jose.jwe.JweHeaders;
import org.apache.cxf.rs.security.jose.jwe.JweJsonProducer;
@@ -55,7 +53,15 @@ public class JweJsonWriterInterceptor extends AbstractJweJsonWriterProvider impl
return;
}
OutputStream actualOs = ctx.getOutputStream();
- List<JweEncryptionProvider> providers = getInitializedEncryptionProviders();
+ JweHeaders sharedProtectedHeaders = new JweHeaders();
+ List<String> propLocs = getPropertyLocations();
+ List<JweHeaders> perRecipientUnprotectedHeaders = new ArrayList<JweHeaders>(propLocs.size());
+ for (int i = 0; i < propLocs.size(); i++) {
+ perRecipientUnprotectedHeaders.add(new JweHeaders());
+ }
+ List<JweEncryptionProvider> providers = getInitializedEncryptionProviders(propLocs,
+ sharedProtectedHeaders,
+ perRecipientUnprotectedHeaders);
String ctString = null;
MediaType contentMediaType = ctx.getMediaType();
@@ -66,30 +72,10 @@ public class JweJsonWriterInterceptor extends AbstractJweJsonWriterProvider impl
ctString = JAXRSUtils.mediaTypeToString(contentMediaType);
}
}
- JweHeaders protectedHeaders = new JweHeaders(ContentAlgorithm.A128GCM);
if (ctString != null) {
- protectedHeaders.setContentType(ctString);
- }
- protectHttpHeadersIfNeeded(ctx, protectedHeaders);
- List<KeyAlgorithm> keyAlgos = new ArrayList<>();
- for (JweEncryptionProvider p : providers) {
- if (!keyAlgos.contains(p.getKeyAlgorithm())) {
- keyAlgos.add(p.getKeyAlgorithm());
- }
- }
- List<JweHeaders> perRecipientUnprotectedHeaders = null;
- if (keyAlgos.size() == 1) {
- // Can be optionally set in shared unprotected headers
- // or per-recipient headers
- protectedHeaders.setKeyEncryptionAlgorithm(keyAlgos.get(0));
- } else {
- perRecipientUnprotectedHeaders = new ArrayList<>();
- for (KeyAlgorithm keyAlgo : keyAlgos) {
- JweHeaders headers = new JweHeaders();
- headers.setKeyEncryptionAlgorithm(keyAlgo);
- perRecipientUnprotectedHeaders.add(headers);
- }
+ sharedProtectedHeaders.setContentType(ctString);
}
+ protectHttpHeadersIfNeeded(ctx, sharedProtectedHeaders);
if (useJweOutputStream) {
//TODO
} else {
@@ -99,7 +85,7 @@ public class JweJsonWriterInterceptor extends AbstractJweJsonWriterProvider impl
- JweJsonProducer producer = new JweJsonProducer(protectedHeaders, cos.getBytes());
+ JweJsonProducer producer = new JweJsonProducer(sharedProtectedHeaders, cos.getBytes());
String jweContent = producer.encryptWith(providers, perRecipientUnprotectedHeaders);
setJoseMediaType(ctx);
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
index 6aca136..0ac3000 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJsonWriterInterceptor.java
@@ -59,15 +59,23 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider impl
ctx.proceed();
return;
}
- List<JwsSignatureProvider> sigProviders = getInitializedSigProviders();
+ List<String> propLocs = getPropertyLocations();
+ List<JwsHeaders> protectedHeaders = new ArrayList<JwsHeaders>(propLocs.size());
+ for (int i = 0; i < propLocs.size(); i++) {
+ protectedHeaders.add(new JwsHeaders());
+ }
+ List<JwsSignatureProvider> sigProviders = getInitializedSigProviders(propLocs, protectedHeaders);
OutputStream actualOs = ctx.getOutputStream();
if (useJwsOutputStream) {
- List<String> protectedHeaders = new ArrayList<>(sigProviders.size());
+ List<String> encodedProtectedHeaders = new ArrayList<>(sigProviders.size());
List<JwsSignature> signatures = new ArrayList<>(sigProviders.size());
- for (JwsSignatureProvider signer : sigProviders) {
- JwsHeaders protectedHeader = prepareProtectedHeader(ctx, signer);
+ int size = sigProviders.size();
+ for (int i = 0; i < size; i++) {
+ JwsSignatureProvider signer = sigProviders.get(i);
+ JwsHeaders protectedHeader = protectedHeaders.get(i);
+ prepareProtectedHeader(protectedHeader, ctx, signer, size == 1);
String encoded = Base64UrlUtility.encode(writer.toJson(protectedHeader));
- protectedHeaders.add(encoded);
+ encodedProtectedHeaders.add(encoded);
JwsSignature signature = signer.createJwsSignature(protectedHeader);
byte[] start = StringUtils.toBytesUTF8(encoded + ".");
signature.update(start, 0, start.length);
@@ -75,7 +83,7 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider impl
}
ctx.setMediaType(JAXRSUtils.toMediaType(JoseConstants.MEDIA_TYPE_JOSE_JSON));
actualOs.write(StringUtils.toBytesUTF8("{\"payload\":\""));
- JwsJsonOutputStream jwsStream = new JwsJsonOutputStream(actualOs, protectedHeaders, signatures);
+ JwsJsonOutputStream jwsStream = new JwsJsonOutputStream(actualOs, encodedProtectedHeaders, signatures);
Base64UrlOutputStream base64Stream = null;
if (encodePayload) {
@@ -94,8 +102,11 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider impl
ctx.setOutputStream(cos);
ctx.proceed();
JwsJsonProducer p = new JwsJsonProducer(new String(cos.getBytes(), StandardCharsets.UTF_8));
- for (JwsSignatureProvider signer : sigProviders) {
- JwsHeaders protectedHeader = prepareProtectedHeader(ctx, signer);
+ int size = sigProviders.size();
+ for (int i = 0; i < size; i++) {
+ JwsSignatureProvider signer = sigProviders.get(i);
+ JwsHeaders protectedHeader = protectedHeaders.get(i);
+ prepareProtectedHeader(protectedHeader, ctx, signer, size == 1);
p.signWith(signer, protectedHeader, null);
}
ctx.setMediaType(JAXRSUtils.toMediaType(JoseConstants.MEDIA_TYPE_JOSE_JSON));
@@ -104,16 +115,18 @@ public class JwsJsonWriterInterceptor extends AbstractJwsJsonWriterProvider impl
}
- private JwsHeaders prepareProtectedHeader(WriterInterceptorContext ctx,
- JwsSignatureProvider signer) {
- JwsHeaders headers = new JwsHeaders();
+ private void prepareProtectedHeader(JwsHeaders headers,
+ WriterInterceptorContext ctx,
+ JwsSignatureProvider signer,
+ boolean protectHttp) {
headers.setSignatureAlgorithm(signer.getAlgorithm());
setContentTypeIfNeeded(headers, ctx);
if (!encodePayload) {
headers.setPayloadEncodingStatus(false);
}
- protectHttpHeadersIfNeeded(ctx, headers);
- return headers;
+ if (protectHttp) {
+ protectHttpHeadersIfNeeded(ctx, headers);
+ }
}
public void setContentTypeRequired(boolean contentTypeRequired) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java
index e0a306d..2234850 100644
--- a/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java
+++ b/rt/rs/security/jose-parent/jose-jaxrs/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/multipart/JwsMultipartSignatureInFilter.java
@@ -103,7 +103,7 @@ public class JwsMultipartSignatureInFilter implements MultipartInputFilter {
JoseConstants.RSSEC_SIGNATURE_IN_PROPS,
JoseConstants.RSSEC_SIGNATURE_PROPS);
- theVerifier = JwsUtils.loadSignatureVerifier(message, props, headers, false);
+ theVerifier = JwsUtils.loadSignatureVerifier(message, props, headers);
} else {
theVerifier = verifier;
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java
index 428c775..470ede1 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/JoseUtils.java
@@ -31,6 +31,7 @@ import java.util.logging.Logger;
import org.apache.cxf.Bus;
import org.apache.cxf.common.classloader.ClassLoaderUtils;
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PropertyUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.jaxrs.json.basic.JsonMapObjectReaderWriter;
import org.apache.cxf.message.Message;
@@ -204,6 +205,17 @@ public final class JoseUtils {
return props;
}
+ public static boolean checkBooleanProperty(JoseHeaders headers, Properties props, Message m,
+ String propertyName) {
+ if (headers == null) {
+ return false;
+ }
+ if (props.containsKey(propertyName)) {
+ return PropertyUtils.isTrue(props.get(propertyName));
+ }
+ return MessageUtils.getContextualBoolean(m, propertyName, false);
+ }
+
//
// <End> Copied from JAX-RS RT FRONTEND ResourceUtils
//
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java
index 63c0b08..2b020df 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java
@@ -505,4 +505,17 @@ public final class KeyManagementUtils {
return null;
}
+
+ public static void setSha1DigestHeader(JoseHeaders headers, Message m, Properties props) {
+ String digest = loadDigestAndEncodeX509Certificate(m, props, MessageDigestUtils.ALGO_SHA_1);
+ if (digest != null) {
+ headers.setX509Thumbprint(digest);
+ }
+ }
+ public static void setSha256DigestHeader(JoseHeaders headers, Message m, Properties props) {
+ String digest = loadDigestAndEncodeX509Certificate(m, props, MessageDigestUtils.ALGO_SHA_256);
+ if (digest != null) {
+ headers.setX509ThumbprintSHA256(digest);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
index a403da0..460696d 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
@@ -71,6 +71,9 @@ public enum KeyAlgorithm {
if (algo == null) {
return null;
}
+ if (KeyAlgorithm.DIRECT.getJwaName().equals(algo)) {
+ return KeyAlgorithm.DIRECT;
+ }
return KeyAlgorithm.valueOf(algo.replace('-', '_')
.replace('+', '_'));
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
index 3f5c955..92bc469 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
@@ -44,7 +44,7 @@ public class DirectKeyDecryptionAlgorithm implements KeyDecryptionProvider {
}
@Override
public KeyAlgorithm getAlgorithm() {
- return null;
+ return KeyAlgorithm.DIRECT;
}
protected void validateKeyEncryptionKey(JweDecryptionInput jweDecryptionInput) {
byte[] encryptedCEK = jweDecryptionInput.getEncryptedCEK();
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
index 2f038a9..584390a 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
@@ -30,13 +30,14 @@ public class DirectKeyEncryptionAlgorithm implements KeyEncryptionProvider {
return new byte[0];
}
protected void checkKeyEncryptionAlgorithm(JweHeaders headers) {
- if (headers.getKeyEncryptionAlgorithm() != null) {
+ KeyAlgorithm keyAlgo = headers.getKeyEncryptionAlgorithm();
+ if (keyAlgo != null && !KeyAlgorithm.DIRECT.equals(keyAlgo)) {
LOG.warning("Key encryption algorithm header is set");
throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
}
}
@Override
public KeyAlgorithm getAlgorithm() {
- return null;
+ return KeyAlgorithm.DIRECT;
}
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java
index 4b71f8d..c457a2c 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumer.java
@@ -93,7 +93,8 @@ public class JweJsonConsumer {
for (Map.Entry<JweJsonEncryptionEntry, JweHeaders> entry : recipientsMap.entrySet()) {
KeyAlgorithm keyAlgo = entry.getValue().getKeyEncryptionAlgorithm();
if (keyAlgo != null && keyAlgo.equals(jwe.getKeyAlgorithm())
- || keyAlgo == null && jwe.getKeyAlgorithm() == null) {
+ || keyAlgo == null
+ && (jwe.getKeyAlgorithm() == null || KeyAlgorithm.DIRECT.equals(jwe.getKeyAlgorithm()))) {
if (recipientProps != null
&& !entry.getValue().asMap().entrySet().containsAll(recipientProps.entrySet())) {
continue;
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java
index f13502e..55f9897 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonEncryptionEntry.java
@@ -47,7 +47,7 @@ public class JweJsonEncryptionEntry implements JsonObject {
public String toJson() {
JsonMapObjectReaderWriter jsonWriter = new JsonMapObjectReaderWriter();
Map<String, Object> recipientsEntry = new LinkedHashMap<String, Object>();
- if (unprotectedHeader != null) {
+ if (unprotectedHeader != null && !unprotectedHeader.asMap().isEmpty()) {
recipientsEntry.put("header", this.unprotectedHeader);
}
if (encodedEncryptedKey != null) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
index 48f4145..0f5ae53 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
@@ -31,6 +31,7 @@ import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.Base64UrlUtility;
import org.apache.cxf.jaxrs.json.basic.JsonMapObjectReaderWriter;
import org.apache.cxf.rs.security.jose.common.JoseConstants;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
public class JweJsonProducer {
protected static final Logger LOG = LogUtils.getL7dLogger(JweJsonProducer.class);
@@ -106,7 +107,7 @@ public class JweJsonProducer {
JweHeaders perRecipientUnprotected =
recipientUnprotected == null ? null : recipientUnprotected.get(i);
JweHeaders jsonHeaders = null;
- if (perRecipientUnprotected != null) {
+ if (perRecipientUnprotected != null && !perRecipientUnprotected.asMap().isEmpty()) {
checkCriticalHeaders(perRecipientUnprotected);
if (!Collections.disjoint(unionHeaders.asMap().keySet(),
perRecipientUnprotected.asMap().keySet())) {
@@ -140,7 +141,9 @@ public class JweJsonProducer {
}
byte[] encryptedCek = state.getContentEncryptionKey();
- if (encryptedCek.length == 0 && encryptor.getKeyAlgorithm() != null) {
+ if (encryptedCek.length == 0
+ && encryptor.getKeyAlgorithm() != null
+ && !KeyAlgorithm.DIRECT.equals(encryptor.getKeyAlgorithm())) {
LOG.warning("Unexpected key encryption algorithm");
throw new JweException(JweException.Error.INVALID_JSON_JWE);
}
@@ -157,7 +160,7 @@ public class JweJsonProducer {
}
if (entries.size() == 1 && canBeFlat) {
JweHeaders unprotectedEntryHeader = entries.get(0).getUnprotectedHeader();
- if (unprotectedEntryHeader != null) {
+ if (unprotectedEntryHeader != null && !unprotectedEntryHeader.asMap().isEmpty()) {
jweJsonMap.put("header", unprotectedEntryHeader);
}
String encryptedKey = entries.get(0).getEncodedEncryptedKey();
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
index ca9192c..9fa4ec6 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweUtils.java
@@ -32,7 +32,6 @@ import java.security.interfaces.RSAPublicKey;
import java.security.spec.ECFieldFp;
import java.security.spec.ECPoint;
import java.security.spec.EllipticCurve;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -45,7 +44,6 @@ import javax.crypto.SecretKey;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.message.Message;
-import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.rs.security.jose.common.JoseConstants;
import org.apache.cxf.rs.security.jose.common.JoseHeaders;
@@ -303,8 +301,23 @@ public final class JweUtils {
return ContentAlgorithm.getAlgorithm(algo);
}
public static JweEncryption getDirectKeyJweEncryption(JsonWebKey key) {
- return getDirectKeyJweEncryption(JwkUtils.toSecretKey(key),
- getContentAlgo(key.getAlgorithm()));
+ if (AlgorithmUtils.isEcdhEsDirect(key.getAlgorithm())) {
+ return getEcDirectKeyJweEncryption(key, ContentAlgorithm.A128GCM);
+ } else {
+ return getDirectKeyJweEncryption(JwkUtils.toSecretKey(key), getContentAlgo(key.getAlgorithm()));
+ }
+ }
+ public static JweEncryption getEcDirectKeyJweEncryption(JsonWebKey key, ContentAlgorithm ctAlgo) {
+ if (AlgorithmUtils.isEcdhEsDirect(key.getAlgorithm())) {
+ String curve = key.getStringProperty(JsonWebKey.EC_CURVE);
+ if (curve == null) {
+ curve = JsonWebKey.EC_CURVE_P256;
+ }
+ ECPublicKey ecKey = JwkUtils.toECPublicKey(key);
+ return new EcdhDirectKeyJweEncryption(ecKey, curve, ctAlgo);
+ } else {
+ throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+ }
}
public static JweEncryption getDirectKeyJweEncryption(SecretKey key, ContentAlgorithm algo) {
return getDirectKeyJweEncryption(key.getEncoded(), algo);
@@ -318,7 +331,11 @@ public final class JweUtils {
}
}
public static JweDecryption getDirectKeyJweDecryption(JsonWebKey key) {
- return getDirectKeyJweDecryption(JwkUtils.toSecretKey(key), getContentAlgo(key.getAlgorithm()));
+ if (AlgorithmUtils.isEcdhEsDirect(key.getAlgorithm())) {
+ return getEcDirectKeyJweDecryption(key, ContentAlgorithm.A128GCM);
+ } else {
+ return getDirectKeyJweDecryption(JwkUtils.toSecretKey(key), getContentAlgo(key.getAlgorithm()));
+ }
}
public static JweDecryption getDirectKeyJweDecryption(SecretKey key, ContentAlgorithm algorithm) {
return getDirectKeyJweDecryption(key.getEncoded(), algorithm);
@@ -331,6 +348,18 @@ public final class JweUtils {
getContentDecryptionProvider(algorithm));
}
}
+ public static JweDecryption getEcDirectKeyJweDecryption(JsonWebKey key, ContentAlgorithm ctAlgo) {
+ if (AlgorithmUtils.isEcdhEsDirect(key.getAlgorithm())) {
+ String curve = key.getStringProperty(JsonWebKey.EC_CURVE);
+ if (curve == null) {
+ curve = JsonWebKey.EC_CURVE_P256;
+ }
+ ECPrivateKey ecKey = JwkUtils.toECPrivateKey(key);
+ return new EcdhDirectKeyJweDecryption(ecKey, ctAlgo);
+ } else {
+ throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+ }
+ }
public static JweEncryptionProvider loadEncryptionProvider(boolean required) {
return loadEncryptionProvider(null, required);
}
@@ -340,97 +369,108 @@ public final class JweUtils {
if (props == null) {
return null;
}
- return loadEncryptionProvider(props, headers, required);
+ return loadEncryptionProvider(props, headers);
}
- public static JweEncryptionProvider loadEncryptionProvider(Properties props, JweHeaders headers, boolean required) {
+ public static JweEncryptionProvider loadEncryptionProvider(Properties props, JweHeaders headers) {
Message m = PhaseInterceptorChain.getCurrentMessage();
-
- boolean includeCert =
- headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT, false);
- boolean includeCertSha1 = headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT_SHA1, false);
- boolean includeCertSha256 = !includeCertSha1 && headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT_SHA256, false);
-
- KeyEncryptionProvider keyEncryptionProvider = null;
- KeyAlgorithm keyAlgo = getKeyEncryptionAlgorithm(m, props, null, null);
+ return loadEncryptionProvider(props, m, headers);
+ }
+
+ public static JweEncryptionProvider loadEncryptionProvider(Properties props, Message m, JweHeaders headers) {
+
+ KeyEncryptionProvider keyEncryptionProvider = loadKeyEncryptionProvider(props, m, headers);
ContentAlgorithm contentAlgo = getContentEncryptionAlgorithm(m, props, null, ContentAlgorithm.A128GCM);
if (m != null) {
m.put(JoseConstants.RSSEC_ENCRYPTION_CONTENT_ALGORITHM, contentAlgo.getJwaName());
}
ContentEncryptionProvider ctEncryptionProvider = null;
- if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
+ if (KeyAlgorithm.DIRECT == keyEncryptionProvider.getAlgorithm()) {
JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, KeyOperation.ENCRYPT);
- if (KeyAlgorithm.DIRECT == keyAlgo) {
+ if (jwk != null) {
contentAlgo = getContentEncryptionAlgorithm(m, props,
- ContentAlgorithm.getAlgorithm(jwk.getAlgorithm()),
- ContentAlgorithm.A128GCM);
+ jwk.getAlgorithm() != null ? ContentAlgorithm.getAlgorithm(jwk.getAlgorithm()) : null,
+ contentAlgo);
ctEncryptionProvider = getContentEncryptionProvider(jwk, contentAlgo);
- } else {
- keyAlgo = getKeyEncryptionAlgorithm(m, props,
- KeyAlgorithm.getAlgorithm(jwk.getAlgorithm()),
- getDefaultKeyAlgorithm(jwk));
- keyEncryptionProvider = getKeyEncryptionProvider(jwk, keyAlgo);
-
- boolean includePublicKey = headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_PUBLIC_KEY, false);
- boolean includeKeyId = headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_KEY_ID, false);
+ }
+ }
+ String compression = props.getProperty(JoseConstants.RSSEC_ENCRYPTION_ZIP_ALGORITHM);
+ return createJweEncryptionProvider(keyEncryptionProvider,
+ ctEncryptionProvider,
+ contentAlgo,
+ compression,
+ headers);
+ }
+
+ public static KeyEncryptionProvider loadKeyEncryptionProvider(Properties props, Message m, JweHeaders headers) {
+
+ KeyEncryptionProvider keyEncryptionProvider = null;
+ KeyAlgorithm keyAlgo = getKeyEncryptionAlgorithm(m, props, null, null);
+ if (KeyAlgorithm.DIRECT == keyAlgo) {
+ keyEncryptionProvider = new DirectKeyEncryptionAlgorithm();
+ } else {
+ boolean includeCert =
+ JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT);
+ boolean includeCertSha1 =
+ JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT_SHA1);
+ boolean includeCertSha256 =
+ JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_CERT_SHA256);
+ boolean includeKeyId =
+ JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_ENCRYPTION_INCLUDE_KEY_ID);
- if (includeCert) {
- JwkUtils.includeCertChain(jwk, headers, keyAlgo.getJwaName());
- }
- if (includeCertSha1) {
- String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
- props, MessageDigestUtils.ALGO_SHA_1);
- if (digest != null) {
- headers.setX509Thumbprint(digest);
+ if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
+ JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, KeyOperation.ENCRYPT);
+ if (jwk != null) {
+ keyAlgo = getKeyEncryptionAlgorithm(m, props,
+ KeyAlgorithm.getAlgorithm(jwk.getAlgorithm()),
+ getDefaultKeyAlgorithm(jwk));
+ keyEncryptionProvider = getKeyEncryptionProvider(jwk, keyAlgo);
+
+ boolean includePublicKey =
+ JoseUtils.checkBooleanProperty(headers, props, m,
+ JoseConstants.RSSEC_ENCRYPTION_INCLUDE_PUBLIC_KEY);
+ if (includeCert) {
+ JwkUtils.includeCertChain(jwk, headers, keyAlgo.getJwaName());
}
- } else if (includeCertSha256) {
- String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
- props, MessageDigestUtils.ALGO_SHA_256);
- if (digest != null) {
- headers.setX509ThumbprintSHA256(digest);
+ if (includeCertSha1) {
+ KeyManagementUtils.setSha1DigestHeader(headers, m, props);
+ } else if (includeCertSha256) {
+ KeyManagementUtils.setSha256DigestHeader(headers, m, props);
+ }
+ if (includePublicKey) {
+ JwkUtils.includePublicKey(jwk, headers, keyAlgo.getJwaName());
+ }
+ if (includeKeyId && jwk.getKeyId() != null) {
+ headers.setKeyId(jwk.getKeyId());
}
}
- if (includePublicKey) {
- JwkUtils.includePublicKey(jwk, headers, keyAlgo.getJwaName());
- }
- if (includeKeyId && jwk.getKeyId() != null && headers != null) {
- headers.setKeyId(jwk.getKeyId());
+ } else {
+ keyEncryptionProvider = getPublicKeyEncryptionProvider(
+ KeyManagementUtils.loadPublicKey(m, props),
+ props,
+ keyAlgo);
+ if (includeCert) {
+ headers.setX509Chain(KeyManagementUtils.loadAndEncodeX509CertificateOrChain(m, props));
}
- }
- } else {
- keyEncryptionProvider = getPublicKeyEncryptionProvider(
- KeyManagementUtils.loadPublicKey(m, props),
- props,
- keyAlgo);
- if (includeCert) {
- headers.setX509Chain(KeyManagementUtils.loadAndEncodeX509CertificateOrChain(m, props));
- }
- if (includeCertSha1) {
- String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
- props, MessageDigestUtils.ALGO_SHA_1);
- if (digest != null) {
- headers.setX509Thumbprint(digest);
+ if (includeCertSha1) {
+ KeyManagementUtils.setSha1DigestHeader(headers, m, props);
+ } else if (includeCertSha256) {
+ KeyManagementUtils.setSha256DigestHeader(headers, m, props);
}
- } else if (includeCertSha256) {
- String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
- props, MessageDigestUtils.ALGO_SHA_256);
- if (digest != null) {
- headers.setX509ThumbprintSHA256(digest);
+ if (includeKeyId && props.containsKey(JoseConstants.RSSEC_KEY_STORE_ALIAS)) {
+ headers.setKeyId(props.getProperty(JoseConstants.RSSEC_KEY_STORE_ALIAS));
}
}
}
-
- String compression = props.getProperty(JoseConstants.RSSEC_ENCRYPTION_ZIP_ALGORITHM);
- return createJweEncryptionProvider(keyEncryptionProvider,
- ctEncryptionProvider,
- contentAlgo.getJwaName(),
- compression);
+ if (keyEncryptionProvider == null) {
+ throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+ }
+ headers.setKeyEncryptionAlgorithm(keyEncryptionProvider.getAlgorithm());
+ return keyEncryptionProvider;
+
}
+
+
public static JweDecryptionProvider loadDecryptionProvider(boolean required) {
return loadDecryptionProvider(null, required);
}
@@ -440,12 +480,11 @@ public final class JweUtils {
return null;
}
- return loadDecryptionProvider(props, inHeaders, required);
+ return loadDecryptionProvider(props, inHeaders);
}
public static JweDecryptionProvider loadDecryptionProvider(Properties props,
- JweHeaders inHeaders,
- boolean required) {
+ JweHeaders inHeaders) {
Message m = PhaseInterceptorChain.getCurrentMessage();
KeyDecryptionProvider keyDecryptionProvider = null;
@@ -524,50 +563,7 @@ public final class JweUtils {
return createJweDecryptionProvider(keyDecryptionProvider, ctDecryptionKey,
contentAlgo);
}
- public static List<JweEncryptionProvider> loadJweEncryptionProviders(String propLoc, Message m) {
- Properties props = loadJweProperties(m, propLoc);
- JweEncryptionProvider theEncProvider = loadEncryptionProvider(props, null, false);
- if (theEncProvider != null) {
- return Collections.singletonList(theEncProvider);
- }
- List<JweEncryptionProvider> theEncProviders = null;
- if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
- List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.ENCRYPT);
- if (jwks != null) {
- theEncProviders = new ArrayList<>(jwks.size());
- for (JsonWebKey jwk : jwks) {
- theEncProviders.add(getDirectKeyJweEncryption(jwk));
- }
- }
- }
- if (theEncProviders == null) {
- LOG.warning("Providers are not available");
- throw new JweException(JweException.Error.NO_ENCRYPTOR);
- }
- return theEncProviders;
- }
- public static List<JweDecryptionProvider> loadJweDecryptionProviders(String propLoc, Message m) {
- Properties props = loadJweProperties(m, propLoc);
- JweDecryptionProvider theDecProvider = loadDecryptionProvider(props, null, false);
- if (theDecProvider != null) {
- return Collections.singletonList(theDecProvider);
- }
- List<JweDecryptionProvider> theDecProviders = null;
- if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
- List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.DECRYPT);
- if (jwks != null) {
- theDecProviders = new ArrayList<>(jwks.size());
- for (JsonWebKey jwk : jwks) {
- theDecProviders.add(getDirectKeyJweDecryption(jwk));
- }
- }
- }
- if (theDecProviders == null) {
- LOG.warning("Providers are not available");
- throw new JweException(JweException.Error.NO_ENCRYPTOR);
- }
- return theDecProviders;
- }
+
public static JweEncryptionProvider createJweEncryptionProvider(PublicKey key,
KeyAlgorithm keyAlgo,
ContentAlgorithm contentEncryptionAlgo) {
@@ -621,17 +617,23 @@ public final class JweUtils {
String compression) {
JweHeaders headers =
prepareJweHeaders(keyEncryptionProvider != null ? keyEncryptionProvider.getAlgorithm().getJwaName() : null,
- contentEncryptionAlgo.getJwaName(), compression);
+ contentEncryptionAlgo.getJwaName(), compression, null);
return createJweEncryptionProvider(keyEncryptionProvider, headers);
}
+
public static JweEncryptionProvider createJweEncryptionProvider(KeyEncryptionProvider keyEncryptionProvider,
JweHeaders headers) {
+ return createJweEncryptionProvider(keyEncryptionProvider, headers, false);
+ }
+ public static JweEncryptionProvider createJweEncryptionProvider(KeyEncryptionProvider keyEncryptionProvider,
+ JweHeaders headers,
+ boolean generateCekOnce) {
ContentAlgorithm contentEncryptionAlgo = headers.getContentEncryptionAlgorithm();
if (AlgorithmUtils.isAesCbcHmac(contentEncryptionAlgo.getJwaName())) {
- return new AesCbcHmacJweEncryption(contentEncryptionAlgo, keyEncryptionProvider);
+ return new AesCbcHmacJweEncryption(contentEncryptionAlgo, keyEncryptionProvider, generateCekOnce);
} else {
return new JweEncryption(keyEncryptionProvider,
- getContentEncryptionProvider(contentEncryptionAlgo));
+ getContentEncryptionProvider(contentEncryptionAlgo, generateCekOnce));
}
}
public static JweDecryptionProvider createJweDecryptionProvider(PrivateKey key,
@@ -798,8 +800,9 @@ public final class JweUtils {
}
private static JweHeaders prepareJweHeaders(String keyEncryptionAlgo,
String contentEncryptionAlgo,
- String compression) {
- JweHeaders headers = new JweHeaders();
+ String compression,
+ JweHeaders headers) {
+ headers = headers != null ? headers : new JweHeaders();
if (keyEncryptionAlgo != null) {
headers.setKeyEncryptionAlgorithm(KeyAlgorithm.getAlgorithm(keyEncryptionAlgo));
}
@@ -809,21 +812,23 @@ public final class JweUtils {
}
return headers;
}
+
private static JweEncryptionProvider createJweEncryptionProvider(KeyEncryptionProvider keyEncryptionProvider,
ContentEncryptionProvider ctEncryptionProvider,
- String contentEncryptionAlgo,
- String compression) {
+ ContentAlgorithm contentEncryptionAlgo,
+ String compression,
+ JweHeaders headers) {
if (keyEncryptionProvider == null && ctEncryptionProvider == null) {
LOG.warning("Key or content encryptor is not available");
throw new JweException(JweException.Error.NO_ENCRYPTOR);
}
- JweHeaders headers =
+ headers =
prepareJweHeaders(keyEncryptionProvider != null ? keyEncryptionProvider.getAlgorithm().getJwaName() : null,
- contentEncryptionAlgo, compression);
- if (keyEncryptionProvider != null) {
+ contentEncryptionAlgo.getJwaName(), compression, headers);
+ if (ctEncryptionProvider == null) {
return createJweEncryptionProvider(keyEncryptionProvider, headers);
} else {
- return new JweEncryption(new DirectKeyEncryptionAlgorithm(), ctEncryptionProvider);
+ return new JweEncryption(keyEncryptionProvider, ctEncryptionProvider);
}
}
private static JweDecryptionProvider createJweDecryptionProvider(KeyDecryptionProvider keyDecryptionProvider,
@@ -875,6 +880,9 @@ public final class JweUtils {
}
return algo;
}
+ public static ContentAlgorithm getContentEncryptionAlgorithm(Properties props) {
+ return getContentEncryptionAlgorithm(PhaseInterceptorChain.getCurrentMessage(), props, null);
+ }
public static ContentAlgorithm getContentEncryptionAlgorithm(Properties props,
ContentAlgorithm defaultAlgo) {
return getContentEncryptionAlgorithm(PhaseInterceptorChain.getCurrentMessage(), props, defaultAlgo);
@@ -943,7 +951,8 @@ public final class JweUtils {
return new JsonWebKeys(jwk);
}
}
- private static Properties loadJweProperties(Message m, String propLoc) {
+
+ public static Properties loadJweProperties(Message m, String propLoc) {
try {
return JoseUtils.loadProperties(propLoc, m.getExchange().getBus());
} catch (Exception ex) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
index cd5a008..b3a5c42 100644
--- a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
+++ b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsUtils.java
@@ -28,7 +28,6 @@ import java.security.interfaces.RSAKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -268,51 +267,8 @@ public final class JwsUtils {
Properties props = loadSignatureInProperties(required);
return loadSignatureVerifier(props, headers);
}
- public static List<JwsSignatureProvider> loadSignatureProviders(String propLoc, Message m) {
- Properties props = loadJwsProperties(m, propLoc);
- JwsSignatureProvider theSigProvider = loadSignatureProvider(m, props, null, true);
- if (theSigProvider != null) {
- return Collections.singletonList(theSigProvider);
- }
- List<JwsSignatureProvider> theSigProviders = null;
- if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
- List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.SIGN);
- if (jwks != null) {
- theSigProviders = new ArrayList<>(jwks.size());
- for (JsonWebKey jwk : jwks) {
- theSigProviders.add(JwsUtils.getSignatureProvider(jwk));
- }
- }
- }
- if (theSigProviders == null) {
- LOG.warning("Providers are not available");
- throw new JwsException(JwsException.Error.NO_PROVIDER);
- }
- return theSigProviders;
- }
-
- public static List<JwsSignatureVerifier> loadSignatureVerifiers(String propLoc, Message m) {
- Properties props = loadJwsProperties(m, propLoc);
- JwsSignatureVerifier theVerifier = loadSignatureVerifier(m, props, null, true);
- if (theVerifier != null) {
- return Collections.singletonList(theVerifier);
- }
- List<JwsSignatureVerifier> theVerifiers = null;
- if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
- List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.VERIFY);
- if (jwks != null) {
- theVerifiers = new ArrayList<>(jwks.size());
- for (JsonWebKey jwk : jwks) {
- theVerifiers.add(JwsUtils.getSignatureVerifier(jwk));
- }
- }
- }
- if (theVerifiers == null) {
- LOG.warning("Verifiers are not available");
- throw new JwsException(JwsException.Error.NO_VERIFIER);
- }
- return theVerifiers;
- }
+
+
public static boolean validateCriticalHeaders(JwsHeaders headers) {
//TODO: validate JWS specific constraints
return JoseUtils.validateCriticalHeaders(headers);
@@ -322,30 +278,25 @@ public final class JwsUtils {
return loadSignatureProvider(PhaseInterceptorChain.getCurrentMessage(),
props, headers);
}
- public static JwsSignatureProvider loadSignatureProvider(Message m,
- Properties props,
- JwsHeaders headers) {
- return loadSignatureProvider(m, props, headers, false);
- }
+
public static JwsSignatureProvider loadSignatureProvider(String propertiesLoc, Bus bus) {
Properties props = loadSignatureProperties(propertiesLoc, bus);
return loadSignatureProvider(props, null);
}
- private static JwsSignatureProvider loadSignatureProvider(Message m,
+ public static JwsSignatureProvider loadSignatureProvider(Message m,
Properties props,
- JwsHeaders headers,
- boolean ignoreNullProvider) {
+ JwsHeaders headers) {
JwsSignatureProvider theSigProvider = null;
- boolean includeCert = headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT, false);
- boolean includeCertSha1 = headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA1, false);
- boolean includeCertSha256 = !includeCertSha1 && headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA256, false);
- boolean includeKeyId = headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_KEY_ID, false);
+ boolean includeCert =
+ JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT);
+ boolean includeCertSha1 =
+ JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA1);
+ boolean includeCertSha256 =
+ JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA256);
+ boolean includeKeyId =
+ JoseUtils.checkBooleanProperty(headers, props, m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_KEY_ID);
if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, KeyOperation.SIGN);
@@ -356,24 +307,17 @@ public final class JwsUtils {
getDefaultKeyAlgorithm(jwk));
theSigProvider = JwsUtils.getSignatureProvider(jwk, signatureAlgo);
- boolean includePublicKey = headers != null && MessageUtils.getContextualBoolean(
- m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_PUBLIC_KEY, false);
+ boolean includePublicKey =
+ JoseUtils.checkBooleanProperty(headers, props, m,
+ JoseConstants.RSSEC_SIGNATURE_INCLUDE_PUBLIC_KEY);
if (includeCert) {
JwkUtils.includeCertChain(jwk, headers, signatureAlgo.getJwaName());
}
if (includeCertSha1) {
- String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
- props, MessageDigestUtils.ALGO_SHA_1);
- if (digest != null) {
- headers.setX509Thumbprint(digest);
- }
+ KeyManagementUtils.setSha1DigestHeader(headers, m, props);
} else if (includeCertSha256) {
- String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
- props, MessageDigestUtils.ALGO_SHA_256);
- if (digest != null) {
- headers.setX509ThumbprintSHA256(digest);
- }
+ KeyManagementUtils.setSha256DigestHeader(headers, m, props);
}
if (includePublicKey) {
JwkUtils.includePublicKey(jwk, headers, signatureAlgo.getJwaName());
@@ -397,24 +341,16 @@ public final class JwsUtils {
headers.setX509Chain(KeyManagementUtils.loadAndEncodeX509CertificateOrChain(m, props));
}
if (includeCertSha1) {
- String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
- props, MessageDigestUtils.ALGO_SHA_1);
- if (digest != null) {
- headers.setX509Thumbprint(digest);
- }
+ KeyManagementUtils.setSha1DigestHeader(headers, m, props);
} else if (includeCertSha256) {
- String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
- props, MessageDigestUtils.ALGO_SHA_256);
- if (digest != null) {
- headers.setX509ThumbprintSHA256(digest);
- }
+ KeyManagementUtils.setSha256DigestHeader(headers, m, props);
}
if (includeKeyId && props.containsKey(JoseConstants.RSSEC_KEY_STORE_ALIAS)) {
headers.setKeyId(props.getProperty(JoseConstants.RSSEC_KEY_STORE_ALIAS));
}
}
}
- if (theSigProvider == null && !ignoreNullProvider) {
+ if (theSigProvider == null) {
LOG.warning("Provider is not available");
throw new JwsException(JwsException.Error.NO_PROVIDER);
}
@@ -423,12 +359,11 @@ public final class JwsUtils {
public static JwsSignatureVerifier loadSignatureVerifier(Properties props,
JwsHeaders inHeaders) {
return loadSignatureVerifier(PhaseInterceptorChain.getCurrentMessage(),
- props, inHeaders, false);
+ props, inHeaders);
}
public static JwsSignatureVerifier loadSignatureVerifier(Message m,
Properties props,
- JwsHeaders inHeaders,
- boolean ignoreNullVerifier) {
+ JwsHeaders inHeaders) {
JwsSignatureVerifier theVerifier = null;
String inHeaderKid = null;
if (inHeaders != null) {
@@ -489,13 +424,13 @@ public final class JwsUtils {
}
}
}
- if (theVerifier == null && !ignoreNullVerifier) {
+ if (theVerifier == null) {
LOG.warning("Verifier is not available");
throw new JwsException(JwsException.Error.NO_VERIFIER);
}
return theVerifier;
}
- private static Properties loadJwsProperties(Message m, String propLoc) {
+ public static Properties loadJwsProperties(Message m, String propLoc) {
try {
return JoseUtils.loadProperties(propLoc, m.getExchange().getBus());
} catch (Exception ex) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java
index 4475375..0a3089e 100644
--- a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java
+++ b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonConsumerTest.java
@@ -161,9 +161,9 @@ public class JweJsonConsumerTest extends Assert {
jweProviders.add(jwe1);
jweProviders.add(jwe2);
- List<JweHeaders> perRecipientHeades = new LinkedList<JweHeaders>();
- perRecipientHeades.add(new JweHeaders("key1"));
- perRecipientHeades.add(new JweHeaders("key2"));
+ List<JweHeaders> perRecipientHeaders = new LinkedList<JweHeaders>();
+ perRecipientHeaders.add(new JweHeaders("key1"));
+ perRecipientHeaders.add(new JweHeaders("key2"));
JweJsonProducer p = new JweJsonProducer(protectedHeaders,
sharedUnprotectedHeaders,
@@ -171,7 +171,7 @@ public class JweJsonConsumerTest extends Assert {
StringUtils.toBytesUTF8(JweJsonProducerTest.EXTRA_AAD_SOURCE),
false);
- String jweJson = p.encryptWith(jweProviders, perRecipientHeades);
+ String jweJson = p.encryptWith(jweProviders, perRecipientHeaders);
doTestMultipleRecipients(jweJson);
}
private void doTestMultipleRecipients(String jweJson) {
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java
index 6f28ef4..d293ace 100644
--- a/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java
+++ b/rt/rs/security/jose-parent/jose/src/test/java/org/apache/cxf/rs/security/jose/jws/JwsUtilsTest.java
@@ -60,8 +60,7 @@ public class JwsUtilsTest extends Assert {
p.put(JoseConstants.RSSEC_KEY_STORE_ALIAS, "alice");
JwsSignatureVerifier jws = JwsUtils.loadSignatureVerifier(createMessage(),
p,
- new JwsHeaders(),
- false);
+ new JwsHeaders());
assertNotNull(jws);
}
@Test
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
index d1bb134..7cab14d 100644
--- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
+++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/jwt/JWTTokenProvider.java
@@ -332,7 +332,7 @@ public class JWTTokenProvider implements TokenProvider {
encProperties.put(JoseConstants.RSSEC_KEY_STORE, keystore);
JweEncryptionProvider encProvider =
- JweUtils.loadEncryptionProvider(encProperties, jweHeaders, false);
+ JweUtils.loadEncryptionProvider(encProperties, jweHeaders);
// token.getJwsHeaders().setSignatureAlgorithm(sigProvider.getAlgorithm());
return encProvider.encrypt(StringUtils.toBytesUTF8(token), null);
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
----------------------------------------------------------------------
diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
index cf09345..7c662d4 100644
--- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
+++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/JWTTokenProviderTest.java
@@ -236,7 +236,7 @@ public class JWTTokenProviderTest extends org.junit.Assert {
decProperties.put(JoseConstants.RSSEC_KEY_PSWD, "skpass");
JweDecryptionProvider decProvider =
- JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders(), false);
+ JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders());
JweDecryptionOutput decOutput = decProvider.decrypt(token);
String decToken = decOutput.getContentText();
@@ -290,7 +290,7 @@ public class JWTTokenProviderTest extends org.junit.Assert {
ContentAlgorithm.A128CBC_HS256.name());
JweDecryptionProvider decProvider =
- JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders(), false);
+ JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders());
JweDecryptionOutput decOutput = decProvider.decrypt(token);
String decToken = decOutput.getContentText();
@@ -337,7 +337,7 @@ public class JWTTokenProviderTest extends org.junit.Assert {
decProperties.put(JoseConstants.RSSEC_KEY_PSWD, "skpass");
JweDecryptionProvider decProvider =
- JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders(), false);
+ JweUtils.loadDecryptionProvider(decProperties, jwtConsumer.getHeaders());
JweDecryptionOutput decOutput = decProvider.decrypt(token);
String decToken = decOutput.getContentText();
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
index b86d923..b0ec144 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
@@ -123,7 +123,7 @@ public class JAXRSClientServerBookTest extends AbstractBusClientServerTestBase {
}
@Test
- public void testBlockAndTrowException() throws Exception {
+ public void testBlockAndThrowException() throws Exception {
String address = "http://localhost:" + PORT + "/bookstore/blockAndThrowException";
WebClient wc = WebClient.create(address);
Response r = wc.get();
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
index 0e039cd..f91733d 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/BookStore.java
@@ -20,7 +20,9 @@
package org.apache.cxf.systest.jaxrs.security.jose;
+import java.util.Collections;
import java.util.List;
+import java.util.Properties;
import javax.ws.rs.Consumes;
import javax.ws.rs.InternalServerErrorException;
@@ -29,6 +31,15 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.apache.cxf.jaxrs.ext.multipart.Multipart;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+import org.apache.cxf.rs.security.jose.jwe.JweDecryptionOutput;
+import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider;
+import org.apache.cxf.rs.security.jose.jwe.JweJsonConsumer;
+import org.apache.cxf.rs.security.jose.jwe.JweUtils;
+import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
+import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
import org.apache.cxf.systest.jaxrs.security.Book;
@Path("/bookstore")
@@ -44,7 +55,7 @@ public class BookStore {
public String echoText(String text) {
return text;
}
-
+
@POST
@Path("/books")
@Produces("application/json")
@@ -86,6 +97,43 @@ public class BookStore {
return books;
}
+ @POST
+ @Path("/books")
+ @Produces({"text/plain"})
+ @Consumes("application/jose+json")
+ public String echoTextJweJsonIn(String jweJson) {
+
+ JweJsonConsumer consumer = new JweJsonConsumer(jweJson);
+
+ // Recipient 1
+ final String recipient1PropLoc = "org/apache/cxf/systest/jaxrs/security/jwejson1.properties";
+ final String recipient1Kid = "AesWrapKey";
+ String recipient1DecryptedText = getRecipientText(consumer, recipient1PropLoc, recipient1Kid);
+
+ // Recipient 2
+ final String recipient2PropLoc = "org/apache/cxf/systest/jaxrs/security/jwejson2.properties";
+ final String recipient2Kid = "AesWrapKey2";
+ String recipient2DecryptedText = getRecipientText(consumer, recipient2PropLoc, recipient2Kid);
+ return recipient1DecryptedText + recipient2DecryptedText;
+ }
+
+ private String getRecipientText(JweJsonConsumer consumer, String recipientPropLoc, String recipientKid) {
+ Message message = JAXRSUtils.getCurrentMessage();
+
+
+ Properties recipientProps = JweUtils.loadJweProperties(message, recipientPropLoc);
+ JsonWebKey recipientKey = JwkUtils.loadJwkSet(message, recipientProps, null).getKey(recipientKid);
+
+ ContentAlgorithm contentEncryptionAlgorithm = JweUtils.getContentEncryptionAlgorithm(recipientProps);
+
+ JweDecryptionProvider jweRecipient =
+ JweUtils.createJweDecryptionProvider(recipientKey, contentEncryptionAlgorithm);
+
+ JweDecryptionOutput jweRecipientOutput =
+ consumer.decryptWith(jweRecipient,
+ Collections.singletonMap("kid", recipientKid));
+ return jweRecipientOutput.getContentText();
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/33eb378e/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJsonTest.java
----------------------------------------------------------------------
diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJsonTest.java b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJsonTest.java
index 6b63f30..332b8c5 100644
--- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJsonTest.java
+++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/jose/jwejws/JAXRSJweJsonTest.java
@@ -21,10 +21,9 @@ package org.apache.cxf.systest.jaxrs.security.jose.jwejws;
import java.net.URL;
import java.security.Security;
-import java.util.Collections;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBusFactory;
@@ -59,24 +58,22 @@ public class JAXRSJweJsonTest extends AbstractBusClientServerTestBase {
}
@Test
- public void testJweJsonPlainTextHmac() throws Exception {
- String address = "https://localhost:" + PORT + "/jwejsonhmac";
+ public void testJweJsonSingleRecipientKeyWrapAndAesCbcHmac() throws Exception {
+ String address = "https://localhost:" + PORT + "/jwejsonkeywrap";
BookStore bs = createBookStore(address,
- "org/apache/cxf/systest/jaxrs/security/secret.jwk.properties",
- null);
+ "org/apache/cxf/systest/jaxrs/security/secret.jwk.properties");
String text = bs.echoText("book");
assertEquals("book", text);
}
-
- private BookStore createBookStore(String address, Object properties,
- List<?> extraProviders) throws Exception {
- return createBookStore(address,
- Collections.singletonMap(JoseConstants.RSSEC_ENCRYPTION_PROPS, properties),
- extraProviders);
+ @Test
+ public void testJweJsonSingleRecipientAesGcmDirect() throws Exception {
+ String address = "https://localhost:" + PORT + "/jwejsondirect";
+ BookStore bs = createBookStore(address,
+ "org/apache/cxf/systest/jaxrs/security/jwe.direct.properties");
+ String text = bs.echoText("book");
+ assertEquals("book", text);
}
- private BookStore createBookStore(String address,
- Map<String, Object> mapProperties,
- List<?> extraProviders) throws Exception {
+ private BookStore createBookStore(String address, String propLoc) throws Exception {
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
SpringBusFactory bf = new SpringBusFactory();
URL busFile = JAXRSJweJsonTest.class.getResource("client.xml");
@@ -88,11 +85,35 @@ public class JAXRSJweJsonTest extends AbstractBusClientServerTestBase {
JweJsonWriterInterceptor writer = new JweJsonWriterInterceptor();
providers.add(writer);
providers.add(new JweJsonClientResponseFilter());
- if (extraProviders != null) {
- providers.addAll(extraProviders);
- }
bean.setProviders(providers);
- bean.getProperties(true).putAll(mapProperties);
+ bean.getProperties(true).put(JoseConstants.RSSEC_ENCRYPTION_PROPS,
+ propLoc);
+ return bean.create(BookStore.class);
+ }
+
+ @Test
+ public void testJweJsontTwoRecipientsKeyWrapAndAesGcm() throws Exception {
+ String address = "https://localhost:" + PORT + "/jwejsonTwoRecipients";
+ BookStore bs = createBookStoreTwoRecipients(address);
+ String text = bs.echoTextJweJsonIn("book");
+ assertEquals("bookbook", text);
+ }
+
+ private BookStore createBookStoreTwoRecipients(String address) throws Exception {
+ JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = JAXRSJweJsonTest.class.getResource("client.xml");
+ Bus springBus = bf.createBus(busFile.toString());
+ bean.setBus(springBus);
+ bean.setServiceClass(BookStore.class);
+ bean.setAddress(address);
+ bean.setProvider(new JweJsonWriterInterceptor());
+
+ List<String> properties = new ArrayList<>();
+ properties.add("org/apache/cxf/systest/jaxrs/security/jwejson1.properties");
+ properties.add("org/apache/cxf/systest/jaxrs/security/jwejson2.properties");
+ bean.getProperties(true).put(JoseConstants.RSSEC_ENCRYPTION_PROPS,
+ properties);
return bean.create(BookStore.class);
}