Repository: cxf Updated Branches: refs/heads/master fa37d8722 -> 1b944b5e2
[CXF-5902] Completing AesCbcHmac encryption/decryption test, some cleanup to follow Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/1b944b5e Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/1b944b5e Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/1b944b5e Branch: refs/heads/master Commit: 1b944b5e20fec5032653748c99ca7b287df361fb Parents: fa37d87 Author: Sergey Beryozkin <sberyoz...@talend.com> Authored: Tue Aug 12 16:33:43 2014 +0100 Committer: Sergey Beryozkin <sberyoz...@talend.com> Committed: Tue Aug 12 16:33:43 2014 +0100 ---------------------------------------------------------------------- .../oauth2/jwe/AbstractJweDecryption.java | 25 ++++--- .../oauth2/jwe/AbstractJweEncryption.java | 13 ++-- .../oauth2/jwe/AesCbcHmacJweDecryption.java | 76 ++++++++++++++++++++ .../oauth2/jwe/AesCbcHmacJweEncryption.java | 53 ++++++++------ .../jwe/AesGcmContentDecryptionAlgorithm.java | 8 ++- .../jwe/AesWrapKeyDecryptionAlgorithm.java | 34 +++++++++ .../oauth2/jwe/ContentDecryptionAlgorithm.java | 24 +++++++ .../oauth2/jwe/DirectKeyJweDecryption.java | 2 +- .../security/oauth2/jwe/JweCompactConsumer.java | 22 ++++-- .../rs/security/oauth2/jwe/JweDecryption.java | 26 ------- .../oauth2/jwe/JweDecryptionProvider.java | 26 +++++++ .../oauth2/jwe/WrappedKeyJweDecryption.java | 2 +- .../jwt/jaxrs/AbstractJweDecryptingFilter.java | 10 +-- .../oauth2/jwe/JweCompactReaderWriterTest.java | 14 ++-- 14 files changed, 250 insertions(+), 85 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java index 04bcde6..4d451d2 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryption.java @@ -28,21 +28,21 @@ import org.apache.cxf.rs.security.oauth2.jwt.JwtTokenReaderWriter; import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties; -public abstract class AbstractJweDecryption implements JweDecryption { +public abstract class AbstractJweDecryption implements JweDecryptionProvider { private JweCryptoProperties props; private KeyDecryptionAlgorithm keyDecryptionAlgo; - private ContentEncryptionCipherProperties contentEncryptionProps; + private ContentDecryptionAlgorithm contentDecryptionAlgo; private JwtHeadersReader reader = new JwtTokenReaderWriter(); protected AbstractJweDecryption(JweCryptoProperties props, JwtHeadersReader theReader, KeyDecryptionAlgorithm keyDecryptionAlgo, - ContentEncryptionCipherProperties contentEncryptionProps) { + ContentDecryptionAlgorithm contentDecryptionAlgo) { this.props = props; if (theReader != null) { reader = theReader; } this.keyDecryptionAlgo = keyDecryptionAlgo; - this.contentEncryptionProps = contentEncryptionProps; + this.contentDecryptionAlgo = contentDecryptionAlgo; } protected byte[] getContentEncryptionKey(JweCompactConsumer consumer) { @@ -60,6 +60,9 @@ public abstract class AbstractJweDecryption implements JweDecryption { protected JweDecryptionOutput doDecrypt(JweCompactConsumer consumer) { consumer.enforceJweCryptoProperties(props); byte[] cek = getContentEncryptionKey(consumer); + return doDecrypt(consumer, cek); + } + protected JweDecryptionOutput doDecrypt(JweCompactConsumer consumer, byte[] cek) { KeyProperties keyProperties = new KeyProperties(getContentEncryptionAlgorithm(consumer)); keyProperties.setAdditionalData(getContentEncryptionCipherAAD(consumer)); AlgorithmParameterSpec spec = getContentEncryptionCipherSpec(consumer); @@ -67,7 +70,8 @@ public abstract class AbstractJweDecryption implements JweDecryption { boolean compressionSupported = JwtConstants.DEFLATE_ZIP_ALGORITHM.equals(consumer.getJweHeaders().getZipAlgorithm()); keyProperties.setCompressionSupported(compressionSupported); - Key secretKey = CryptoUtils.createSecretKeySpec(cek, keyProperties.getKeyAlgo()); + byte[] actualCek = getActualCek(cek, consumer.getJweHeaders().getContentEncryptionAlgorithm()); + Key secretKey = CryptoUtils.createSecretKeySpec(actualCek, keyProperties.getKeyAlgo()); byte[] bytes = CryptoUtils.decryptBytes(getEncryptedContentWithAuthTag(consumer), secretKey, keyProperties); return new JweDecryptionOutput(consumer.getJweHeaders(), bytes); @@ -76,16 +80,17 @@ public abstract class AbstractJweDecryption implements JweDecryption { return consumer.getEncryptedContentEncryptionKey(); } protected AlgorithmParameterSpec getContentEncryptionCipherSpec(JweCompactConsumer consumer) { - return contentEncryptionProps.getAlgorithmParameterSpec(getContentEncryptionCipherInitVector(consumer)); + return contentDecryptionAlgo.getAlgorithmParameterSpec(getContentEncryptionCipherInitVector(consumer)); } protected String getContentEncryptionAlgorithm(JweCompactConsumer consumer) { return Algorithm.toJavaName(consumer.getJweHeaders().getContentEncryptionAlgorithm()); } protected byte[] getContentEncryptionCipherAAD(JweCompactConsumer consumer) { - return contentEncryptionProps.getAdditionalAuthenticationData(consumer.getDecodedJsonHeaders()); + return contentDecryptionAlgo.getAdditionalAuthenticationData(consumer.getDecodedJsonHeaders()); } protected byte[] getEncryptedContentWithAuthTag(JweCompactConsumer consumer) { - return consumer.getEncryptedContentWithAuthTag(); + return contentDecryptionAlgo.getEncryptedSequence(consumer.getEncryptedContent(), + getEncryptionAuthenticationTag(consumer)); } protected byte[] getContentEncryptionCipherInitVector(JweCompactConsumer consumer) { return consumer.getContentDecryptionCipherInitVector(); @@ -96,6 +101,8 @@ public abstract class AbstractJweDecryption implements JweDecryption { protected int getEncryptionAuthenticationTagLenBits(JweCompactConsumer consumer) { return getEncryptionAuthenticationTag(consumer).length * 8; } - + protected byte[] getActualCek(byte[] theCek, String algoJwt) { + return theCek; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java index 357a300..167d04e 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java @@ -31,7 +31,7 @@ import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties; public abstract class AbstractJweEncryption implements JweEncryptionProvider { - private static final int DEFAULT_AUTH_TAG_LENGTH = 128; + protected static final int DEFAULT_AUTH_TAG_LENGTH = 128; private JweHeaders headers; private JwtHeadersWriter writer; private ContentEncryptionAlgorithm contentEncryptionAlgo; @@ -80,10 +80,6 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { protected String getContentEncryptionAlgoJava() { return Algorithm.toJavaName(getContentEncryptionAlgoJwt()); } - - protected int getAuthTagLen() { - return DEFAULT_AUTH_TAG_LENGTH; - } protected byte[] getAAD(JweHeaders theHeaders) { return contentEncryptionAlgo.getAdditionalAuthenticationData(writer.headersToJson(theHeaders)); } @@ -103,7 +99,7 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { state.jweContentEncryptionKey, state.theIv, cipher, - getAuthTagLen()); + DEFAULT_AUTH_TAG_LENGTH); } protected JwtHeadersWriter getJwtHeadersWriter() { @@ -128,10 +124,11 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { return null; } protected SecretKey createCekSecretKey(JweEncryptionInternal state) { - return CryptoUtils.createSecretKeySpec(getActualCek(state.secretKey), state.keyProps.getKeyAlgo()); + return CryptoUtils.createSecretKeySpec(getActualCek(state.secretKey, this.getContentEncryptionAlgoJwt()), + state.keyProps.getKeyAlgo()); } - protected byte[] getActualCek(byte[] theCek) { + protected byte[] getActualCek(byte[] theCek, String algoJwt) { return theCek; } http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweDecryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweDecryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweDecryption.java new file mode 100644 index 0000000..5aef222 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweDecryption.java @@ -0,0 +1,76 @@ +/** + * 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.oauth2.jwe; + +import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; + +import javax.crypto.spec.IvParameterSpec; + +import org.apache.cxf.rs.security.oauth2.jwt.JwtHeadersReader; + +public class AesCbcHmacJweDecryption extends AbstractJweDecryption { + public AesCbcHmacJweDecryption(KeyDecryptionAlgorithm keyDecryptionAlgo) { + this(keyDecryptionAlgo, null, null); + } + public AesCbcHmacJweDecryption(KeyDecryptionAlgorithm keyDecryptionAlgo, + JweCryptoProperties props, + JwtHeadersReader reader) { + super(props, reader, keyDecryptionAlgo, new AesCbcContentDecryptionAlgorithm()); + } + protected JweDecryptionOutput doDecrypt(JweCompactConsumer consumer, byte[] cek) { + validateAuthenticationTag(consumer, cek); + return super.doDecrypt(consumer, cek); + } + @Override + protected byte[] getActualCek(byte[] theCek, String algoJwt) { + return AesCbcHmacJweEncryption.doGetActualCek(theCek, algoJwt); + } + protected void validateAuthenticationTag(JweCompactConsumer consumer, byte[] theCek) { + byte[] actualAuthTag = consumer.getEncryptionAuthenticationTag(); + + final AesCbcHmacJweEncryption.MacState macState = + AesCbcHmacJweEncryption.getInitializedMacState(theCek, + consumer.getContentDecryptionCipherInitVector(), + consumer.getJweHeaders(), + consumer.getDecodedJsonHeaders()); + macState.mac.update(consumer.getEncryptedContent()); + byte[] expectedAuthTag = AesCbcHmacJweEncryption.signAndGetTag(macState); + if (!Arrays.equals(actualAuthTag, expectedAuthTag)) { + throw new SecurityException(); + } + + } + private static class AesCbcContentDecryptionAlgorithm extends AbstractContentEncryptionCipherProperties + implements ContentDecryptionAlgorithm { + @Override + public AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) { + return new IvParameterSpec(theIv); + } + @Override + public byte[] getAdditionalAuthenticationData(String headersJson) { + return null; + } + @Override + public byte[] getEncryptedSequence(byte[] cipher, byte[] authTag) { + return cipher; + } + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java index d79452a..0489819 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesCbcHmacJweEncryption.java @@ -69,26 +69,25 @@ public class AesCbcHmacJweEncryption extends AbstractJweEncryption { throw new SecurityException(); } } - - protected byte[] getActualCek(byte[] theCek) { - int size = getCekKeySize() / 2; + @Override + protected byte[] getActualCek(byte[] theCek, String algoJwt) { + return doGetActualCek(theCek, algoJwt); + } + protected static byte[] doGetActualCek(byte[] theCek, String algoJwt) { + int size = getCekKeySize(algoJwt) / 2; byte[] actualCek = new byte[size]; System.arraycopy(theCek, size, actualCek, 0, size); return actualCek; } - protected int getCekKeySize() { - return AES_CEK_SIZE_MAP.get(super.getContentEncryptionAlgoJwt()); + protected static int getCekKeySize(String algoJwt) { + return AES_CEK_SIZE_MAP.get(algoJwt); } protected JweCompactProducer getJweCompactProducer(JweEncryptionInternal state, byte[] cipher) { final MacState macState = getInitializedMacState(state); - macState.mac.update(cipher); - macState.mac.update(macState.al); - byte[] sig = macState.mac.doFinal(); - byte[] authTag = getTagFromSignature(sig); - + byte[] authTag = signAndGetTag(macState); return new JweCompactProducer(macState.headersJson, state.jweContentEncryptionKey, state.theIv, @@ -96,28 +95,38 @@ public class AesCbcHmacJweEncryption extends AbstractJweEncryption { authTag); } - private byte[] getTagFromSignature(byte[] sig) { - int authTagLen = getAuthTagLen() / 8; + protected static byte[] signAndGetTag(MacState macState) { + macState.mac.update(macState.al); + byte[] sig = macState.mac.doFinal(); + + int authTagLen = DEFAULT_AUTH_TAG_LENGTH / 8; byte[] authTag = new byte[authTagLen]; System.arraycopy(sig, 0, authTag, 0, authTagLen); return authTag; } - private MacState getInitializedMacState(final JweEncryptionInternal state) { - int size = getCekKeySize() / 2; + String headersJson = getJwtHeadersWriter().headersToJson(state.theHeaders); + return getInitializedMacState(state.secretKey, state.theIv, state.theHeaders, headersJson); + } + protected static MacState getInitializedMacState(byte[] secretKey, + byte[] theIv, + JweHeaders theHeaders, + String headersJson) { + String algoJwt = theHeaders.getContentEncryptionAlgorithm(); + int size = getCekKeySize(algoJwt) / 2; byte[] macKey = new byte[size]; - System.arraycopy(state.secretKey, 0, macKey, 0, size); + System.arraycopy(secretKey, 0, macKey, 0, size); - String hmacAlgoJava = AES_HMAC_MAP.get(super.getContentEncryptionAlgoJwt()); + String hmacAlgoJava = AES_HMAC_MAP.get(algoJwt); Mac mac = HmacUtils.getInitializedMac(macKey, hmacAlgoJava, null); - String headersJson = getJwtHeadersWriter().headersToJson(state.theHeaders); + byte[] aad = JweHeaders.toCipherAdditionalAuthData(headersJson); ByteBuffer buf = ByteBuffer.allocate(8); final byte[] al = buf.putInt(0).putInt(aad.length * 8).array(); mac.update(aad); - mac.update(state.theIv); + mac.update(theIv); MacState macState = new MacState(); macState.mac = mac; macState.al = al; @@ -138,9 +147,7 @@ public class AesCbcHmacJweEncryption extends AbstractJweEncryption { @Override public byte[] getTag() { - macState.mac.update(macState.al); - byte[] sig = macState.mac.doFinal(); - return getTagFromSignature(sig); + return signAndGetTag(macState); } }; @@ -164,8 +171,8 @@ public class AesCbcHmacJweEncryption extends AbstractJweEncryption { } } - private static class MacState { - private Mac mac; + protected static class MacState { + protected Mac mac; private byte[] al; private String headersJson; } http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java index 9397bd4..7c3f3ca 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesGcmContentDecryptionAlgorithm.java @@ -20,5 +20,11 @@ package org.apache.cxf.rs.security.oauth2.jwe; -public class AesGcmContentDecryptionAlgorithm extends AbstractContentEncryptionCipherProperties { +public class AesGcmContentDecryptionAlgorithm extends AbstractContentEncryptionCipherProperties + implements ContentDecryptionAlgorithm { + + @Override + public byte[] getEncryptedSequence(byte[] cipher, byte[] authTag) { + return JweCompactConsumer.getEncryptedContentWithAuthTag(cipher, authTag); + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyDecryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyDecryptionAlgorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyDecryptionAlgorithm.java new file mode 100644 index 0000000..ec99447 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyDecryptionAlgorithm.java @@ -0,0 +1,34 @@ +/** + * 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.oauth2.jwe; + +import javax.crypto.SecretKey; + +import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; +import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; + +public class AesWrapKeyDecryptionAlgorithm extends WrappedKeyDecryptionAlgorithm { + public AesWrapKeyDecryptionAlgorithm(byte[] secretKey) { + this(CryptoUtils.createSecretKeySpec(secretKey, Algorithm.AES_WRAP_ALGO_JAVA)); + } + public AesWrapKeyDecryptionAlgorithm(SecretKey secretKey) { + super(secretKey, true); + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/ContentDecryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/ContentDecryptionAlgorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/ContentDecryptionAlgorithm.java new file mode 100644 index 0000000..71c20c4 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/ContentDecryptionAlgorithm.java @@ -0,0 +1,24 @@ +/** + * 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.oauth2.jwe; + + +interface ContentDecryptionAlgorithm extends ContentEncryptionCipherProperties { + byte[] getEncryptedSequence(byte[] cipher, byte[] authTag); +} http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java index 9ef9ae1..d76db24 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryption.java @@ -37,7 +37,7 @@ public class DirectKeyJweDecryption extends AbstractJweDecryption { public DirectKeyJweDecryption(Key contentDecryptionKey, JweCryptoProperties props, JwtHeadersReader reader, - ContentEncryptionCipherProperties cipherProps) { + ContentDecryptionAlgorithm cipherProps) { super(props, reader, new DirectKeyDecryptionAlgorithm(contentDecryptionKey), cipherProps); } http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java index 6a1954f..24631ed 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactConsumer.java @@ -31,7 +31,7 @@ public class JweCompactConsumer { private String headersJson; private byte[] encryptedCEK; private byte[] initVector; - private byte[] encryptedContentWithTag; + private byte[] encryptedContent; private byte[] authTag; private JweHeaders jweHeaders; public JweCompactConsumer(String jweContent) { @@ -47,11 +47,8 @@ public class JweCompactConsumer { encryptedCEK = Base64UrlUtility.decode(parts[1]); initVector = Base64UrlUtility.decode(parts[2]); - byte[] cipherText = Base64UrlUtility.decode(parts[3]); + encryptedContent = Base64UrlUtility.decode(parts[3]); authTag = Base64UrlUtility.decode(parts[4]); - encryptedContentWithTag = new byte[cipherText.length + authTag.length]; - System.arraycopy(cipherText, 0, encryptedContentWithTag, 0, cipherText.length); - System.arraycopy(authTag, 0, encryptedContentWithTag, cipherText.length, authTag.length); jweHeaders = new JweHeaders(reader.fromJsonHeaders(headersJson).asMap()); } catch (Base64Exception ex) { throw new SecurityException(ex); @@ -88,14 +85,25 @@ public class JweCompactConsumer { return authTag; } + public byte[] getEncryptedContent() { + return encryptedContent; + } + public byte[] getEncryptedContentWithAuthTag() { + return getEncryptedContentWithAuthTag(encryptedContent, authTag); + } + + public static byte[] getEncryptedContentWithAuthTag(byte[] cipher, byte[] authTag) { + byte[] encryptedContentWithTag = new byte[cipher.length + authTag.length]; + System.arraycopy(cipher, 0, encryptedContentWithTag, 0, cipher.length); + System.arraycopy(authTag, 0, encryptedContentWithTag, cipher.length, authTag.length); return encryptedContentWithTag; } - public byte[] getDecryptedContent(JweDecryption decryption) { + public byte[] getDecryptedContent(JweDecryptionProvider decryption) { return decryption.decrypt(this); } - public String getDecryptedContentText(JweDecryption decryption) { + public String getDecryptedContentText(JweDecryptionProvider decryption) { try { return new String(getDecryptedContent(decryption), "UTF-8"); } catch (UnsupportedEncodingException ex) { http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryption.java deleted file mode 100644 index e910884..0000000 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryption.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * 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.oauth2.jwe; - - - -public interface JweDecryption { - JweDecryptionOutput decrypt(String jweContent); - byte[] decrypt(JweCompactConsumer consumer); -} http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionProvider.java new file mode 100644 index 0000000..ebf2cd8 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionProvider.java @@ -0,0 +1,26 @@ +/** + * 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.oauth2.jwe; + + + +public interface JweDecryptionProvider { + JweDecryptionOutput decrypt(String jweContent); + byte[] decrypt(JweCompactConsumer consumer); +} http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java index 05d1098..45164bf 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryption.java @@ -47,7 +47,7 @@ public class WrappedKeyJweDecryption extends AbstractJweDecryption { } public WrappedKeyJweDecryption(WrappedKeyDecryptionAlgorithm keyDecryptionAlgo, JweCryptoProperties props, JwtHeadersReader reader, - ContentEncryptionCipherProperties cipherProps) { + ContentDecryptionAlgorithm cipherProps) { super(props, reader, keyDecryptionAlgo, cipherProps); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java index 38052cc..d42d7b2 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJweDecryptingFilter.java @@ -25,8 +25,8 @@ import java.security.PrivateKey; import org.apache.cxf.helpers.IOUtils; import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.rs.security.oauth2.jwe.JweCryptoProperties; -import org.apache.cxf.rs.security.oauth2.jwe.JweDecryption; import org.apache.cxf.rs.security.oauth2.jwe.JweDecryptionOutput; +import org.apache.cxf.rs.security.oauth2.jwe.JweDecryptionProvider; import org.apache.cxf.rs.security.oauth2.jwe.JweHeaders; import org.apache.cxf.rs.security.oauth2.jwe.WrappedKeyJweDecryption; import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; @@ -35,11 +35,11 @@ public class AbstractJweDecryptingFilter { private static final String RSSEC_ENCRYPTION_IN_PROPS = "rs.security.encryption.in.properties"; private static final String RSSEC_ENCRYPTION_PROPS = "rs.security.encryption.properties"; - private JweDecryption decryption; + private JweDecryptionProvider decryption; private JweCryptoProperties cryptoProperties; private String defaultMediaType; protected JweDecryptionOutput decrypt(InputStream is) throws IOException { - JweDecryption theDecryptor = getInitializedDecryption(); + JweDecryptionProvider theDecryptor = getInitializedDecryption(); JweDecryptionOutput out = theDecryptor.decrypt(new String(IOUtils.readBytesFromStream(is), "UTF-8")); validateHeaders(out.getHeaders()); return out; @@ -48,10 +48,10 @@ public class AbstractJweDecryptingFilter { protected void validateHeaders(JweHeaders headers) { // complete } - public void setDecryption(JweDecryption decryptor) { + public void setDecryption(JweDecryptionProvider decryptor) { this.decryption = decryptor; } - protected JweDecryption getInitializedDecryption() { + protected JweDecryptionProvider getInitializedDecryption() { if (decryption != null) { return decryption; } http://git-wip-us.apache.org/repos/asf/cxf/blob/1b944b5e/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java index c5d2bce..cd7312b 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactReaderWriterTest.java @@ -99,15 +99,21 @@ public class JweCompactReaderWriterTest extends Assert { headers.setAlgorithm(Algorithm.A128KW.getJwtName()); headers.setContentEncryptionAlgorithm(Algorithm.A128CBC_HS256.getJwtName()); + byte[] cekEncryptionKey = Base64UrlUtility.decode(KEY_ENCRYPTION_KEY_A3); + AesWrapKeyEncryptionAlgorithm keyEncryption = - new AesWrapKeyEncryptionAlgorithm(Base64UrlUtility.decode(KEY_ENCRYPTION_KEY_A3), - Algorithm.A128KW.getJwtName()); + new AesWrapKeyEncryptionAlgorithm(cekEncryptionKey, Algorithm.A128KW.getJwtName()); JweEncryptionProvider encryption = new AesCbcHmacJweEncryption(headers, CONTENT_ENCRYPTION_KEY_A3, INIT_VECTOR_A3, keyEncryption); - String encryptedText = encryption.encrypt(specPlainText.getBytes("UTF-8"), null); - assertEquals(JWE_OUTPUT_A3, encryptedText); + String jweContent = encryption.encrypt(specPlainText.getBytes("UTF-8"), null); + assertEquals(JWE_OUTPUT_A3, jweContent); + + AesWrapKeyDecryptionAlgorithm keyDecryption = new AesWrapKeyDecryptionAlgorithm(cekEncryptionKey); + JweDecryptionProvider decryption = new AesCbcHmacJweDecryption(keyDecryption); + String decryptedText = decryption.decrypt(jweContent).getContentText(); + assertEquals(specPlainText, decryptedText); } @Test