Repository: cxf Updated Branches: refs/heads/master 42131e0c8 -> 9899753a5
[CXF-5902] Refactoring Jwe helpers to better support diffent key encryption algorithms, more to follow Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/9899753a Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/9899753a Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/9899753a Branch: refs/heads/master Commit: 9899753a56993bc5c4b1da8048d8a120580e4a6e Parents: 42131e0 Author: Sergey Beryozkin <[email protected]> Authored: Tue Jul 29 18:24:13 2014 +0300 Committer: Sergey Beryozkin <[email protected]> Committed: Tue Jul 29 18:24:13 2014 +0300 ---------------------------------------------------------------------- .../oauth2/jwe/AbstractJweEncryption.java | 51 ++++++----- .../oauth2/jwe/AbstractWrapKeyEncryption.java | 95 ++++++++++++++++++++ .../oauth2/jwe/AesWrapKeyEncryption.java | 45 ++++++++++ .../oauth2/jwe/DirectKeyEncryption.java | 29 ++++++ .../oauth2/jwe/DirectKeyJweEncryption.java | 7 +- .../rs/security/oauth2/jwe/JweEncryption.java | 60 ------------- .../oauth2/jwe/JweEncryptionProvider.java | 2 +- .../security/oauth2/jwe/JweEncryptionState.java | 60 +++++++++++++ .../cxf/rs/security/oauth2/jwe/JweHeaders.java | 4 + .../oauth2/jwe/KeyEncryptionAlgorithm.java | 24 +++++ .../security/oauth2/jwe/RSAJweEncryption.java | 50 +++++------ .../oauth2/jwe/RSAOaepKeyEncryption.java | 45 ++++++++++ .../oauth2/jwe/WrappedKeyJweEncryption.java | 44 +++------ .../cxf/rs/security/oauth2/jwt/Algorithm.java | 6 ++ .../jwt/jaxrs/AbstractJwsWriterProvider.java | 4 + .../oauth2/jwt/jaxrs/JweWriterInterceptor.java | 15 ++-- .../oauth2/jwe/JweCompactReaderWriterTest.java | 17 ++-- .../oauth2/utils/crypto/CryptoUtils.java | 4 +- .../systest/jaxrs/security/alice.rs.properties | 1 + .../systest/jaxrs/security/bob.rs.properties | 1 + 20 files changed, 404 insertions(+), 160 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java index 871bfd8..e8728c7 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryption.java @@ -35,38 +35,47 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { protected static final int DEFAULT_IV_SIZE = 96; protected static final int DEFAULT_AUTH_TAG_LENGTH = 128; private JweHeaders headers; - private JwtHeadersWriter writer = new JwtTokenReaderWriter(); + private JwtHeadersWriter writer; private byte[] cek; private byte[] iv; private AtomicInteger providedIvUsageCount; - private int authTagLen = DEFAULT_AUTH_TAG_LENGTH; + private int authTagLen; + private KeyEncryptionAlgorithm keyEncryptionAlgo; - protected AbstractJweEncryption(SecretKey cek, byte[] iv) { + protected AbstractJweEncryption(SecretKey cek, byte[] iv, KeyEncryptionAlgorithm keyEncryptionAlgo) { this(new JweHeaders(Algorithm.toJwtName(cek.getAlgorithm(), cek.getEncoded().length * 8)), - cek.getEncoded(), iv); + cek.getEncoded(), iv, keyEncryptionAlgo); } - protected AbstractJweEncryption(JweHeaders headers, byte[] cek, byte[] iv) { + protected AbstractJweEncryption(JweHeaders headers, byte[] cek, byte[] iv, + KeyEncryptionAlgorithm keyEncryptionAlgo) { + this(headers, cek, iv, DEFAULT_AUTH_TAG_LENGTH, keyEncryptionAlgo); + } + protected AbstractJweEncryption(JweHeaders headers, byte[] cek, byte[] iv, int authTagLen, + KeyEncryptionAlgorithm keyEncryptionAlgo) { + this(headers, cek, iv, DEFAULT_AUTH_TAG_LENGTH, keyEncryptionAlgo, null); + } + protected AbstractJweEncryption(JweHeaders headers, KeyEncryptionAlgorithm keyEncryptionAlgo) { + this(headers, null, null, DEFAULT_AUTH_TAG_LENGTH, keyEncryptionAlgo, null); + } + protected AbstractJweEncryption(JweHeaders headers, + byte[] cek, + byte[] iv, + int authTagLen, + KeyEncryptionAlgorithm keyEncryptionAlgo, + JwtHeadersWriter writer) { this.headers = headers; this.cek = cek; this.iv = iv; if (iv != null && iv.length > 0) { providedIvUsageCount = new AtomicInteger(); } - } - protected AbstractJweEncryption(JweHeaders headers, byte[] cek, byte[] iv, int authTagLen) { - this(headers, cek, iv); this.authTagLen = authTagLen; - } - protected AbstractJweEncryption(JweHeaders headers) { - this.headers = headers; - } - protected AbstractJweEncryption(JweHeaders headers, byte[] cek, byte[] iv, int authTagLen, - JwtHeadersWriter writer) { - this(headers, cek, iv, authTagLen); - if (writer != null) { - this.writer = writer; + this.writer = writer; + if (this.writer == null) { + this.writer = new JwtTokenReaderWriter(); } + this.keyEncryptionAlgo = keyEncryptionAlgo; } protected AlgorithmParameterSpec getContentEncryptionCipherSpec(byte[] theIv) { @@ -87,7 +96,9 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { return cek; } - protected abstract byte[] getEncryptedContentEncryptionKey(byte[] theCek); + protected byte[] getEncryptedContentEncryptionKey(byte[] theCek) { + return keyEncryptionAlgo.getEncryptedContentEncryptionKey(headers, theCek); + } protected String getContentEncryptionAlgoJwt() { return headers.getContentEncryptionAlgorithm(); @@ -121,11 +132,11 @@ public abstract class AbstractJweEncryption implements JweEncryptionProvider { } @Override - public JweEncryption createJweEncryption(String contentType) { + public JweEncryptionState createJweEncryptionState(String contentType) { JweEncryptionInternal state = getInternalState(contentType); Cipher c = CryptoUtils.initCipher(state.secretKey, state.keyProps, Cipher.ENCRYPT_MODE); - return new JweEncryption(c, getAuthTagLen(), state.theHeaders, state.jweContentEncryptionKey, + return new JweEncryptionState(c, getAuthTagLen(), state.theHeaders, state.jweContentEncryptionKey, state.theIv, state.keyProps.isCompressionSupported()); } http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractWrapKeyEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractWrapKeyEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractWrapKeyEncryption.java new file mode 100644 index 0000000..8ab04c5 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractWrapKeyEncryption.java @@ -0,0 +1,95 @@ +/** + * 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.Key; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Set; + +import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; +import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; +import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties; + +public abstract class AbstractWrapKeyEncryption implements KeyEncryptionAlgorithm { + private Key keyEncryptionKey; + private boolean wrap; + private String algorithm; + private Set<String> supportedAlgorithms; + protected AbstractWrapKeyEncryption(Key key, Set<String> supportedAlgorithms) { + this(key, null, true, supportedAlgorithms); + } + protected AbstractWrapKeyEncryption(Key key, boolean wrap, Set<String> supportedAlgorithms) { + this(key, null, wrap, supportedAlgorithms); + } + protected AbstractWrapKeyEncryption(Key key, String jweAlgo, Set<String> supportedAlgorithms) { + this(key, jweAlgo, true, supportedAlgorithms); + } + protected AbstractWrapKeyEncryption(Key key, String jweAlgo, boolean wrap, Set<String> supportedAlgorithms) { + this.keyEncryptionKey = key; + this.algorithm = jweAlgo; + this.wrap = wrap; + this.supportedAlgorithms = supportedAlgorithms; + } + @Override + public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] cek) { + checkAlgorithms(headers, algorithm); + KeyProperties secretKeyProperties = new KeyProperties(getKeyEncryptionAlgoJava(headers)); + AlgorithmParameterSpec spec = getAlgorithmParameterSpec(); + 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 Algorithm.toJavaName(headers.getKeyEncryptionAlgorithm()); + } + protected String getContentEncryptionAlgoJava(JweHeaders headers) { + return Algorithm.toJavaName(headers.getContentEncryptionAlgorithm()); + } + protected AlgorithmParameterSpec getAlgorithmParameterSpec() { + return null; + } + private static String checkAlgorithm(Set<String> supportedAlgorithms, String algo) { + if (algo != null && !supportedAlgorithms.contains(algo)) { + throw new SecurityException(); + } + return algo; + } + private 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); + headers.setKeyEncryptionAlgorithm(defaultAlgo); + } + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyEncryption.java new file mode 100644 index 0000000..ec4aa87 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AesWrapKeyEncryption.java @@ -0,0 +1,45 @@ +/** + * 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.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import javax.crypto.SecretKey; + +import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; +import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; + +public class AesWrapKeyEncryption extends AbstractWrapKeyEncryption { + private static final Set<String> SUPPORTED_ALGORITHMS = new HashSet<String>( + Arrays.asList(Algorithm.A128KW.getJwtName(), + Algorithm.A192KW.getJwtName(), + Algorithm.A256KW.getJwtName())); + public AesWrapKeyEncryption(byte[] keyBytes, String keyAlgoJwt) { + this(CryptoUtils.createSecretKeySpec(keyBytes, Algorithm.toJavaName(keyAlgoJwt)), + keyAlgoJwt); + } + public AesWrapKeyEncryption(SecretKey key, String keyAlgoJwt) { + super(key, keyAlgoJwt, SUPPORTED_ALGORITHMS); + } + + + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyEncryption.java new file mode 100644 index 0000000..b81cbb3 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyEncryption.java @@ -0,0 +1,29 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.jwe; + + +public class DirectKeyEncryption implements KeyEncryptionAlgorithm { + public byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] theCek) { + if (headers.getKeyEncryptionAlgorithm() != null) { + throw new SecurityException(); + } + return new byte[0]; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryption.java index 88caeec..978fd8a 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryption.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweEncryption.java @@ -28,12 +28,9 @@ public class DirectKeyJweEncryption extends AbstractJweEncryption { cek.getEncoded().length * 8)), cek.getEncoded(), iv); } public DirectKeyJweEncryption(JweHeaders headers, byte[] cek, byte[] iv) { - super(headers, cek, iv); + this(headers, cek, iv, AbstractJweEncryption.DEFAULT_AUTH_TAG_LENGTH); } public DirectKeyJweEncryption(JweHeaders headers, byte[] cek, byte[] iv, int authTagLen) { - super(headers, cek, iv, authTagLen); - } - protected byte[] getEncryptedContentEncryptionKey(byte[] theCek) { - return new byte[0]; + super(headers, cek, iv, authTagLen, new DirectKeyEncryption()); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryption.java deleted file mode 100644 index 66ce657..0000000 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryption.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.oauth2.jwe; - -import javax.crypto.Cipher; - -public class JweEncryption { - private Cipher cipher; - private int authTagLen; - private JweHeaders headers; - private byte[] contentEncryptionKey; - private byte[] iv; - private boolean compressionSupported; - - public JweEncryption(Cipher cipher, int authTagLen, JweHeaders headers, - byte[] contentEncryptionKey, - byte[] iv, boolean compressionSupported) { - this.cipher = cipher; - this.authTagLen = authTagLen; - this.headers = headers; - this.contentEncryptionKey = contentEncryptionKey; - this.iv = iv; - this.compressionSupported = compressionSupported; - } - public Cipher getCipher() { - return cipher; - } - public JweHeaders getHeaders() { - return headers; - } - public byte[] getContentEncryptionKey() { - return contentEncryptionKey; - } - public byte[] getIv() { - return iv; - } - public boolean isCompressionSupported() { - return compressionSupported; - } - public int getAuthTagLen() { - return authTagLen; - } - -} http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptionProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptionProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptionProvider.java index 71bd02e..4f4ec2c 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptionProvider.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptionProvider.java @@ -22,5 +22,5 @@ package org.apache.cxf.rs.security.oauth2.jwe; public interface JweEncryptionProvider { String encrypt(byte[] jweContent, String contentType); - JweEncryption createJweEncryption(String contentType); + JweEncryptionState createJweEncryptionState(String contentType); } http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptionState.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptionState.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptionState.java new file mode 100644 index 0000000..98db5f0 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptionState.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.oauth2.jwe; + +import javax.crypto.Cipher; + +public class JweEncryptionState { + private Cipher cipher; + private int authTagLen; + private JweHeaders headers; + private byte[] contentEncryptionKey; + private byte[] iv; + private boolean compressionSupported; + + public JweEncryptionState(Cipher cipher, int authTagLen, JweHeaders headers, + byte[] contentEncryptionKey, + byte[] iv, boolean compressionSupported) { + this.cipher = cipher; + this.authTagLen = authTagLen; + this.headers = headers; + this.contentEncryptionKey = contentEncryptionKey; + this.iv = iv; + this.compressionSupported = compressionSupported; + } + public Cipher getCipher() { + return cipher; + } + public JweHeaders getHeaders() { + return headers; + } + public byte[] getContentEncryptionKey() { + return contentEncryptionKey; + } + public byte[] getIv() { + return iv; + } + public boolean isCompressionSupported() { + return compressionSupported; + } + public int getAuthTagLen() { + return authTagLen; + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java index d3806c8..4b0d157 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweHeaders.java @@ -25,6 +25,7 @@ import java.util.Map; import org.apache.cxf.rs.security.oauth2.jwt.JwtConstants; import org.apache.cxf.rs.security.oauth2.jwt.JwtHeaders; import org.apache.cxf.rs.security.oauth2.jwt.JwtHeadersWriter; +import org.apache.cxf.rs.security.oauth2.jwt.JwtTokenReaderWriter; import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility; @@ -89,6 +90,9 @@ public class JweHeaders extends JwtHeaders { return (JwtHeaders)super.setHeader(name, value); } + public byte[] toCipherAdditionalAuthData() { + return toCipherAdditionalAuthData(new JwtTokenReaderWriter()); + } public byte[] toCipherAdditionalAuthData(JwtHeadersWriter writer) { return toCipherAdditionalAuthData(writer.headersToJson(this)); } http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/KeyEncryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/KeyEncryptionAlgorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/KeyEncryptionAlgorithm.java new file mode 100644 index 0000000..2bc4d16 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/KeyEncryptionAlgorithm.java @@ -0,0 +1,24 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.jwe; + + +interface KeyEncryptionAlgorithm { + byte[] getEncryptedContentEncryptionKey(JweHeaders headers, byte[] cek); +} http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryption.java index b45c800..d00b8ed 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryption.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweEncryption.java @@ -22,41 +22,41 @@ import java.security.interfaces.RSAPublicKey; import javax.crypto.SecretKey; -import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; import org.apache.cxf.rs.security.oauth2.jwt.JwtHeadersWriter; public class RSAJweEncryption extends WrappedKeyJweEncryption { - public RSAJweEncryption(RSAPublicKey publicKey, String contentEncryptionAlgo) { - super(new JweHeaders(Algorithm.RSA_OAEP.getJwtName(), - contentEncryptionAlgo), publicKey); + public RSAJweEncryption(RSAPublicKey publicKey, + String keyEncryptionJwtAlgo, + String contentEncryptionJwtAlgo) { + super(new JweHeaders(keyEncryptionJwtAlgo, + contentEncryptionJwtAlgo), + new RSAOaepKeyEncryption(publicKey, keyEncryptionJwtAlgo)); } public RSAJweEncryption(RSAPublicKey publicKey, JweHeaders headers, byte[] cek, byte[] iv) { - this(publicKey, headers, cek, iv, DEFAULT_AUTH_TAG_LENGTH, true); + this(publicKey, headers, cek, iv, DEFAULT_AUTH_TAG_LENGTH, true, null); } - public RSAJweEncryption(RSAPublicKey publicKey, SecretKey secretKey, String secretKeyJwtAlgorithm, - byte[] iv) { + public RSAJweEncryption(RSAPublicKey publicKey, + String keyEncryptionJwtAlgo, + SecretKey secretKey, + String secretKeyJwtAlgo, + byte[] iv) { this(publicKey, - new JweHeaders(Algorithm.RSA_OAEP.getJwtName(), secretKeyJwtAlgorithm), - secretKey != null ? secretKey.getEncoded() : null, iv, DEFAULT_AUTH_TAG_LENGTH, true); - } - public RSAJweEncryption(RSAPublicKey publicKey, SecretKey secretKey, byte[] iv) { - this(publicKey, secretKey, - Algorithm.toJwtName(secretKey.getAlgorithm(), - secretKey.getEncoded().length * 8), iv); + new JweHeaders(keyEncryptionJwtAlgo, secretKeyJwtAlgo), + secretKey != null ? secretKey.getEncoded() : null, iv, DEFAULT_AUTH_TAG_LENGTH, true, null); } - public RSAJweEncryption(RSAPublicKey publicKey, JweHeaders headers, byte[] cek, byte[] iv, - int authTagLen, boolean wrap) { - this(publicKey, headers, cek, iv, authTagLen, wrap, null); - } - - public RSAJweEncryption(RSAPublicKey publicKey, JweHeaders headers, byte[] cek, byte[] iv, - JwtHeadersWriter writer) { - this(publicKey, headers, cek, iv, DEFAULT_AUTH_TAG_LENGTH, true, null); + public RSAJweEncryption(RSAPublicKey publicKey, + JweHeaders headers, + byte[] cek, + byte[] iv, + int authTagLen, + boolean wrap, + JwtHeadersWriter writer) { + this(new RSAOaepKeyEncryption(publicKey, wrap), headers, cek, iv, DEFAULT_AUTH_TAG_LENGTH, writer); } - public RSAJweEncryption(RSAPublicKey publicKey, JweHeaders headers, byte[] cek, byte[] iv, - int authTagLen, boolean wrap, JwtHeadersWriter writer) { - super(headers, publicKey, cek, iv, authTagLen, wrap, writer); + public RSAJweEncryption(RSAOaepKeyEncryption keyEncryptionAlgorithm, JweHeaders headers, byte[] cek, + byte[] iv, int authTagLen, JwtHeadersWriter writer) { + super(headers, cek, iv, authTagLen, keyEncryptionAlgorithm, writer); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAOaepKeyEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAOaepKeyEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAOaepKeyEncryption.java new file mode 100644 index 0000000..bdd9dd6 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAOaepKeyEncryption.java @@ -0,0 +1,45 @@ +/** + * 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.interfaces.RSAPublicKey; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; + +public class RSAOaepKeyEncryption extends AbstractWrapKeyEncryption { + private static final Set<String> SUPPORTED_ALGORITHMS = new HashSet<String>( + Arrays.asList(Algorithm.RSA_OAEP.getJwtName(), + Algorithm.RSA_OAEP_256.getJwtName())); + public RSAOaepKeyEncryption(RSAPublicKey publicKey) { + this(publicKey, null, true); + } + public RSAOaepKeyEncryption(RSAPublicKey publicKey, boolean wrap) { + this(publicKey, null, wrap); + } + public RSAOaepKeyEncryption(RSAPublicKey publicKey, String jweAlgo) { + this(publicKey, jweAlgo, true); + } + public RSAOaepKeyEncryption(RSAPublicKey publicKey, String jweAlgo, boolean wrap) { + super(publicKey, jweAlgo, wrap, SUPPORTED_ALGORITHMS); + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryption.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryption.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryption.java index 9b37515..e7c09bc 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryption.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweEncryption.java @@ -18,34 +18,29 @@ */ package org.apache.cxf.rs.security.oauth2.jwe; -import java.security.Key; import java.util.concurrent.atomic.AtomicInteger; import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; import org.apache.cxf.rs.security.oauth2.jwt.JwtHeadersWriter; import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; -import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties; public class WrappedKeyJweEncryption extends AbstractJweEncryption { - private Key cekEncryptionKey; - private boolean wrap; private AtomicInteger providedCekUsageCount; - public WrappedKeyJweEncryption(JweHeaders headers, Key cekEncryptionKey) { - this(headers, cekEncryptionKey, null, null); + public WrappedKeyJweEncryption(JweHeaders headers, + KeyEncryptionAlgorithm keyEncryptionAlgorithm) { + this(headers, null, null, keyEncryptionAlgorithm); } - public WrappedKeyJweEncryption(JweHeaders headers, Key cekEncryptionKey, byte[] cek, byte[] iv) { - this(headers, cekEncryptionKey, cek, iv, DEFAULT_AUTH_TAG_LENGTH, true); + public WrappedKeyJweEncryption(JweHeaders headers, byte[] cek, + byte[] iv, KeyEncryptionAlgorithm keyEncryptionAlgorithm) { + this(headers, cek, iv, DEFAULT_AUTH_TAG_LENGTH, keyEncryptionAlgorithm, null); } - public WrappedKeyJweEncryption(JweHeaders headers, Key cekEncryptionKey, byte[] cek, byte[] iv, - int authTagLen, boolean wrap) { - this(headers, cekEncryptionKey, cek, iv, authTagLen, wrap, null); - } - - public WrappedKeyJweEncryption(JweHeaders headers, Key cekEncryptionKey, byte[] cek, byte[] iv, int authTagLen, - boolean wrap, JwtHeadersWriter writer) { - super(headers, cek, iv, authTagLen, writer); - this.cekEncryptionKey = cekEncryptionKey; - this.wrap = wrap; + public WrappedKeyJweEncryption(JweHeaders headers, + byte[] cek, + byte[] iv, + int authTagLen, + KeyEncryptionAlgorithm keyEncryptionAlgorithm, + JwtHeadersWriter writer) { + super(headers, cek, iv, authTagLen, keyEncryptionAlgorithm, writer); if (cek != null) { providedCekUsageCount = new AtomicInteger(); } @@ -62,16 +57,5 @@ public class WrappedKeyJweEncryption extends AbstractJweEncryption { } return theCek; } - protected byte[] getEncryptedContentEncryptionKey(byte[] theCek) { - KeyProperties secretKeyProperties = new KeyProperties(getContentEncryptionKeyEncryptionAlgo()); - if (!wrap) { - return CryptoUtils.encryptBytes(theCek, cekEncryptionKey, secretKeyProperties); - } else { - return CryptoUtils.wrapSecretKey(theCek, getContentEncryptionAlgoJava(), cekEncryptionKey, - secretKeyProperties.getKeyAlgo()); - } - } - protected String getContentEncryptionKeyEncryptionAlgo() { - return Algorithm.toJavaName(getJweHeaders().getKeyEncryptionAlgorithm()); - } + } http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/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 4f115a7..1f1b573 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 @@ -90,6 +90,9 @@ public enum Algorithm { JAVA_TO_JWT_NAMES.put(AES_GCM_ALGO_JAVA, JwtConstants.A256GCM_ALGO); JAVA_TO_JWT_NAMES.put(AES_GCM_ALGO_JAVA, JwtConstants.A192GCM_ALGO); JAVA_TO_JWT_NAMES.put(AES_GCM_ALGO_JAVA, JwtConstants.A128GCM_ALGO); + JAVA_TO_JWT_NAMES.put(AES_WRAP_ALGO_JAVA, JwtConstants.A128KW_ALGO); + JAVA_TO_JWT_NAMES.put(AES_WRAP_ALGO_JAVA, JwtConstants.A192KW_ALGO); + JAVA_TO_JWT_NAMES.put(AES_WRAP_ALGO_JAVA, JwtConstants.A256KW_ALGO); JAVA_TO_JWT_NAMES.put(AES_CBC_ALGO_JAVA, JwtConstants.A128CBC_HS256_ALGO); JAVA_TO_JWT_NAMES.put(AES_CBC_ALGO_JAVA, JwtConstants.A192CBC_HS354_ALGO); JAVA_TO_JWT_NAMES.put(AES_CBC_ALGO_JAVA, JwtConstants.A256CBC_HS512_ALGO); @@ -106,6 +109,9 @@ public enum Algorithm { JWT_TO_JAVA_NAMES.put(JwtConstants.RSA_OAEP_ALGO, RSA_OAEP_ALGO_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.RSA_OAEP_256_ALGO, RSA_OAEP_256_ALGO_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.RSA_1_5_ALGO, RSA_1_5_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.A128KW_ALGO, AES_WRAP_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.A192KW_ALGO, AES_WRAP_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.A256KW_ALGO, AES_WRAP_ALGO_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.A256GCM_ALGO, AES_GCM_ALGO_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.A192GCM_ALGO, AES_GCM_ALGO_JAVA); JWT_TO_JAVA_NAMES.put(JwtConstants.A128GCM_ALGO, AES_GCM_ALGO_JAVA); http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJwsWriterProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJwsWriterProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJwsWriterProvider.java index e8cdd8c..62e83ae 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJwsWriterProvider.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/AbstractJwsWriterProvider.java @@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; import java.security.PrivateKey; +import java.security.interfaces.RSAPrivateKey; import java.util.Properties; import org.apache.cxf.helpers.IOUtils; @@ -58,6 +59,9 @@ public class AbstractJwsWriterProvider { try { Properties props = ResourceUtils.loadProperties(propLoc, m.getExchange().getBus()); PrivateKey pk = CryptoUtils.loadPrivateKey(m, props, CryptoUtils.RSSEC_SIG_KEY_PSWD_PROVIDER); + if (!(pk instanceof RSAPrivateKey)) { + throw new SecurityException(); + } PrivateKeyJwsSignatureProvider provider = new PrivateKeyJwsSignatureProvider(pk); provider.setDefaultJwtAlgorithm(props.getProperty(JSON_WEB_SIGNATURE_ALGO_PROP)); return provider; http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/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 d62a8c1..7fcf683 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 @@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.OutputStream; import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; import java.util.Properties; import java.util.zip.DeflaterOutputStream; @@ -39,12 +40,12 @@ import org.apache.cxf.jaxrs.utils.ResourceUtils; import org.apache.cxf.message.Message; import org.apache.cxf.message.MessageUtils; import org.apache.cxf.rs.security.oauth2.jwe.JweCompactProducer; -import org.apache.cxf.rs.security.oauth2.jwe.JweEncryption; import org.apache.cxf.rs.security.oauth2.jwe.JweEncryptionProvider; +import org.apache.cxf.rs.security.oauth2.jwe.JweEncryptionState; import org.apache.cxf.rs.security.oauth2.jwe.JweHeaders; import org.apache.cxf.rs.security.oauth2.jwe.JweOutputStream; +import org.apache.cxf.rs.security.oauth2.jwe.RSAOaepKeyEncryption; import org.apache.cxf.rs.security.oauth2.jwe.WrappedKeyJweEncryption; -import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; import org.apache.cxf.rs.security.oauth2.jwt.JwtHeadersWriter; import org.apache.cxf.rs.security.oauth2.jwt.JwtTokenReaderWriter; import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; @@ -54,6 +55,7 @@ public class JweWriterInterceptor implements WriterInterceptor { private static final String JSON_ENCRYPTION_OUT_PROPS = "rs.security.encryption.out.properties"; private static final String JSON_ENCRYPTION_PROPS = "rs.security.encryption.properties"; private static final String JSON_WEB_ENCRYPTION_CEK_ALGO_PROP = "rs.security.jwe.content.encryption.algorithm"; + private static final String JSON_WEB_ENCRYPTION_KEY_ALGO_PROP = "rs.security.jwe.key.encryption.algorithm"; private static final String JSON_WEB_ENCRYPTION_ZIP_ALGO_PROP = "rs.security.jwe.zip.algorithm"; private JweEncryptionProvider encryptionProvider; private boolean contentTypeRequired = true; @@ -75,7 +77,7 @@ public class JweWriterInterceptor implements WriterInterceptor { if (useJweOutputStream) { - JweEncryption encryption = theEncryptionProvider.createJweEncryption(ctString); + JweEncryptionState encryption = theEncryptionProvider.createJweEncryptionState(ctString); try { JweCompactProducer.startJweContent(actualOs, encryption.getHeaders(), @@ -118,14 +120,17 @@ public class JweWriterInterceptor implements WriterInterceptor { try { Properties props = ResourceUtils.loadProperties(propLoc, bus); PublicKey pk = CryptoUtils.loadPublicKey(m, props); - JweHeaders headers = new JweHeaders(Algorithm.RSA_OAEP.getJwtName(), + if (!(pk instanceof RSAPublicKey)) { + throw new SecurityException(); + } + JweHeaders headers = new JweHeaders(props.getProperty(JSON_WEB_ENCRYPTION_KEY_ALGO_PROP), props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP)); String compression = props.getProperty(JSON_WEB_ENCRYPTION_ZIP_ALGO_PROP); if (compression != null) { headers.setZipAlgorithm(compression); } - return new WrappedKeyJweEncryption(headers, pk); + return new WrappedKeyJweEncryption(headers, new RSAOaepKeyEncryption((RSAPublicKey)pk)); } catch (SecurityException ex) { throw ex; } catch (Exception ex) { http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/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 5ec0115..b432d9c 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 @@ -18,7 +18,6 @@ */ package org.apache.cxf.rs.security.oauth2.jwe; -import java.math.BigInteger; import java.nio.ByteBuffer; import java.security.Security; import java.security.interfaces.RSAPrivateKey; @@ -31,7 +30,6 @@ import javax.crypto.spec.IvParameterSpec; import org.apache.cxf.rs.security.oauth2.jws.JwsCompactReaderWriterTest; import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; -import org.apache.cxf.rs.security.oauth2.jwt.JwtTokenReaderWriter; import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility; import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; import org.apache.cxf.rs.security.oauth2.utils.crypto.HmacUtils; @@ -114,17 +112,11 @@ public class JweCompactReaderWriterTest extends Assert { headers.setAlgorithm(Algorithm.A128KW.getJwtName()); headers.setContentEncryptionAlgorithm(Algorithm.A128CBC_HS256.getJwtName()); - SecretKey secretCompleteCek = CryptoUtils.createSecretKeySpec(CONTENT_ENCRYPTION_KEY_A3, - Algorithm.A128CBC_HS256.getJavaAlgoName()); - byte[] wrapperKeyBytes = Base64UrlUtility.decode(KEY_ENCRYPTION_KEY_A3); - SecretKey secretWrapperKey = - CryptoUtils.createSecretKeySpec(wrapperKeyBytes, Algorithm.A128KW.getJavaAlgoName()); - byte[] defaultAesWrapIv = new BigInteger("A6A6A6A6A6A6A6A6", 16).toByteArray(); - KeyProperties wrapperkeyProps = new KeyProperties(Algorithm.A128KW.getJavaName()); - keyProps.setAlgoSpec(new IvParameterSpec(defaultAesWrapIv)); - byte[] encryptedCek = CryptoUtils.wrapSecretKey(secretCompleteCek, secretWrapperKey, wrapperkeyProps); + AesWrapKeyEncryption keyEncryption = new AesWrapKeyEncryption(Base64UrlUtility.decode(KEY_ENCRYPTION_KEY_A3), + Algorithm.A128KW.getJwtName()); + byte[] encryptedCek = keyEncryption.getEncryptedContentEncryptionKey(headers, CONTENT_ENCRYPTION_KEY_A3); - byte[] aad = headers.toCipherAdditionalAuthData(new JwtTokenReaderWriter()); + byte[] aad = headers.toCipherAdditionalAuthData(); ByteBuffer buf = ByteBuffer.allocate(8); byte[] al = buf.putInt(0).putInt(aad.length * 8).array(); @@ -180,6 +172,7 @@ public class JweCompactReaderWriterTest extends Assert { jwtKeyName = Algorithm.toJwtName(key.getAlgorithm(), key.getEncoded().length * 8); } RSAJweEncryption encryptor = new RSAJweEncryption(publicKey, + Algorithm.RSA_OAEP.getJwtName(), key, jwtKeyName, INIT_VECTOR); http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java index 3edc75d..ebbb3fd 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java @@ -540,10 +540,10 @@ public final class CryptoUtils { public static byte[] wrapSecretKey(byte[] keyBytes, String keyAlgo, Key wrapperKey, - String wrapperKeyAlgo) throws SecurityException { + KeyProperties wrapperKeyProps) throws SecurityException { return wrapSecretKey(new SecretKeySpec(keyBytes, convertJCECipherToSecretKeyName(keyAlgo)), wrapperKey, - new KeyProperties(wrapperKeyAlgo)); + wrapperKeyProps); } public static byte[] wrapSecretKey(Key secretKey, http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/alice.rs.properties ---------------------------------------------------------------------- diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/alice.rs.properties b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/alice.rs.properties index 1b42f7e..bb85d61 100644 --- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/alice.rs.properties +++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/alice.rs.properties @@ -19,4 +19,5 @@ rs.security.keystore.password=password rs.security.keystore.alias=alice rs.security.keystore.file=org/apache/cxf/systest/jaxrs/security/certs/alice.jks rs.security.jwe.content.encryption.algorithm=A128GCM +rs.security.jwe.key.encryption.algorithm=RSA-OAEP rs.security.jws.content.signature.algorithm=RS256 http://git-wip-us.apache.org/repos/asf/cxf/blob/9899753a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.rs.properties ---------------------------------------------------------------------- diff --git a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.rs.properties b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.rs.properties index 1cc2de3..73ee40e 100644 --- a/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.rs.properties +++ b/systests/rs-security/src/test/resources/org/apache/cxf/systest/jaxrs/security/bob.rs.properties @@ -21,4 +21,5 @@ rs.security.keystore.password=password rs.security.keystore.alias=bob rs.security.keystore.file=org/apache/cxf/systest/jaxrs/security/certs/bob.jks rs.security.jwe.content.encryption.algorithm=A128GCM +rs.security.jwe.key.encryption.algorithm=RSA-OAEP rs.security.jws.content.signature.algorithm=RS256
