You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2015/10/13 12:42:17 UTC
[17/20] cxf git commit: Splitting current jose module into jose-core
+ jose-jaxrs
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
new file mode 100644
index 0000000..446f039
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/KeyAlgorithm.java
@@ -0,0 +1,78 @@
+/**
+ * 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.jwa;
+
+
+
+
+public enum KeyAlgorithm {
+ RSA_OAEP(AlgorithmUtils.RSA_OAEP_ALGO, "RSA/ECB/OAEPWithSHA-1AndMGF1Padding", -1),
+ RSA_OAEP_256(AlgorithmUtils.RSA_OAEP_256_ALGO, "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", -1),
+ RSA1_5(AlgorithmUtils.RSA1_5_ALGO, "RSA/ECB/PKCS1Padding", -1),
+ A128KW(AlgorithmUtils.A128KW_ALGO, "AESWrap", 128),
+ A192KW(AlgorithmUtils.A192KW_ALGO, "AESWrap", 192),
+ A256KW(AlgorithmUtils.A256KW_ALGO, "AESWrap", 256),
+ A128GCMKW(AlgorithmUtils.A128GCMKW_ALGO, "AES/GCM/NoPadding", 128),
+ A192GCMKW(AlgorithmUtils.A192GCMKW_ALGO, "AES/GCM/NoPadding", 192),
+ A256GCMKW(AlgorithmUtils.A256GCMKW_ALGO, "AES/GCM/NoPadding", 256),
+ PBES2_HS256_A128KW(AlgorithmUtils.PBES2_HS256_A128KW_ALGO, "AESWrap", 128),
+ PBES2_HS384_A192KW(AlgorithmUtils.PBES2_HS384_A192KW_ALGO, "AESWrap", 192),
+ PBES2_HS512_A256KW(AlgorithmUtils.PBES2_HS512_A256KW_ALGO, "AESWrap", 256),
+ ECDH_ES_A128KW(AlgorithmUtils.ECDH_ES_A128KW_ALGO, "AESWrap", 128),
+ ECDH_ES_A192KW(AlgorithmUtils.ECDH_ES_A192KW_ALGO, "AESWrap", 192),
+ ECDH_ES_A256KW(AlgorithmUtils.ECDH_ES_A256KW_ALGO, "AESWrap", 256),
+ ECDH_ES_DIRECT(AlgorithmUtils.ECDH_ES_DIRECT_ALGO, null, -1);
+
+ private final String jwaName;
+ private final String javaName;
+ private final int keySizeBits;
+
+ private KeyAlgorithm(String jwaName, String javaName, int keySizeBits) {
+ this.jwaName = jwaName;
+ this.javaName = javaName;
+ this.keySizeBits = keySizeBits;
+ }
+
+ public String getJwaName() {
+ return jwaName;
+ }
+
+ public String getJavaName() {
+ return javaName == null ? name() : javaName;
+ }
+
+ public String getJavaAlgoName() {
+ return AlgorithmUtils.stripAlgoProperties(getJavaName());
+ }
+
+ public int getKeySizeBits() {
+ return keySizeBits;
+ }
+ public static KeyAlgorithm getAlgorithm(String algo) {
+ if (algo == null) {
+ return null;
+ }
+ return KeyAlgorithm.valueOf(algo.replace('-', '_')
+ .replace('+', '_'));
+
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/SignatureAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/SignatureAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/SignatureAlgorithm.java
new file mode 100644
index 0000000..fe6418a
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/SignatureAlgorithm.java
@@ -0,0 +1,83 @@
+/**
+ * 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.jwa;
+
+
+
+
+public enum SignatureAlgorithm {
+ HS256(AlgorithmUtils.HMAC_SHA_256_ALGO, AlgorithmUtils.HMAC_SHA_256_JAVA, 256),
+ HS384(AlgorithmUtils.HMAC_SHA_384_ALGO, AlgorithmUtils.HMAC_SHA_384_JAVA, 384),
+ HS512(AlgorithmUtils.HMAC_SHA_512_ALGO, AlgorithmUtils.HMAC_SHA_512_JAVA, 512),
+
+ RS256(AlgorithmUtils.RS_SHA_256_ALGO, AlgorithmUtils.RS_SHA_256_JAVA, 256),
+ RS384(AlgorithmUtils.RS_SHA_384_ALGO, AlgorithmUtils.RS_SHA_384_JAVA, 384),
+ RS512(AlgorithmUtils.RS_SHA_512_ALGO, AlgorithmUtils.RS_SHA_512_JAVA, 512),
+
+ PS256(AlgorithmUtils.PS_SHA_256_ALGO, AlgorithmUtils.PS_SHA_256_JAVA, 256),
+ PS384(AlgorithmUtils.PS_SHA_384_ALGO, AlgorithmUtils.PS_SHA_384_JAVA, 384),
+ PS512(AlgorithmUtils.PS_SHA_512_ALGO, AlgorithmUtils.PS_SHA_512_JAVA, 512),
+
+ ES256(AlgorithmUtils.ES_SHA_256_ALGO, AlgorithmUtils.ES_SHA_256_JAVA, 256),
+ ES384(AlgorithmUtils.ES_SHA_384_ALGO, AlgorithmUtils.ES_SHA_384_JAVA, 384),
+ ES512(AlgorithmUtils.ES_SHA_512_ALGO, AlgorithmUtils.ES_SHA_512_JAVA, 512),
+
+ NONE(AlgorithmUtils.NONE_TEXT_ALGO, null, -1);
+
+
+ private final String jwaName;
+ private final String javaName;
+ private final int keySizeBits;
+
+ private SignatureAlgorithm(String jwaName, String javaName, int keySizeBits) {
+ this.jwaName = jwaName;
+ this.javaName = javaName;
+ this.keySizeBits = keySizeBits;
+ }
+
+ public String getJwaName() {
+ return jwaName;
+ }
+
+ public String getJavaName() {
+ return javaName == null ? name() : javaName;
+ }
+
+ public String getJavaAlgoName() {
+ return AlgorithmUtils.stripAlgoProperties(getJavaName());
+ }
+
+ public int getKeySizeBits() {
+ return keySizeBits;
+ }
+
+ public static SignatureAlgorithm getAlgorithm(String algo) {
+ if (algo == null) {
+ return null;
+ }
+ if (AlgorithmUtils.NONE_TEXT_ALGO.equals(algo)) {
+ return NONE;
+ }
+ return SignatureAlgorithm.valueOf(algo.replace('-', '_')
+ .replace('+', '_'));
+
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java
new file mode 100644
index 0000000..355a21b
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java
@@ -0,0 +1,60 @@
+/**
+ * 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.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+
+
+public abstract class AbstractContentEncryptionAlgorithm extends AbstractContentEncryptionCipherProperties
+ implements ContentEncryptionProvider {
+ private static final int DEFAULT_IV_SIZE = 128;
+ private byte[] cek;
+ private byte[] iv;
+ private AtomicInteger providedIvUsageCount;
+
+
+ protected AbstractContentEncryptionAlgorithm(byte[] cek, byte[] iv, ContentAlgorithm algo) {
+ super(algo);
+ this.cek = cek;
+ this.iv = iv;
+ if (iv != null && iv.length > 0) {
+ providedIvUsageCount = new AtomicInteger();
+ }
+ }
+
+ public byte[] getContentEncryptionKey(JweHeaders headers) {
+ return cek;
+ }
+ public byte[] getInitVector() {
+ if (iv == null) {
+ return CryptoUtils.generateSecureRandomBytes(getIvSize() / 8);
+ } else if (iv.length > 0 && providedIvUsageCount.addAndGet(1) > 1) {
+ LOG.warning("Custom IV is recommeded to be used once");
+ throw new JweException(JweException.Error.CUSTOM_IV_REUSED);
+ } else {
+ return iv;
+ }
+ }
+ protected int getIvSize() {
+ return DEFAULT_IV_SIZE;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionCipherProperties.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionCipherProperties.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionCipherProperties.java
new file mode 100644
index 0000000..b683c77
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionCipherProperties.java
@@ -0,0 +1,51 @@
+/**
+ * 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.spec.AlgorithmParameterSpec;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+
+
+public abstract class AbstractContentEncryptionCipherProperties implements ContentEncryptionCipherProperties {
+ protected static final Logger LOG = LogUtils.getL7dLogger(AbstractContentEncryptionCipherProperties.class);
+
+ private static final int DEFAULT_AUTH_TAG_LENGTH = 128;
+ private int authTagLen = DEFAULT_AUTH_TAG_LENGTH;
+ private ContentAlgorithm algo;
+ public AbstractContentEncryptionCipherProperties(ContentAlgorithm algo) {
+ this.algo = algo;
+ }
+ public AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) {
+ return CryptoUtils.getContentEncryptionCipherSpec(getAuthTagLen(), theIv);
+ }
+ public byte[] getAdditionalAuthenticationData(String headersJson, byte[] aad) {
+ return JweUtils.getAdditionalAuthenticationData(headersJson, aad);
+ }
+ protected int getAuthTagLen() {
+ return authTagLen;
+ }
+ @Override
+ public ContentAlgorithm getAlgorithm() {
+ return algo;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
new file mode 100644
index 0000000..1af9424
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweDecryption.java
@@ -0,0 +1,113 @@
+/**
+ * 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;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.rs.security.jose.JoseConstants;
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+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.jws.JwsUtils;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+import org.apache.cxf.rt.security.crypto.KeyProperties;
+
+public abstract class AbstractJweDecryption implements JweDecryptionProvider {
+ protected static final Logger LOG = LogUtils.getL7dLogger(JwsUtils.class);
+
+ private KeyDecryptionProvider keyDecryptionAlgo;
+ private ContentDecryptionProvider contentDecryptionAlgo;
+ protected AbstractJweDecryption(KeyDecryptionProvider keyDecryptionAlgo,
+ ContentDecryptionProvider contentDecryptionAlgo) {
+ this.keyDecryptionAlgo = keyDecryptionAlgo;
+ this.contentDecryptionAlgo = contentDecryptionAlgo;
+ }
+
+ protected byte[] getContentEncryptionKey(JweDecryptionInput jweDecryptionInput) {
+ return keyDecryptionAlgo.getDecryptedContentEncryptionKey(jweDecryptionInput);
+ }
+
+ public JweDecryptionOutput decrypt(String content) {
+ JweCompactConsumer consumer = new JweCompactConsumer(content);
+ byte[] cek = getContentEncryptionKey(consumer.getJweDecryptionInput());
+ return doDecrypt(consumer.getJweDecryptionInput(), cek);
+ }
+ public byte[] decrypt(JweDecryptionInput jweDecryptionInput) {
+ byte[] cek = getContentEncryptionKey(jweDecryptionInput);
+ return doDecrypt(jweDecryptionInput, cek).getContent();
+ }
+ protected JweDecryptionOutput doDecrypt(JweDecryptionInput jweDecryptionInput, byte[] cek) {
+ KeyProperties keyProperties = new KeyProperties(getContentEncryptionAlgorithm(jweDecryptionInput));
+ keyProperties.setAdditionalData(getContentEncryptionCipherAAD(jweDecryptionInput));
+ AlgorithmParameterSpec spec = getContentEncryptionCipherSpec(jweDecryptionInput);
+ keyProperties.setAlgoSpec(spec);
+ boolean compressionSupported =
+ JoseConstants.JWE_DEFLATE_ZIP_ALGORITHM.equals(jweDecryptionInput.getJweHeaders().getZipAlgorithm());
+ keyProperties.setCompressionSupported(compressionSupported);
+ byte[] actualCek = getActualCek(cek,
+ jweDecryptionInput.getJweHeaders().getContentEncryptionAlgorithm().getJwaName());
+ Key secretKey = CryptoUtils.createSecretKeySpec(actualCek, keyProperties.getKeyAlgo());
+ byte[] bytes =
+ CryptoUtils.decryptBytes(getEncryptedContentWithAuthTag(jweDecryptionInput), secretKey, keyProperties);
+ return new JweDecryptionOutput(jweDecryptionInput.getJweHeaders(), bytes);
+ }
+ protected byte[] getEncryptedContentEncryptionKey(JweCompactConsumer consumer) {
+ return consumer.getEncryptedContentEncryptionKey();
+ }
+ protected AlgorithmParameterSpec getContentEncryptionCipherSpec(JweDecryptionInput jweDecryptionInput) {
+ return contentDecryptionAlgo.getAlgorithmParameterSpec(
+ getContentEncryptionCipherInitVector(jweDecryptionInput));
+ }
+ protected String getContentEncryptionAlgorithm(JweDecryptionInput jweDecryptionInput) {
+ return AlgorithmUtils.toJavaName(jweDecryptionInput.getJweHeaders()
+ .getContentEncryptionAlgorithm().getJwaName());
+ }
+ protected byte[] getContentEncryptionCipherAAD(JweDecryptionInput jweDecryptionInput) {
+ return contentDecryptionAlgo.getAdditionalAuthenticationData(
+ jweDecryptionInput.getDecodedJsonHeaders(), jweDecryptionInput.getAad());
+ }
+ protected byte[] getEncryptedContentWithAuthTag(JweDecryptionInput jweDecryptionInput) {
+ return contentDecryptionAlgo.getEncryptedSequence(jweDecryptionInput.getJweHeaders(),
+ jweDecryptionInput.getEncryptedContent(),
+ getEncryptionAuthenticationTag(jweDecryptionInput));
+ }
+ protected byte[] getContentEncryptionCipherInitVector(JweDecryptionInput jweDecryptionInput) {
+ return jweDecryptionInput.getInitVector();
+ }
+ protected byte[] getEncryptionAuthenticationTag(JweDecryptionInput jweDecryptionInput) {
+ return jweDecryptionInput.getAuthTag();
+ }
+ protected int getEncryptionAuthenticationTagLenBits(JweDecryptionInput jweDecryptionInput) {
+ return getEncryptionAuthenticationTag(jweDecryptionInput).length * 8;
+ }
+ protected byte[] getActualCek(byte[] theCek, String algoJwt) {
+ return theCek;
+ }
+ @Override
+ public KeyAlgorithm getKeyAlgorithm() {
+ return keyDecryptionAlgo.getAlgorithm();
+ }
+ @Override
+ public ContentAlgorithm getContentAlgorithm() {
+ return contentDecryptionAlgo.getAlgorithm();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
new file mode 100644
index 0000000..07e60c4
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractJweEncryption.java
@@ -0,0 +1,243 @@
+/**
+ * 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.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.logging.Logger;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.jaxrs.provider.json.JsonMapObjectReaderWriter;
+import org.apache.cxf.rs.security.jose.JoseConstants;
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+import org.apache.cxf.rt.security.crypto.KeyProperties;
+
+public abstract class AbstractJweEncryption implements JweEncryptionProvider {
+ protected static final Logger LOG = LogUtils.getL7dLogger(AbstractJweEncryption.class);
+ protected static final int DEFAULT_AUTH_TAG_LENGTH = 128;
+ private ContentEncryptionProvider contentEncryptionAlgo;
+ private KeyEncryptionProvider keyEncryptionAlgo;
+ private JsonMapObjectReaderWriter writer = new JsonMapObjectReaderWriter();
+ protected AbstractJweEncryption(ContentEncryptionProvider contentEncryptionAlgo,
+ KeyEncryptionProvider keyEncryptionAlgo) {
+ this.keyEncryptionAlgo = keyEncryptionAlgo;
+ this.contentEncryptionAlgo = contentEncryptionAlgo;
+ }
+ protected ContentEncryptionProvider getContentEncryptionAlgorithm() {
+ return contentEncryptionAlgo;
+ }
+ protected AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) {
+ return getContentEncryptionAlgorithm().getAlgorithmParameterSpec(theIv);
+ }
+
+ protected byte[] getContentEncryptionKey(JweHeaders headers) {
+ byte[] cek = getProvidedContentEncryptionKey(headers);
+ if (cek == null) {
+ String algoJava = getContentEncryptionAlgoJava();
+ String algoJwt = getContentEncryptionAlgoJwt();
+ cek = CryptoUtils.getSecretKey(AlgorithmUtils.stripAlgoProperties(algoJava),
+ getCekSize(algoJwt)).getEncoded();
+ }
+ return cek;
+ }
+
+ protected int getCekSize(String algoJwt) {
+ return ContentAlgorithm.valueOf(algoJwt.replace('-', '_')).getKeySizeBits();
+ }
+
+ protected byte[] getProvidedContentEncryptionKey(JweHeaders headers) {
+ return getContentEncryptionAlgorithm().getContentEncryptionKey(headers);
+ }
+
+ protected byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] theCek) {
+ return getKeyEncryptionAlgo().getEncryptedContentEncryptionKey(headers, theCek);
+ }
+
+ protected String getContentEncryptionAlgoJwt() {
+ return getContentEncryptionAlgorithm().getAlgorithm().getJwaName();
+ }
+ protected String getContentEncryptionAlgoJava() {
+ return getContentEncryptionAlgorithm().getAlgorithm().getJavaName();
+ }
+ protected byte[] getAAD(String protectedHeaders, byte[] aad) {
+ return getContentEncryptionAlgorithm().getAdditionalAuthenticationData(protectedHeaders, aad);
+ }
+ @Override
+ public String encrypt(byte[] content, JweHeaders jweHeaders) {
+ JweEncryptionInternal state = getInternalState(jweHeaders, null);
+
+ byte[] encryptedContent = encryptInternal(state, content);
+ byte[] cipher = getActualCipher(encryptedContent);
+ byte[] authTag = getAuthenticationTag(state, encryptedContent);
+ JweCompactProducer producer = new JweCompactProducer(state.protectedHeadersJson,
+ state.jweContentEncryptionKey,
+ state.theIv,
+ cipher,
+ authTag);
+ return producer.getJweContent();
+ }
+ @Override
+ public JweEncryptionOutput getEncryptionOutput(JweEncryptionInput jweInput) {
+ JweEncryptionInternal state = getInternalState(jweInput.getJweHeaders(), jweInput);
+ Cipher c = null;
+ AuthenticationTagProducer authTagProducer = null;
+ byte[] cipher = null;
+ byte[] authTag = null;
+ if (jweInput.getContent() == null) {
+ c = CryptoUtils.initCipher(createCekSecretKey(state), state.keyProps,
+ Cipher.ENCRYPT_MODE);
+ authTagProducer = getAuthenticationTagProducer(state);
+ } else {
+ byte[] encryptedContent = encryptInternal(state, jweInput.getContent());
+ cipher = getActualCipher(encryptedContent);
+ authTag = getAuthenticationTag(state, encryptedContent);
+ }
+ return new JweEncryptionOutput(c,
+ state.theHeaders,
+ state.jweContentEncryptionKey,
+ state.theIv,
+ authTagProducer,
+ state.keyProps,
+ cipher,
+ authTag);
+ }
+ protected byte[] encryptInternal(JweEncryptionInternal state, byte[] content) {
+ try {
+ return CryptoUtils.encryptBytes(content, createCekSecretKey(state), state.keyProps);
+ } catch (SecurityException ex) {
+ if (ex.getCause() instanceof NoSuchAlgorithmException) {
+ LOG.warning("Unsupported algorithm: " + state.keyProps.getKeyAlgo());
+ throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+ }
+ throw new JweException(JweException.Error.CONTENT_ENCRYPTION_FAILURE);
+ }
+ }
+ protected byte[] getActualCipher(byte[] cipher) {
+ return Arrays.copyOf(cipher, cipher.length - DEFAULT_AUTH_TAG_LENGTH / 8);
+ }
+ protected byte[] getAuthenticationTag(JweEncryptionInternal state, byte[] cipher) {
+ return Arrays.copyOfRange(cipher, cipher.length - DEFAULT_AUTH_TAG_LENGTH / 8, cipher.length);
+ }
+ @Override
+ public KeyAlgorithm getKeyAlgorithm() {
+ KeyAlgorithm keyAlgo = getKeyEncryptionAlgo().getAlgorithm();
+ return keyAlgo != null ? keyAlgo : null;
+ }
+ @Override
+ public ContentAlgorithm getContentAlgorithm() {
+ return getContentEncryptionAlgorithm().getAlgorithm();
+ }
+ protected JsonMapObjectReaderWriter getJwtHeadersWriter() {
+ return writer;
+ }
+
+ protected AuthenticationTagProducer getAuthenticationTagProducer(JweEncryptionInternal state) {
+ return null;
+ }
+ protected SecretKey createCekSecretKey(JweEncryptionInternal state) {
+ return CryptoUtils.createSecretKeySpec(getActualCek(state.secretKey, this.getContentEncryptionAlgoJwt()),
+ state.keyProps.getKeyAlgo());
+ }
+
+ protected byte[] getActualCek(byte[] theCek, String algoJwt) {
+ return theCek;
+ }
+
+ private JweEncryptionInternal getInternalState(JweHeaders jweInHeaders, JweEncryptionInput jweInput) {
+ JweHeaders theHeaders = new JweHeaders();
+ if (getKeyAlgorithm() != null) {
+ theHeaders.setKeyEncryptionAlgorithm(getKeyAlgorithm());
+ }
+ theHeaders.setContentEncryptionAlgorithm(getContentEncryptionAlgorithm().getAlgorithm());
+
+ JweHeaders protectedHeaders = null;
+ if (jweInHeaders != null) {
+ if (jweInHeaders.getKeyEncryptionAlgorithm() != null
+ && (getKeyAlgorithm() == null
+ || !getKeyAlgorithm().equals(jweInHeaders.getKeyEncryptionAlgorithm()))) {
+ LOG.warning("Invalid key encryption algorithm");
+ throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+ }
+ if (jweInHeaders.getContentEncryptionAlgorithm() != null
+ && !getContentEncryptionAlgoJwt().equals(jweInHeaders.getContentEncryptionAlgorithm().getJwaName())) {
+ LOG.warning("Invalid content encryption algorithm");
+ throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+ }
+ theHeaders.asMap().putAll(jweInHeaders.asMap());
+ protectedHeaders = jweInHeaders.getProtectedHeaders() != null
+ ? jweInHeaders.getProtectedHeaders() : theHeaders;
+ } else {
+ protectedHeaders = theHeaders;
+ }
+
+
+
+ byte[] theCek = jweInput != null && jweInput.getCek() != null
+ ? jweInput.getCek() : getContentEncryptionKey(theHeaders);
+ String contentEncryptionAlgoJavaName = getContentEncryptionAlgoJava();
+ KeyProperties keyProps = new KeyProperties(contentEncryptionAlgoJavaName);
+ keyProps.setCompressionSupported(compressionRequired(theHeaders));
+
+ byte[] theIv = jweInput != null && jweInput.getIv() != null
+ ? jweInput.getIv() : getContentEncryptionAlgorithm().getInitVector();
+ AlgorithmParameterSpec specParams = getAlgorithmParameterSpec(theIv);
+ keyProps.setAlgoSpec(specParams);
+ byte[] jweContentEncryptionKey =
+ getEncryptedContentEncryptionKey(theHeaders, theCek);
+
+
+ String protectedHeadersJson = writer.toJson(protectedHeaders);
+
+ byte[] additionalEncryptionParam = getAAD(protectedHeadersJson,
+ jweInput == null ? null : jweInput.getAad());
+ keyProps.setAdditionalData(additionalEncryptionParam);
+
+ JweEncryptionInternal state = new JweEncryptionInternal();
+ state.theHeaders = theHeaders;
+ state.jweContentEncryptionKey = jweContentEncryptionKey;
+ state.keyProps = keyProps;
+ state.secretKey = theCek;
+ state.theIv = theIv;
+ state.protectedHeadersJson = protectedHeadersJson;
+ state.aad = jweInput != null ? jweInput.getAad() : null;
+ return state;
+ }
+ private boolean compressionRequired(JweHeaders theHeaders) {
+ return JoseConstants.JWE_DEFLATE_ZIP_ALGORITHM.equals(theHeaders.getZipAlgorithm());
+ }
+ protected KeyEncryptionProvider getKeyEncryptionAlgo() {
+ return keyEncryptionAlgo;
+ }
+ protected static class JweEncryptionInternal {
+ JweHeaders theHeaders;
+ byte[] jweContentEncryptionKey;
+ byte[] theIv;
+ KeyProperties keyProps;
+ byte[] secretKey;
+ String protectedHeadersJson;
+ byte[] aad;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractWrapKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractWrapKeyEncryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractWrapKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..ffb971f
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractWrapKeyEncryptionAlgorithm.java
@@ -0,0 +1,105 @@
+/**
+ * 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;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+import org.apache.cxf.rt.security.crypto.KeyProperties;
+
+public abstract class AbstractWrapKeyEncryptionAlgorithm implements KeyEncryptionProvider {
+ protected static final Logger LOG = LogUtils.getL7dLogger(AbstractWrapKeyEncryptionAlgorithm.class);
+ private Key keyEncryptionKey;
+ private boolean wrap;
+ private KeyAlgorithm algorithm;
+ private Set<String> supportedAlgorithms;
+ protected AbstractWrapKeyEncryptionAlgorithm(Key key, Set<String> supportedAlgorithms) {
+ this(key, null, true, supportedAlgorithms);
+ }
+ protected AbstractWrapKeyEncryptionAlgorithm(Key key, boolean wrap, Set<String> supportedAlgorithms) {
+ this(key, null, wrap, supportedAlgorithms);
+ }
+ protected AbstractWrapKeyEncryptionAlgorithm(Key key, KeyAlgorithm jweAlgo, Set<String> supportedAlgorithms) {
+ this(key, jweAlgo, true, supportedAlgorithms);
+ }
+ protected AbstractWrapKeyEncryptionAlgorithm(Key key, KeyAlgorithm jweAlgo, boolean wrap,
+ Set<String> supportedAlgorithms) {
+ this.keyEncryptionKey = key;
+ this.algorithm = jweAlgo;
+ this.wrap = wrap;
+ this.supportedAlgorithms = supportedAlgorithms;
+ }
+ @Override
+ public KeyAlgorithm getAlgorithm() {
+ return algorithm;
+ }
+ @Override
+ public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] cek) {
+ checkAlgorithms(headers);
+ KeyProperties secretKeyProperties = new KeyProperties(getKeyEncryptionAlgoJava(headers));
+ AlgorithmParameterSpec spec = getAlgorithmParameterSpec(headers);
+ if (spec != null) {
+ secretKeyProperties.setAlgoSpec(spec);
+ }
+ if (!wrap) {
+ return CryptoUtils.encryptBytes(cek, keyEncryptionKey, secretKeyProperties);
+ } else {
+ return CryptoUtils.wrapSecretKey(cek,
+ getContentEncryptionAlgoJava(headers),
+ keyEncryptionKey,
+ secretKeyProperties);
+ }
+ }
+ protected String getKeyEncryptionAlgoJava(JweHeaders headers) {
+ return AlgorithmUtils.toJavaName(headers.getKeyEncryptionAlgorithm().getJwaName());
+ }
+ protected String getContentEncryptionAlgoJava(JweHeaders headers) {
+ return AlgorithmUtils.toJavaName(headers.getContentEncryptionAlgorithm().getJwaName());
+ }
+ protected AlgorithmParameterSpec getAlgorithmParameterSpec(JweHeaders headers) {
+ return null;
+ }
+ protected String checkAlgorithm(String algo) {
+ if (algo != null && !supportedAlgorithms.contains(algo)) {
+ LOG.warning("Invalid key encryption algorithm: " + algo);
+ throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+ }
+ return algo;
+ }
+ protected void checkAlgorithms(JweHeaders headers) {
+ KeyAlgorithm providedAlgo = headers.getKeyEncryptionAlgorithm();
+ if (providedAlgo != null && !providedAlgo.equals(algorithm)) {
+ LOG.warning("Invalid key encryption algorithm: " + providedAlgo);
+ throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+ }
+ if (providedAlgo != null) {
+ checkAlgorithm(providedAlgo.getJwaName());
+ } else {
+ checkAlgorithm(algorithm.getJwaName());
+ headers.setKeyEncryptionAlgorithm(algorithm);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweDecryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweDecryption.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweDecryption.java
new file mode 100644
index 0000000..e713ff0
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweDecryption.java
@@ -0,0 +1,91 @@
+/**
+ * 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.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+
+import javax.crypto.spec.IvParameterSpec;
+
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+
+public class AesCbcHmacJweDecryption extends JweDecryption {
+ private String supportedAlgo;
+ public AesCbcHmacJweDecryption(KeyDecryptionProvider keyDecryptionAlgo) {
+ this(keyDecryptionAlgo, null);
+ }
+ public AesCbcHmacJweDecryption(KeyDecryptionProvider keyDecryptionAlgo,
+ ContentAlgorithm supportedAlgo) {
+ super(keyDecryptionAlgo, new AesCbcContentDecryptionAlgorithm(supportedAlgo));
+ this.supportedAlgo = supportedAlgo == null ? null : supportedAlgo.getJwaName();
+ }
+ protected JweDecryptionOutput doDecrypt(JweDecryptionInput jweDecryptionInput, byte[] cek) {
+ validateAuthenticationTag(jweDecryptionInput, cek);
+ return super.doDecrypt(jweDecryptionInput, cek);
+ }
+ @Override
+ protected byte[] getActualCek(byte[] theCek, String algoJwt) {
+ validateCekAlgorithm(algoJwt);
+ return AesCbcHmacJweEncryption.doGetActualCek(theCek, algoJwt);
+ }
+ protected void validateAuthenticationTag(JweDecryptionInput jweDecryptionInput, byte[] theCek) {
+ byte[] actualAuthTag = jweDecryptionInput.getAuthTag();
+
+ final AesCbcHmacJweEncryption.MacState macState =
+ AesCbcHmacJweEncryption.getInitializedMacState(theCek,
+ jweDecryptionInput.getInitVector(),
+ jweDecryptionInput.getAad(),
+ jweDecryptionInput.getJweHeaders(),
+ jweDecryptionInput.getDecodedJsonHeaders());
+ macState.mac.update(jweDecryptionInput.getEncryptedContent());
+ byte[] expectedAuthTag = AesCbcHmacJweEncryption.signAndGetTag(macState);
+ if (!Arrays.equals(actualAuthTag, expectedAuthTag)) {
+ LOG.warning("Invalid authentication tag");
+ throw new JweException(JweException.Error.CONTENT_DECRYPTION_FAILURE);
+ }
+
+ }
+ private static class AesCbcContentDecryptionAlgorithm extends AbstractContentEncryptionCipherProperties
+ implements ContentDecryptionProvider {
+ public AesCbcContentDecryptionAlgorithm(ContentAlgorithm supportedAlgo) {
+ super(supportedAlgo);
+ }
+ @Override
+ public AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) {
+ return new IvParameterSpec(theIv);
+ }
+ @Override
+ public byte[] getAdditionalAuthenticationData(String headersJson, byte[] aad) {
+ return null;
+ }
+ @Override
+ public byte[] getEncryptedSequence(JweHeaders headers, byte[] cipher, byte[] authTag) {
+ return cipher;
+ }
+ }
+ private String validateCekAlgorithm(String cekAlgo) {
+ if (!AlgorithmUtils.isAesCbcHmac(cekAlgo)
+ || supportedAlgo != null && !supportedAlgo.equals(cekAlgo)) {
+ LOG.warning("Invalid content encryption algorithm");
+ throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+ }
+ return cekAlgo;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweEncryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweEncryption.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweEncryption.java
new file mode 100644
index 0000000..80a8630
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesCbcHmacJweEncryption.java
@@ -0,0 +1,175 @@
+/**
+ * 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.nio.ByteBuffer;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.IvParameterSpec;
+
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+import org.apache.cxf.rt.security.crypto.HmacUtils;
+
+public class AesCbcHmacJweEncryption extends JweEncryption {
+ private static final Map<String, String> AES_HMAC_MAP;
+ private static final Map<String, Integer> AES_CEK_SIZE_MAP;
+ static {
+ AES_HMAC_MAP = new HashMap<String, String>();
+ AES_HMAC_MAP.put(ContentAlgorithm.A128CBC_HS256.getJwaName(), AlgorithmUtils.HMAC_SHA_256_JAVA);
+ AES_HMAC_MAP.put(ContentAlgorithm.A192CBC_HS384.getJwaName(), AlgorithmUtils.HMAC_SHA_384_JAVA);
+ AES_HMAC_MAP.put(ContentAlgorithm.A256CBC_HS512.getJwaName(), AlgorithmUtils.HMAC_SHA_512_JAVA);
+
+ AES_CEK_SIZE_MAP = new HashMap<String, Integer>();
+ AES_CEK_SIZE_MAP.put(ContentAlgorithm.A128CBC_HS256.getJwaName(), 32);
+ AES_CEK_SIZE_MAP.put(ContentAlgorithm.A192CBC_HS384.getJwaName(), 48);
+ AES_CEK_SIZE_MAP.put(ContentAlgorithm.A256CBC_HS512.getJwaName(), 64);
+ }
+ public AesCbcHmacJweEncryption(String cekAlgo,
+ KeyEncryptionProvider keyEncryptionAlgorithm) {
+ this(ContentAlgorithm.getAlgorithm(cekAlgo), keyEncryptionAlgorithm);
+ }
+ public AesCbcHmacJweEncryption(ContentAlgorithm cekAlgoJwt,
+ KeyEncryptionProvider keyEncryptionAlgorithm) {
+ this(cekAlgoJwt, null, null, keyEncryptionAlgorithm);
+ }
+ public AesCbcHmacJweEncryption(ContentAlgorithm cekAlgoJwt, byte[] cek,
+ byte[] iv, KeyEncryptionProvider keyEncryptionAlgorithm) {
+ super(keyEncryptionAlgorithm,
+ new AesCbcContentEncryptionAlgorithm(cek, iv,
+ validateCekAlgorithm(cekAlgoJwt)));
+
+ }
+ @Override
+ protected byte[] getActualCek(byte[] theCek, String algoJwt) {
+ return doGetActualCek(theCek, algoJwt);
+ }
+ @Override
+ protected int getCekSize(String algoJwt) {
+ return getFullCekKeySize(algoJwt) * 8;
+ }
+ protected static byte[] doGetActualCek(byte[] theCek, String algoJwt) {
+ int size = getFullCekKeySize(algoJwt) / 2;
+ byte[] actualCek = new byte[size];
+ System.arraycopy(theCek, size, actualCek, 0, size);
+ return actualCek;
+ }
+
+ protected static int getFullCekKeySize(String algoJwt) {
+ return AES_CEK_SIZE_MAP.get(algoJwt);
+ }
+ protected byte[] getActualCipher(byte[] cipher) {
+ return cipher;
+ }
+ protected byte[] getAuthenticationTag(JweEncryptionInternal state, byte[] cipher) {
+ final MacState macState = getInitializedMacState(state);
+ macState.mac.update(cipher);
+ return signAndGetTag(macState);
+ }
+
+ 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) {
+ return getInitializedMacState(state.secretKey, state.theIv, state.aad,
+ state.theHeaders, state.protectedHeadersJson);
+ }
+ protected static MacState getInitializedMacState(byte[] secretKey,
+ byte[] theIv,
+ byte[] extraAad,
+ JweHeaders theHeaders,
+ String protectedHeadersJson) {
+ String algoJwt = theHeaders.getContentEncryptionAlgorithm().getJwaName();
+ int size = getFullCekKeySize(algoJwt) / 2;
+ byte[] macKey = new byte[size];
+ System.arraycopy(secretKey, 0, macKey, 0, size);
+
+ String hmacAlgoJava = AES_HMAC_MAP.get(algoJwt);
+ Mac mac = HmacUtils.getInitializedMac(macKey, hmacAlgoJava, null);
+
+ byte[] aad = JweUtils.getAdditionalAuthenticationData(protectedHeadersJson, extraAad);
+ ByteBuffer buf = ByteBuffer.allocate(8);
+ final byte[] al = buf.putInt(0).putInt(aad.length * 8).array();
+
+ mac.update(aad);
+ mac.update(theIv);
+ MacState macState = new MacState();
+ macState.mac = mac;
+ macState.al = al;
+ return macState;
+ }
+
+ protected AuthenticationTagProducer getAuthenticationTagProducer(final JweEncryptionInternal state) {
+ final MacState macState = getInitializedMacState(state);
+
+
+ return new AuthenticationTagProducer() {
+
+ @Override
+ public void update(byte[] cipher, int off, int len) {
+ macState.mac.update(cipher, off, len);
+ }
+
+ @Override
+ public byte[] getTag() {
+ return signAndGetTag(macState);
+ }
+ };
+ }
+ @Override
+ protected byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] theCek) {
+ return getKeyEncryptionAlgo().getEncryptedContentEncryptionKey(headers, theCek);
+ }
+
+ private static class AesCbcContentEncryptionAlgorithm extends AbstractContentEncryptionAlgorithm {
+ public AesCbcContentEncryptionAlgorithm(byte[] cek, byte[] iv, ContentAlgorithm algo) {
+ super(cek, iv, algo);
+ }
+ @Override
+ public AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) {
+ return new IvParameterSpec(theIv);
+ }
+ @Override
+ public byte[] getAdditionalAuthenticationData(String headersJson, byte[] aad) {
+ return null;
+ }
+ }
+
+ protected static class MacState {
+ protected Mac mac;
+ private byte[] al;
+ }
+
+ private static ContentAlgorithm validateCekAlgorithm(ContentAlgorithm cekAlgo) {
+ if (!AlgorithmUtils.isAesCbcHmac(cekAlgo.getJwaName())) {
+ LOG.warning("Invalid content encryption algorithm");
+ throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+ }
+ return cekAlgo;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentDecryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentDecryptionAlgorithm.java
new file mode 100644
index 0000000..64206b7
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentDecryptionAlgorithm.java
@@ -0,0 +1,41 @@
+/**
+ * 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 org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+
+
+
+public class AesGcmContentDecryptionAlgorithm extends AbstractContentEncryptionCipherProperties
+ implements ContentDecryptionProvider {
+ public AesGcmContentDecryptionAlgorithm(ContentAlgorithm supportedAlgo) {
+ super(supportedAlgo);
+ }
+
+ @Override
+ public byte[] getEncryptedSequence(JweHeaders headers, byte[] cipher, byte[] authTag) {
+ String algo = headers.getContentEncryptionAlgorithm().getJwaName();
+ if (!AlgorithmUtils.isAesGcm(algo) || !getAlgorithm().getJwaName().equals(algo)) {
+ LOG.warning("Invalid content encryption algorithm");
+ throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+ }
+ return JweCompactConsumer.getCipherWithAuthTag(cipher, authTag);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentEncryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentEncryptionAlgorithm.java
new file mode 100644
index 0000000..4f87829
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmContentEncryptionAlgorithm.java
@@ -0,0 +1,55 @@
+/**
+ * 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 javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+
+
+public class AesGcmContentEncryptionAlgorithm extends AbstractContentEncryptionAlgorithm {
+ private static final int DEFAULT_IV_SIZE = 96;
+ public AesGcmContentEncryptionAlgorithm(ContentAlgorithm algo) {
+ this((byte[])null, null, algo);
+ }
+ public AesGcmContentEncryptionAlgorithm(String encodedCek, String encodedIv, ContentAlgorithm algo) {
+ this((byte[])CryptoUtils.decodeSequence(encodedCek), CryptoUtils.decodeSequence(encodedIv), algo);
+ }
+ public AesGcmContentEncryptionAlgorithm(String encodedCek, ContentAlgorithm algo) {
+ this((byte[])CryptoUtils.decodeSequence(encodedCek), null, algo);
+ }
+ public AesGcmContentEncryptionAlgorithm(SecretKey key, byte[] iv, ContentAlgorithm algo) {
+ this(key.getEncoded(), iv, algo);
+ }
+ public AesGcmContentEncryptionAlgorithm(byte[] cek, byte[] iv, ContentAlgorithm algo) {
+ super(cek, iv, checkAlgorithm(algo));
+ }
+ protected int getIvSize() {
+ return DEFAULT_IV_SIZE;
+ }
+ private static ContentAlgorithm checkAlgorithm(ContentAlgorithm algo) {
+ if (AlgorithmUtils.isAesGcm(algo.getJwaName())) {
+ return algo;
+ }
+ LOG.warning("Invalid content encryption algorithm");
+ throw new JweException(JweException.Error.INVALID_CONTENT_ALGORITHM);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyDecryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..dda527e
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyDecryptionAlgorithm.java
@@ -0,0 +1,78 @@
+/**
+ * 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.spec.AlgorithmParameterSpec;
+import java.util.logging.Logger;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.rs.security.jose.JoseException;
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+
+public class AesGcmWrapKeyDecryptionAlgorithm extends WrappedKeyDecryptionAlgorithm {
+ protected static final Logger LOG = LogUtils.getL7dLogger(AesGcmWrapKeyDecryptionAlgorithm.class);
+ public AesGcmWrapKeyDecryptionAlgorithm(String encodedKey) {
+ this(encodedKey, null);
+ }
+ public AesGcmWrapKeyDecryptionAlgorithm(String encodedKey, KeyAlgorithm supportedAlgo) {
+ this(CryptoUtils.decodeSequence(encodedKey), supportedAlgo);
+ }
+ public AesGcmWrapKeyDecryptionAlgorithm(byte[] secretKey) {
+ this(secretKey, KeyAlgorithm.A128GCMKW);
+ }
+ public AesGcmWrapKeyDecryptionAlgorithm(byte[] secretKey, KeyAlgorithm supportedAlgo) {
+ this(CryptoUtils.createSecretKeySpec(secretKey, AlgorithmUtils.AES), supportedAlgo);
+ }
+ public AesGcmWrapKeyDecryptionAlgorithm(SecretKey secretKey) {
+ this(secretKey, null);
+ }
+ public AesGcmWrapKeyDecryptionAlgorithm(SecretKey secretKey, KeyAlgorithm supportedAlgo) {
+ super(secretKey, supportedAlgo);
+ }
+ @Override
+ protected byte[] getEncryptedContentEncryptionKey(JweDecryptionInput jweDecryptionInput) {
+ byte[] encryptedCekKey = super.getEncryptedContentEncryptionKey(jweDecryptionInput);
+ byte[] tag = getDecodedBytes(jweDecryptionInput, "tag");
+ return JweCompactConsumer.getCipherWithAuthTag(encryptedCekKey, tag);
+ }
+ protected AlgorithmParameterSpec getAlgorithmParameterSpec(JweDecryptionInput jweDecryptionInput) {
+ byte[] iv = getDecodedBytes(jweDecryptionInput, "iv");
+ return CryptoUtils.getContentEncryptionCipherSpec(128, iv);
+ }
+ private byte[] getDecodedBytes(JweDecryptionInput jweDecryptionInput, String headerName) {
+ try {
+ Object ivHeader = jweDecryptionInput.getJweHeaders().getHeader(headerName);
+ return Base64UrlUtility.decode(ivHeader.toString());
+ } catch (Exception ex) {
+ throw new JoseException(ex);
+ }
+ }
+ protected void validateKeyEncryptionAlgorithm(String keyAlgo) {
+ super.validateKeyEncryptionAlgorithm(keyAlgo);
+ if (!AlgorithmUtils.isAesGcmKeyWrap(keyAlgo)) {
+ LOG.warning("Invalid key encryption algorithm");
+ throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyEncryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..6349b7d
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesGcmWrapKeyEncryptionAlgorithm.java
@@ -0,0 +1,65 @@
+/**
+ * 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.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.common.util.Base64UrlUtility;
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+
+public class AesGcmWrapKeyEncryptionAlgorithm extends AbstractWrapKeyEncryptionAlgorithm {
+ private static final Set<String> SUPPORTED_ALGORITHMS = new HashSet<String>(
+ Arrays.asList(KeyAlgorithm.A128GCMKW.getJwaName(),
+ KeyAlgorithm.A192GCMKW.getJwaName(),
+ KeyAlgorithm.A256GCMKW.getJwaName()));
+ public AesGcmWrapKeyEncryptionAlgorithm(String encodedKey, KeyAlgorithm keyAlgoJwt) {
+ this(CryptoUtils.decodeSequence(encodedKey), keyAlgoJwt);
+ }
+ public AesGcmWrapKeyEncryptionAlgorithm(byte[] keyBytes, KeyAlgorithm keyAlgoJwt) {
+ this(CryptoUtils.createSecretKeySpec(keyBytes, AlgorithmUtils.AES),
+ keyAlgoJwt);
+ }
+ public AesGcmWrapKeyEncryptionAlgorithm(SecretKey key, KeyAlgorithm keyAlgoJwt) {
+ super(key, keyAlgoJwt, true, SUPPORTED_ALGORITHMS);
+ }
+
+ @Override
+ public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] cek) {
+ byte[] wrappedKeyAndTag = super.getEncryptedContentEncryptionKey(headers, cek);
+ byte[] wrappedKey = new byte[wrappedKeyAndTag.length - 128 / 8];
+ System.arraycopy(wrappedKeyAndTag, 0, wrappedKey, 0, wrappedKeyAndTag.length - 128 / 8);
+ String encodedTag = Base64UrlUtility.encodeChunk(wrappedKeyAndTag,
+ wrappedKeyAndTag.length - 128 / 8, 128 / 8);
+ headers.setHeader("tag", encodedTag);
+ return wrappedKey;
+ }
+ protected AlgorithmParameterSpec getAlgorithmParameterSpec(JweHeaders headers) {
+ byte[] iv = CryptoUtils.generateSecureRandomBytes(96 / 8);
+ String encodedIv = Base64UrlUtility.encode(iv);
+ headers.setHeader("iv", encodedIv);
+ return CryptoUtils.getContentEncryptionCipherSpec(128, iv);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyDecryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..11350a2
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyDecryptionAlgorithm.java
@@ -0,0 +1,59 @@
+/**
+ * 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 javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+
+public class AesWrapKeyDecryptionAlgorithm extends WrappedKeyDecryptionAlgorithm {
+ public AesWrapKeyDecryptionAlgorithm(String encodedKey) {
+ this(encodedKey, KeyAlgorithm.A128KW);
+ }
+ public AesWrapKeyDecryptionAlgorithm(String encodedKey, KeyAlgorithm supportedAlgo) {
+ this(CryptoUtils.decodeSequence(encodedKey), supportedAlgo);
+ }
+ public AesWrapKeyDecryptionAlgorithm(byte[] secretKey) {
+ this(secretKey, KeyAlgorithm.A128KW);
+ }
+ public AesWrapKeyDecryptionAlgorithm(byte[] secretKey, KeyAlgorithm supportedAlgo) {
+ this(CryptoUtils.createSecretKeySpec(secretKey, AlgorithmUtils.AES_WRAP_ALGO_JAVA),
+ supportedAlgo);
+ }
+ public AesWrapKeyDecryptionAlgorithm(SecretKey secretKey) {
+ this(secretKey, null);
+ }
+ public AesWrapKeyDecryptionAlgorithm(SecretKey secretKey, KeyAlgorithm supportedAlgo) {
+ super(secretKey, supportedAlgo);
+ }
+ @Override
+ protected void validateKeyEncryptionAlgorithm(String keyAlgo) {
+ super.validateKeyEncryptionAlgorithm(keyAlgo);
+ if (!isValidAlgorithmFamily(keyAlgo)) {
+ reportInvalidKeyAlgorithm(keyAlgo);
+ }
+ }
+
+ protected boolean isValidAlgorithmFamily(String keyAlgo) {
+ return AlgorithmUtils.isAesKeyWrap(keyAlgo);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyEncryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..3fe85e3
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AesWrapKeyEncryptionAlgorithm.java
@@ -0,0 +1,48 @@
+/**
+ * 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.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.crypto.SecretKey;
+
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+
+public class AesWrapKeyEncryptionAlgorithm extends AbstractWrapKeyEncryptionAlgorithm {
+ private static final Set<String> SUPPORTED_ALGORITHMS = new HashSet<String>(
+ Arrays.asList(KeyAlgorithm.A128KW.getJwaName(),
+ KeyAlgorithm.A192KW.getJwaName(),
+ KeyAlgorithm.A256KW.getJwaName()));
+ public AesWrapKeyEncryptionAlgorithm(String encodedKey, KeyAlgorithm keyAlgoJwt) {
+ this(CryptoUtils.decodeSequence(encodedKey), keyAlgoJwt);
+ }
+ public AesWrapKeyEncryptionAlgorithm(byte[] keyBytes, KeyAlgorithm keyAlgoJwt) {
+ this(CryptoUtils.createSecretKeySpec(keyBytes, keyAlgoJwt.getJavaName()),
+ keyAlgoJwt);
+ }
+ public AesWrapKeyEncryptionAlgorithm(SecretKey key, KeyAlgorithm keyAlgoJwt) {
+ super(key, keyAlgoJwt, SUPPORTED_ALGORITHMS);
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AuthenticationTagProducer.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AuthenticationTagProducer.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AuthenticationTagProducer.java
new file mode 100644
index 0000000..897e68c
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/AuthenticationTagProducer.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.jose.jwe;
+
+public interface AuthenticationTagProducer {
+ void update(byte[] cipher, int off, int len);
+ byte[] getTag();
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentDecryptionProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentDecryptionProvider.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentDecryptionProvider.java
new file mode 100644
index 0000000..6c79019
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentDecryptionProvider.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.jose.jwe;
+
+
+public interface ContentDecryptionProvider extends ContentEncryptionCipherProperties {
+ byte[] getEncryptedSequence(JweHeaders headers, byte[] cipher, byte[] authTag);
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
new file mode 100644
index 0000000..055d602
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionCipherProperties.java
@@ -0,0 +1,30 @@
+/**
+ * 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.spec.AlgorithmParameterSpec;
+
+import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm;
+
+
+public interface ContentEncryptionCipherProperties {
+ ContentAlgorithm getAlgorithm();
+ byte[] getAdditionalAuthenticationData(String headersJson, byte[] aad);
+ AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] iv);
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionProvider.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionProvider.java
new file mode 100644
index 0000000..940455a
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/ContentEncryptionProvider.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.jose.jwe;
+
+
+
+public interface ContentEncryptionProvider extends ContentEncryptionCipherProperties {
+ byte[] getInitVector();
+ byte[] getContentEncryptionKey(JweHeaders headers);
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..3883dcd
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyDecryptionAlgorithm.java
@@ -0,0 +1,56 @@
+/**
+ * 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;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+import org.apache.cxf.rt.security.crypto.CryptoUtils;
+
+public class DirectKeyDecryptionAlgorithm implements KeyDecryptionProvider {
+ private static final Logger LOG = LogUtils.getL7dLogger(DirectKeyDecryptionAlgorithm.class);
+ private byte[] contentDecryptionKey;
+ public DirectKeyDecryptionAlgorithm(Key contentDecryptionKey) {
+ this(contentDecryptionKey.getEncoded());
+ }
+ public DirectKeyDecryptionAlgorithm(String encodedContentDecryptionKey) {
+ this(CryptoUtils.decodeSequence(encodedContentDecryptionKey));
+ }
+ public DirectKeyDecryptionAlgorithm(byte[] contentDecryptionKey) {
+ this.contentDecryptionKey = contentDecryptionKey;
+ }
+ @Override
+ public byte[] getDecryptedContentEncryptionKey(JweDecryptionInput jweDecryptionInput) {
+ validateKeyEncryptionKey(jweDecryptionInput);
+ return contentDecryptionKey;
+ }
+ @Override
+ public KeyAlgorithm getAlgorithm() {
+ return null;
+ }
+ protected void validateKeyEncryptionKey(JweDecryptionInput jweDecryptionInput) {
+ byte[] encryptedCEK = jweDecryptionInput.getEncryptedCEK();
+ if (encryptedCEK != null && encryptedCEK.length > 0) {
+ LOG.warning("Unexpected content encryption key");
+ throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
new file mode 100644
index 0000000..2f038a9
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyEncryptionAlgorithm.java
@@ -0,0 +1,42 @@
+/**
+ * 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.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+
+public class DirectKeyEncryptionAlgorithm implements KeyEncryptionProvider {
+ private static final Logger LOG = LogUtils.getL7dLogger(DirectKeyEncryptionAlgorithm.class);
+ public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] theCek) {
+ checkKeyEncryptionAlgorithm(headers);
+ return new byte[0];
+ }
+ protected void checkKeyEncryptionAlgorithm(JweHeaders headers) {
+ if (headers.getKeyEncryptionAlgorithm() != null) {
+ LOG.warning("Key encryption algorithm header is set");
+ throw new JweException(JweException.Error.INVALID_KEY_ALGORITHM);
+ }
+ }
+ @Override
+ public KeyAlgorithm getAlgorithm() {
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
new file mode 100644
index 0000000..7434acf
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweDecryption.java
@@ -0,0 +1,32 @@
+/**
+ * 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 DirectKeyJweDecryption extends JweDecryption {
+ public DirectKeyJweDecryption(String encodedKey, ContentDecryptionProvider ctAlgo) {
+ super(new DirectKeyDecryptionAlgorithm(encodedKey),
+ ctAlgo);
+ }
+ public DirectKeyJweDecryption(byte[] key, ContentDecryptionProvider ctAlgo) {
+ super(new DirectKeyDecryptionAlgorithm(key),
+ ctAlgo);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
new file mode 100644
index 0000000..3c83466
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/DirectKeyJweEncryption.java
@@ -0,0 +1,27 @@
+/**
+ * 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 DirectKeyJweEncryption extends JweEncryption {
+ public DirectKeyJweEncryption(ContentEncryptionProvider contentEncryptionAlgo) {
+ super(new DirectKeyEncryptionAlgorithm(), contentEncryptionAlgo);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/5e40ea35/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhAesWrapKeyDecryptionAlgorithm.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhAesWrapKeyDecryptionAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhAesWrapKeyDecryptionAlgorithm.java
new file mode 100644
index 0000000..4860904
--- /dev/null
+++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwe/EcdhAesWrapKeyDecryptionAlgorithm.java
@@ -0,0 +1,54 @@
+/**
+ * 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.interfaces.ECPrivateKey;
+
+import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
+import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm;
+
+public class EcdhAesWrapKeyDecryptionAlgorithm implements KeyDecryptionProvider {
+ private ECPrivateKey key;
+ private KeyAlgorithm algo;
+ public EcdhAesWrapKeyDecryptionAlgorithm(ECPrivateKey key) {
+ this(key, KeyAlgorithm.ECDH_ES_A128KW);
+ }
+ public EcdhAesWrapKeyDecryptionAlgorithm(ECPrivateKey key, KeyAlgorithm algo) {
+ this.key = key;
+ this.algo = algo;
+ }
+ @Override
+ public byte[] getDecryptedContentEncryptionKey(JweDecryptionInput jweDecryptionInput) {
+ byte[] derivedKey =
+ EcdhDirectKeyJweDecryption.getDecryptedContentEncryptionKeyFromHeaders(
+ jweDecryptionInput.getJweHeaders(), key);
+ KeyDecryptionProvider aesWrap = new AesWrapKeyDecryptionAlgorithm(derivedKey) {
+ protected boolean isValidAlgorithmFamily(String wrapAlgo) {
+ return AlgorithmUtils.isEcdhEsWrap(wrapAlgo);
+ }
+ };
+ return aesWrap.getDecryptedContentEncryptionKey(jweDecryptionInput);
+ }
+
+ @Override
+ public KeyAlgorithm getAlgorithm() {
+ return algo;
+ }
+
+}