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 2015/02/16 16:28:30 UTC
cxf git commit: [CXF-6085] Adding direct key producer tests
Repository: cxf
Updated Branches:
refs/heads/master 60e023348 -> 52b83045b
[CXF-6085] Adding direct key producer tests
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/52b83045
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/52b83045
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/52b83045
Branch: refs/heads/master
Commit: 52b83045b6f7298117e9a66758c07fc9f1fba3af
Parents: 60e0233
Author: Sergey Beryozkin <sb...@talend.com>
Authored: Mon Feb 16 15:28:08 2015 +0000
Committer: Sergey Beryozkin <sb...@talend.com>
Committed: Mon Feb 16 15:28:08 2015 +0000
----------------------------------------------------------------------
.../jose/jwe/AbstractJweEncryption.java | 2 +-
.../jose/jwe/DirectKeyDecryptionAlgorithm.java | 46 +++++++++++++
.../jose/jwe/DirectKeyEncryptionAlgorithm.java | 37 +++++++++++
.../jose/jwe/DirectKeyJweDecryption.java | 25 +------
.../jose/jwe/DirectKeyJweEncryption.java | 18 +----
.../rs/security/jose/jwe/JweJsonProducer.java | 22 ++++--
.../cxf/rs/security/jose/jwe/JweUtils.java | 8 +--
.../security/jose/jwe/JweJsonProducerTest.java | 70 +++++++++++++++++++-
8 files changed, 173 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/52b83045/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
index 18fdc5c..6f47018 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
@@ -163,7 +163,7 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider {
if (jweInHeaders.getKeyEncryptionAlgorithm() != null
&& (getKeyAlgorithm() == null
|| !getKeyAlgorithm().equals(jweInHeaders.getKeyEncryptionAlgorithm()))
- || jweInHeaders.getAlgorithm() != null
+ || jweInHeaders.getContentEncryptionAlgorithm() != null
&& !getContentAlgorithm().equals(jweInHeaders.getContentEncryptionAlgorithm())) {
throw new SecurityException();
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/52b83045/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..f7cfcc1
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.jose.jwe;
+
+import java.security.Key;
+
+public class DirectKeyDecryptionAlgorithm implements KeyDecryptionAlgorithm {
+ private byte[] contentDecryptionKey;
+ public DirectKeyDecryptionAlgorithm(Key contentDecryptionKey) {
+ this(contentDecryptionKey.getEncoded());
+ }
+ public DirectKeyDecryptionAlgorithm(byte[] contentDecryptionKey) {
+ this.contentDecryptionKey = contentDecryptionKey;
+ }
+ @Override
+ public byte[] getDecryptedContentEncryptionKey(JweDecryptionInput jweDecryptionInput) {
+ validateKeyEncryptionKey(jweDecryptionInput);
+ return contentDecryptionKey;
+ }
+ @Override
+ public String getAlgorithm() {
+ return null;
+ }
+ protected void validateKeyEncryptionKey(JweDecryptionInput jweDecryptionInput) {
+ byte[] encryptedCEK = jweDecryptionInput.getEncryptedCEK();
+ if (encryptedCEK != null && encryptedCEK.length > 0) {
+ throw new SecurityException();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/52b83045/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..3fe8967
--- /dev/null
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.rs.security.jose.jwe;
+
+public class DirectKeyEncryptionAlgorithm implements KeyEncryptionAlgorithm {
+ public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] theCek) {
+ if (headers.getKeyEncryptionAlgorithm() != null) {
+ throw new SecurityException();
+ }
+ return new byte[0];
+ }
+ protected void checkKeyEncryptionAlgorithm(JweHeaders headers) {
+ if (headers.getKeyEncryptionAlgorithm() != null) {
+ throw new SecurityException();
+ }
+ }
+ @Override
+ public String getAlgorithm() {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/52b83045/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
index 576cdaa..6a98e46 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
@@ -30,28 +30,5 @@ public class DirectKeyJweDecryption extends AbstractJweDecryption {
ContentDecryptionAlgorithm cipherProps) {
super(direct, cipherProps);
}
- protected static class DirectKeyDecryptionAlgorithm implements KeyDecryptionAlgorithm {
- private byte[] contentDecryptionKey;
- public DirectKeyDecryptionAlgorithm(Key contentDecryptionKey) {
- this(contentDecryptionKey.getEncoded());
- }
- public DirectKeyDecryptionAlgorithm(byte[] contentDecryptionKey) {
- this.contentDecryptionKey = contentDecryptionKey;
- }
- @Override
- public byte[] getDecryptedContentEncryptionKey(JweDecryptionInput jweDecryptionInput) {
- validateKeyEncryptionKey(jweDecryptionInput);
- return contentDecryptionKey;
- }
- @Override
- public String getAlgorithm() {
- return null;
- }
- protected void validateKeyEncryptionKey(JweDecryptionInput jweDecryptionInput) {
- byte[] encryptedCEK = jweDecryptionInput.getEncryptedCEK();
- if (encryptedCEK != null && encryptedCEK.length > 0) {
- throw new SecurityException();
- }
- }
- }
+
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/52b83045/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
index 0017689..5a951e1 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
@@ -40,21 +40,5 @@ public class DirectKeyJweEncryption extends AbstractJweEncryption {
}
return cek;
}
- protected static class DirectKeyEncryptionAlgorithm implements KeyEncryptionAlgorithm {
- public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] theCek) {
- if (headers.getKeyEncryptionAlgorithm() != null) {
- throw new SecurityException();
- }
- return new byte[0];
- }
- protected void checkKeyEncryptionAlgorithm(JweHeaders headers) {
- if (headers.getKeyEncryptionAlgorithm() != null) {
- throw new SecurityException();
- }
- }
- @Override
- public String getAlgorithm() {
- return null;
- }
- }
+
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/52b83045/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
index 3dcd1e7..45d3d47 100644
--- a/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
+++ b/rt/rs/security/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducer.java
@@ -27,6 +27,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.rs.security.jose.JoseConstants;
import org.apache.cxf.rs.security.jose.JoseHeadersReaderWriter;
public class JweJsonProducer {
@@ -82,6 +83,7 @@ public class JweJsonProducer {
unprotectedHeader.asMap().keySet())) {
throw new SecurityException("Protected and unprotected headers have duplicate values");
}
+ checkCriticalHeaders(unprotectedHeader);
unionHeaders.asMap().putAll(unprotectedHeader.asMap());
}
@@ -95,13 +97,14 @@ public class JweJsonProducer {
JweHeaders perRecipientUnprotected =
recipientUnprotected == null ? null : recipientUnprotected.get(i);
JweHeaders jsonHeaders = null;
- if (recipientUnprotected != null) {
+ if (perRecipientUnprotected != null) {
+ checkCriticalHeaders(perRecipientUnprotected);
if (!Collections.disjoint(unionHeaders.asMap().keySet(),
perRecipientUnprotected.asMap().keySet())) {
throw new SecurityException("Protected and unprotected headers have duplicate values");
}
jsonHeaders = new JweHeaders(unionHeaders.asMap());
- jsonHeaders.asMap().putAll(unprotectedHeader.asMap());
+ jsonHeaders.asMap().putAll(perRecipientUnprotected.asMap());
} else {
jsonHeaders = unionHeaders;
}
@@ -126,11 +129,11 @@ public class JweJsonProducer {
}
byte[] encryptedCek = state.getContentEncryptionKey();
- if (encryptedCek == null && encryptor.getKeyAlgorithm() != null) {
+ if (encryptedCek.length == 0 && encryptor.getKeyAlgorithm() != null) {
// can be null only if it is the direct key encryption
throw new SecurityException();
}
- String encodedCek = encryptedCek == null ? null : Base64UrlUtility.encode(encryptedCek);
+ String encodedCek = encryptedCek.length == 0 ? null : Base64UrlUtility.encode(encryptedCek);
entries.add(new JweJsonEncryptionEntry(perRecipientUnprotected, encodedCek));
}
@@ -146,7 +149,10 @@ public class JweJsonProducer {
if (unprotectedEntryHeader != null) {
jweJsonMap.put("header", unprotectedEntryHeader);
}
- jweJsonMap.put("encrypted_key", entries.get(0).getEncodedEncryptedKey());
+ String encryptedKey = entries.get(0).getEncodedEncryptedKey();
+ if (encryptedKey != null) {
+ jweJsonMap.put("encrypted_key", encryptedKey);
+ }
} else {
jweJsonMap.put("recipients", entries);
}
@@ -171,5 +177,9 @@ public class JweJsonProducer {
}
return set.iterator().next();
}
-
+ private static void checkCriticalHeaders(JweHeaders unprotected) {
+ if (unprotected.asMap().containsKey(JoseConstants.HEADER_CRITICAL)) {
+ throw new SecurityException();
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/52b83045/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 a28c859..950efdf 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
@@ -488,10 +488,10 @@ public final class JweUtils {
JweHeaders headers = new JweHeaders();
if (keyEncryptionAlgo != null) {
headers.setAlgorithm(keyEncryptionAlgo);
- headers.setContentEncryptionAlgorithm(contentEncryptionAlgo);
- if (compression != null) {
- headers.setZipAlgorithm(compression);
- }
+ }
+ headers.setContentEncryptionAlgorithm(contentEncryptionAlgo);
+ if (compression != null) {
+ headers.setZipAlgorithm(compression);
}
return headers;
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/52b83045/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducerTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducerTest.java b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducerTest.java
index 0d85d24..0eb8480 100644
--- a/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducerTest.java
+++ b/rt/rs/security/jose/src/test/java/org/apache/cxf/rs/security/jose/jwe/JweJsonProducerTest.java
@@ -60,6 +60,24 @@ public class JweJsonProducerTest extends Assert {
+ "\"ciphertext\":\"KTuJBMk9QG59xPB-c_YLM5-J7VG40_eMPvyHDD7eB-WHj_34YiWgpBOydTBm4RW0zUCJZ09xqorhWJME-DcQ\","
+ "\"tag\":\"GxWlwvTPmHi4ZnQgafiHew\""
+ "}";
+ private static final String SINGLE_RECIPIENT_DIRECT_OUTPUT =
+ "{"
+ + "\"protected\":\"eyJlbmMiOiJBMTI4R0NNIn0\","
+ + "\"recipients\":"
+ + "["
+ + "{}"
+ + "],"
+ + "\"iv\":\"48V1_ALb6US04U3b\","
+ + "\"ciphertext\":\"KTuJBMk9QG59xPB-c_YLM5-J7VG40_eMPvyHDD7eB-WHj_34YiWgpBOydTBm4RW0zUCJZ09xqorhWJME-DcQ\","
+ + "\"tag\":\"Te59ApbK8wNBDY_1_dgYSw\""
+ + "}";
+ private static final String SINGLE_RECIPIENT_DIRECT_FLAT_OUTPUT =
+ "{"
+ + "\"protected\":\"eyJlbmMiOiJBMTI4R0NNIn0\","
+ + "\"iv\":\"48V1_ALb6US04U3b\","
+ + "\"ciphertext\":\"KTuJBMk9QG59xPB-c_YLM5-J7VG40_eMPvyHDD7eB-WHj_34YiWgpBOydTBm4RW0zUCJZ09xqorhWJME-DcQ\","
+ + "\"tag\":\"Te59ApbK8wNBDY_1_dgYSw\""
+ + "}";
private static final String SINGLE_RECIPIENT_ALL_HEADERS_AAD_OUTPUT =
"{"
+ "\"protected\":\"eyJlbmMiOiJBMTI4R0NNIn0\","
@@ -117,6 +135,17 @@ public class JweJsonProducerTest extends Assert {
+ "\"ciphertext\":\"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY\","
+ "\"tag\":\"U0m_YmjN04DJvceFICbCVQ\""
+ "}";
+ private static final String SINGLE_RECIPIENT_A128CBCHS256_DIRECT_OUTPUT =
+ "{"
+ + "\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\","
+ + "\"recipients\":"
+ + "["
+ + "{}"
+ + "],"
+ + "\"iv\":\"AxY8DCtDaGlsbGljb3RoZQ\","
+ + "\"ciphertext\":\"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY\","
+ + "\"tag\":\"Mz-VPPyU4RlcuYv1IwIvzw\""
+ + "}";
@BeforeClass
public static void registerBouncyCastleIfNeeded() throws Exception {
try {
@@ -139,6 +168,20 @@ public class JweJsonProducerTest extends Assert {
CEK_BYTES, false);
}
@Test
+ public void testSingleRecipientDirectGcm() throws Exception {
+ final String text = "The true sign of intelligence is not knowledge but imagination.";
+ doTestSingleRecipient(text, SINGLE_RECIPIENT_DIRECT_OUTPUT, JoseConstants.A128GCM_ALGO,
+ null, JweCompactReaderWriterTest.INIT_VECTOR_A1,
+ CEK_BYTES, false);
+ }
+ @Test
+ public void testSingleRecipientDirectFlatGcm() throws Exception {
+ final String text = "The true sign of intelligence is not knowledge but imagination.";
+ doTestSingleRecipient(text, SINGLE_RECIPIENT_DIRECT_FLAT_OUTPUT, JoseConstants.A128GCM_ALGO,
+ null, JweCompactReaderWriterTest.INIT_VECTOR_A1,
+ CEK_BYTES, true);
+ }
+ @Test
public void testSingleRecipientFlatGcm() throws Exception {
final String text = "The true sign of intelligence is not knowledge but imagination.";
doTestSingleRecipient(text, SINGLE_RECIPIENT_FLAT_OUTPUT, JoseConstants.A128GCM_ALGO,
@@ -154,18 +197,39 @@ public class JweJsonProducerTest extends Assert {
JweCompactReaderWriterTest.CONTENT_ENCRYPTION_KEY_A3,
false);
}
+ @Test
+ public void testSingleRecipientDirectA128CBCHS256() throws Exception {
+ String text = "Live long and prosper.";
+ doTestSingleRecipient(text, SINGLE_RECIPIENT_A128CBCHS256_DIRECT_OUTPUT, JoseConstants.A128CBC_HS256_ALGO,
+ null,
+ JweCompactReaderWriterTest.INIT_VECTOR_A3,
+ JweCompactReaderWriterTest.CONTENT_ENCRYPTION_KEY_A3,
+ false);
+ }
private String doTestSingleRecipient(String text,
String expectedOutput,
String contentEncryptionAlgo,
- byte[] wrapperKeyBytes,
+ final byte[] wrapperKeyBytes,
final byte[] iv,
final byte[] cek,
boolean canBeFlat) throws Exception {
- SecretKey wrapperKey = CryptoUtils.createSecretKeySpec(wrapperKeyBytes, "AES");
JweHeaders headers = new JweHeaders(JoseConstants.A128KW_ALGO,
contentEncryptionAlgo);
- JweEncryptionProvider jwe = JweUtils.createJweEncryptionProvider(wrapperKey, headers);
+ JweEncryptionProvider jwe = null;
+ if (wrapperKeyBytes == null) {
+ headers.asMap().remove("alg");
+ if (Algorithm.isAesCbcHmac(contentEncryptionAlgo)) {
+ jwe = JweUtils.createJweEncryptionProvider(new DirectKeyEncryptionAlgorithm(),
+ contentEncryptionAlgo, null);
+ } else {
+ SecretKey cekKey = CryptoUtils.createSecretKeySpec(cek, "AES");
+ jwe = JweUtils.getDirectKeyJweEncryption(cekKey, JoseConstants.A128GCM_ALGO);
+ }
+ } else {
+ SecretKey wrapperKey = CryptoUtils.createSecretKeySpec(wrapperKeyBytes, "AES");
+ jwe = JweUtils.createJweEncryptionProvider(wrapperKey, headers);
+ }
JweJsonProducer p = new JweJsonProducer(headers, StringUtils.toBytesUTF8(text), canBeFlat) {
protected JweEncryptionInput createEncryptionInput(JweHeaders jsonHeaders) {
JweEncryptionInput input = super.createEncryptionInput(jsonHeaders);