Repository: cxf Updated Branches: refs/heads/master d292979c5 -> e3c99deff
[CXF-5954] Experimenting with PbeHmacAesWrap JWE with the view of supporting the encryption of JWK sets with the help of password callbacks Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/e3c99def Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/e3c99def Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/e3c99def Branch: refs/heads/master Commit: e3c99deffc0e391a43b27a31b9f951c7993ebc11 Parents: d292979 Author: Sergey Beryozkin <sberyoz...@talend.com> Authored: Fri Sep 12 17:47:15 2014 +0100 Committer: Sergey Beryozkin <sberyoz...@talend.com> Committed: Fri Sep 12 17:47:15 2014 +0100 ---------------------------------------------------------------------- rt/rs/security/oauth-parent/oauth2-jwt/pom.xml | 3 +- .../jwe/AbstractWrapKeyEncryptionAlgorithm.java | 10 +- .../PbesHmacAesWrapKeyEncryptionAlgorithm.java | 151 +++++++++++++++++++ .../cxf/rs/security/oauth2/jwt/Algorithm.java | 7 + .../rs/security/oauth2/jwt/JwtConstants.java | 3 + .../cxf/rs/security/oauth2/jwt/JwtUtils.java | 8 + .../oauth2/jwt/jaxrs/JweWriterInterceptor.java | 6 +- .../oauth2/jwt/jaxrs/JwsWriterInterceptor.java | 6 +- .../oauth2/jwe/JweCompactReaderWriterTest.java | 17 +++ .../oauth2/jwe/JwePbeHmacAesWrapTest.java | 56 +++++++ 10 files changed, 259 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/rt/rs/security/oauth-parent/oauth2-jwt/pom.xml ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/pom.xml b/rt/rs/security/oauth-parent/oauth2-jwt/pom.xml index 5d9d841..aba9eaf 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/pom.xml +++ b/rt/rs/security/oauth-parent/oauth2-jwt/pom.xml @@ -40,7 +40,8 @@ <groupId>org.bouncycastle</groupId> <artifactId>bcprov-ext-jdk15on</artifactId> <version>1.50</version> - <scope>test</scope> + <scope>provided</scope> + <optional>true</optional> </dependency> <!--test dependencies--> <dependency> http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractWrapKeyEncryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractWrapKeyEncryptionAlgorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractWrapKeyEncryptionAlgorithm.java index a689529..0d4cb5f 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractWrapKeyEncryptionAlgorithm.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractWrapKeyEncryptionAlgorithm.java @@ -73,23 +73,23 @@ public abstract class AbstractWrapKeyEncryptionAlgorithm implements KeyEncryptio protected AlgorithmParameterSpec getAlgorithmParameterSpec(JweHeaders headers) { return null; } - private static String checkAlgorithm(Set<String> supportedAlgorithms, String algo) { + protected String checkAlgorithm(String algo) { if (algo != null && !supportedAlgorithms.contains(algo)) { throw new SecurityException(); } return algo; } - private void checkAlgorithms(JweHeaders headers, String defaultAlgo) { + protected void checkAlgorithms(JweHeaders headers, String defaultAlgo) { String providedAlgo = headers.getKeyEncryptionAlgorithm(); if ((providedAlgo == null && defaultAlgo == null) || (providedAlgo != null && defaultAlgo != null && !providedAlgo.equals(defaultAlgo))) { throw new SecurityException(); } if (providedAlgo != null) { - checkAlgorithm(supportedAlgorithms, providedAlgo); - } else { - checkAlgorithms(headers, defaultAlgo); + checkAlgorithm(providedAlgo); + } else if (defaultAlgo != null) { headers.setKeyEncryptionAlgorithm(defaultAlgo); + checkAlgorithm(defaultAlgo); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/PbesHmacAesWrapKeyEncryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/PbesHmacAesWrapKeyEncryptionAlgorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/PbesHmacAesWrapKeyEncryptionAlgorithm.java new file mode 100644 index 0000000..892086e --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/PbesHmacAesWrapKeyEncryptionAlgorithm.java @@ -0,0 +1,151 @@ +/** + * 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.io.UnsupportedEncodingException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; +import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility; +import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.digests.SHA256Digest; +import org.bouncycastle.crypto.digests.SHA384Digest; +import org.bouncycastle.crypto.digests.SHA512Digest; +import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; +import org.bouncycastle.crypto.params.KeyParameter; + +public class PbesHmacAesWrapKeyEncryptionAlgorithm implements KeyEncryptionAlgorithm { + private static final Set<String> SUPPORTED_ALGORITHMS = new HashSet<String>( + Arrays.asList(Algorithm.PBES2_HS256_A128KW.getJwtName(), + Algorithm.PBES2_HS384_A192KW.getJwtName(), + Algorithm.PBES2_HS512_A256KW.getJwtName())); + private static final Map<String, Integer> PBES_HMAC_MAP; + private static final Map<String, String> PBES_AES_MAP; + private static final Map<String, Integer> DERIVED_KEY_SIZE_MAP; + static { + PBES_HMAC_MAP = new HashMap<String, Integer>(); + PBES_HMAC_MAP.put(Algorithm.PBES2_HS256_A128KW.getJwtName(), 256); + PBES_HMAC_MAP.put(Algorithm.PBES2_HS384_A192KW.getJwtName(), 384); + PBES_HMAC_MAP.put(Algorithm.PBES2_HS512_A256KW.getJwtName(), 512); + + PBES_AES_MAP = new HashMap<String, String>(); + PBES_AES_MAP.put(Algorithm.PBES2_HS256_A128KW.getJwtName(), Algorithm.A128KW.getJwtName()); + PBES_AES_MAP.put(Algorithm.PBES2_HS384_A192KW.getJwtName(), Algorithm.A192KW.getJwtName()); + PBES_AES_MAP.put(Algorithm.PBES2_HS512_A256KW.getJwtName(), Algorithm.A256KW.getJwtName()); + + DERIVED_KEY_SIZE_MAP = new HashMap<String, Integer>(); + DERIVED_KEY_SIZE_MAP.put(Algorithm.PBES2_HS256_A128KW.getJwtName(), 16); + DERIVED_KEY_SIZE_MAP.put(Algorithm.PBES2_HS384_A192KW.getJwtName(), 24); + DERIVED_KEY_SIZE_MAP.put(Algorithm.PBES2_HS512_A256KW.getJwtName(), 32); + } + + + private byte[] password; + private int pbesCount; + private String keyAlgoJwt; + public PbesHmacAesWrapKeyEncryptionAlgorithm(String password, String keyAlgoJwt) { + this(stringToBytes(password), keyAlgoJwt); + } + public PbesHmacAesWrapKeyEncryptionAlgorithm(String password, int pbesCount, String keyAlgoJwt) { + this(stringToBytes(password), pbesCount, keyAlgoJwt); + } + public PbesHmacAesWrapKeyEncryptionAlgorithm(byte[] password, String keyAlgoJwt) { + this(password, 4096, keyAlgoJwt); + } + public PbesHmacAesWrapKeyEncryptionAlgorithm(byte[] password, int pbesCount, String keyAlgoJwt) { + this.password = password; + this.keyAlgoJwt = validateKeyAlgorithm(keyAlgoJwt); + this.pbesCount = validatePbesCount(pbesCount); + } + + @Override + public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] cek) { + int keySize = DERIVED_KEY_SIZE_MAP.get(keyAlgoJwt); + byte[] saltInput = createSaltInputValue(keySize); + PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(createShaDigest()); + gen.init(password, saltInput, pbesCount); + byte[] derivedKey = ((KeyParameter) gen.generateDerivedParameters(keySize * 8)).getKey(); + + headers.setHeader("p2s", Base64UrlUtility.encode(saltInput)); + headers.setHeader("p2c", Integer.valueOf(pbesCount)); + + final String aesAlgoJwt = PBES_AES_MAP.get(keyAlgoJwt); + KeyEncryptionAlgorithm aesWrap = new AesWrapKeyEncryptionAlgorithm(derivedKey, aesAlgoJwt) { + protected void checkAlgorithms(JweHeaders headers, String defaultAlgo) { + // complete + } + protected String getKeyEncryptionAlgoJava(JweHeaders headers) { + return Algorithm.AES_WRAP_ALGO_JAVA; + } + }; + return aesWrap.getEncryptedContentEncryptionKey(headers, cek); + + } + + private Digest createShaDigest() { + int macSigSize = PBES_HMAC_MAP.get(keyAlgoJwt); + if (macSigSize == 256) { + return new SHA256Digest(); + } else if (macSigSize == 384) { + return new SHA384Digest(); + } else { + return new SHA512Digest(); + } + + + } + + private byte[] createSaltInputValue(int keySize) { + byte[] algoBytes = stringToBytes(keyAlgoJwt); + + + byte[] saltInput = CryptoUtils.generateSecureRandomBytes(keySize); + byte[] saltValue = new byte[algoBytes.length + 1 + keySize]; + System.arraycopy(algoBytes, 0, saltValue, 0, algoBytes.length); + saltValue[algoBytes.length] = 0; + System.arraycopy(saltInput, 0, saltValue, algoBytes.length + 1, saltInput.length); + return saltValue; + } + private static String validateKeyAlgorithm(String algo) { + if (!SUPPORTED_ALGORITHMS.contains(algo)) { + throw new SecurityException(); + } + return algo; + } + private static int validatePbesCount(int count) { + if (count < 1000) { + throw new SecurityException(); + } + return count; + } + + private static byte[] stringToBytes(String str) { + try { + return str.getBytes("UTF-8"); + } catch (UnsupportedEncodingException ex) { + throw new SecurityException(ex); + } + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java index 1f8fa94..b2d0827 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/Algorithm.java @@ -49,6 +49,10 @@ public enum Algorithm { A128GCMKW(JwtConstants.A128GCMKW_ALGO, "AES/GCM/NoPadding", 128), A192GCMKW(JwtConstants.A192GCMKW_ALGO, "AES/GCM/NoPadding", 192), A256GCMKW(JwtConstants.A256GCMKW_ALGO, "AES/GCM/NoPadding", 256), + PBES2_HS256_A128KW(JwtConstants.PBES2_HS256_A128KW_ALGO, "AESWrap", 128), + PBES2_HS384_A192KW(JwtConstants.PBES2_HS384_A192KW_ALGO, "AESWrap", 192), + PBES2_HS512_A256KW(JwtConstants.PBES2_HS512_A256KW_ALGO, "AESWrap", 256), + // Content Encryption A128GCM(JwtConstants.A128GCM_ALGO, "AES/GCM/NoPadding", 128), A192GCM(JwtConstants.A192GCM_ALGO, "AES/GCM/NoPadding", 192), @@ -124,6 +128,9 @@ public enum Algorithm { JWT_TO_JAVA_NAMES.put(JwtConstants.A128CBC_HS256_ALGO, AES_CBC_ALGO_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.A192CBC_HS384_ALGO, AES_CBC_ALGO_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.A256CBC_HS512_ALGO, AES_CBC_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.PBES2_HS256_A128KW_ALGO, AES_WRAP_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.PBES2_HS384_A192KW_ALGO, AES_WRAP_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.PBES2_HS512_A256KW_ALGO, AES_WRAP_ALGO_JAVA); } private final String jwtName; private final String javaName; http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java index 003d2ec..d0eba30 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtConstants.java @@ -72,6 +72,9 @@ public final class JwtConstants { public static final String A128GCMKW_ALGO = "A128GCMKW"; public static final String A192GCMKW_ALGO = "A192GCMKW"; public static final String A256GCMKW_ALGO = "A256GCMKW"; + public static final String PBES2_HS256_A128KW_ALGO = "PBES2-HS256+A128KW"; + public static final String PBES2_HS384_A192KW_ALGO = "PBES2-HS384+A192KW"; + public static final String PBES2_HS512_A256KW_ALGO = "PBES2-HS512+A256KW"; // Content Encryption public static final String A128CBC_HS256_ALGO = "A128CBC-HS256"; public static final String A192CBC_HS384_ALGO = "A192CBC-HS384"; http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtUtils.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtUtils.java index 61c9544..cbd155e 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtUtils.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/JwtUtils.java @@ -35,4 +35,12 @@ public final class JwtUtils { } return contentType; } + public static String expandContentType(String contentType) { + int paramIndex = contentType.indexOf(';'); + String typeWithoutParams = paramIndex == -1 ? contentType : contentType.substring(0, paramIndex); + if (typeWithoutParams.indexOf('/') == -1) { + contentType = "application/" + contentType; + } + return contentType; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java index a23c74a..73fa72c 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JweWriterInterceptor.java @@ -81,7 +81,11 @@ public class JweWriterInterceptor implements WriterInterceptor { if (contentTypeRequired) { MediaType mt = ctx.getMediaType(); if (mt != null) { - ctString = JAXRSUtils.mediaTypeToString(mt); + if ("application".equals(mt.getType())) { + ctString = mt.getSubtype(); + } else { + ctString = JAXRSUtils.mediaTypeToString(mt); + } } } http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java index 1e7f706..fdbf56b 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java @@ -87,7 +87,11 @@ public class JwsWriterInterceptor extends AbstractJwsWriterProvider implements W if (contentTypeRequired) { MediaType mt = ctx.getMediaType(); if (mt != null) { - headers.setContentType(JAXRSUtils.mediaTypeToString(mt)); + if ("application".equals(mt.getType())) { + headers.setContentType(mt.getSubtype()); + } else { + headers.setContentType(JAXRSUtils.mediaTypeToString(mt)); + } } } } http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/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 f59e602..beed021 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 @@ -205,5 +205,22 @@ public class JweCompactReaderWriterTest extends Assert { } return key; } + + @Test + public void testEncryptDecryptPbesHmacAesWrapA128CBCHS256() throws Exception { + final String specPlainText = "Live long and prosper."; + JweHeaders headers = new JweHeaders(); + headers.setAlgorithm(JwtConstants.PBES2_HS256_A128KW_ALGO); + headers.setContentEncryptionAlgorithm(Algorithm.A128CBC_HS256.getJwtName()); + final String password = "Thus from my lips, by yours, my sin is purged."; + KeyEncryptionAlgorithm keyEncryption = + new PbesHmacAesWrapKeyEncryptionAlgorithm(password, + 4096, + JwtConstants.PBES2_HS256_A128KW_ALGO); + JweEncryptionProvider encryption = new AesCbcHmacJweEncryption(headers, keyEncryption); + String jweContent = encryption.encrypt(specPlainText.getBytes("UTF-8"), null); + + System.out.println(jweContent); + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/e3c99def/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JwePbeHmacAesWrapTest.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JwePbeHmacAesWrapTest.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JwePbeHmacAesWrapTest.java new file mode 100644 index 0000000..9dbd2cf --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/test/java/org/apache/cxf/rs/security/oauth2/jwe/JwePbeHmacAesWrapTest.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.oauth2.jwe; + +import java.security.Security; + +import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; +import org.apache.cxf.rs.security.oauth2.jwt.JwtConstants; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class JwePbeHmacAesWrapTest extends Assert { + @Before + public void registerBouncyCastleIfNeeded() throws Exception { + Security.addProvider(new BouncyCastleProvider()); + } + @After + public void unregisterBouncyCastleIfNeeded() throws Exception { + Security.removeProvider(BouncyCastleProvider.class.getName()); + } + @Test + public void testEncryptDecryptPbesHmacAesWrapA128CBCHS256() throws Exception { + final String specPlainText = "Live long and prosper."; + JweHeaders headers = new JweHeaders(); + headers.setAlgorithm(JwtConstants.PBES2_HS256_A128KW_ALGO); + headers.setContentEncryptionAlgorithm(Algorithm.A128CBC_HS256.getJwtName()); + final String password = "Thus from my lips, by yours, my sin is purged."; + KeyEncryptionAlgorithm keyEncryption = + new PbesHmacAesWrapKeyEncryptionAlgorithm(password, JwtConstants.PBES2_HS256_A128KW_ALGO); + JweEncryptionProvider encryption = new AesCbcHmacJweEncryption(headers, keyEncryption); + String jweContent = encryption.encrypt(specPlainText.getBytes("UTF-8"), null); + assertNotNull(jweContent); + + } +} +