Repository: cxf Updated Branches: refs/heads/master b46641c6f -> bfd50e974
[CXF-5311] More refactorings to make it simpler to use JWE helpers in JAX-RS providers Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/bfd50e97 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/bfd50e97 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/bfd50e97 Branch: refs/heads/master Commit: bfd50e974ed07f49bf8f981fae30cb80b213db37 Parents: b46641c Author: Sergey Beryozkin <[email protected]> Authored: Fri Jun 6 16:52:28 2014 +0100 Committer: Sergey Beryozkin <[email protected]> Committed: Fri Jun 6 16:52:28 2014 +0100 ---------------------------------------------------------------------- .../oauth2/jwe/AbstractJweDecryptor.java | 22 ++++++---- .../oauth2/jwe/AbstractJweEncryptor.java | 8 ++-- .../oauth2/jwe/DirectKeyJweDecryptor.java | 8 ++-- .../oauth2/jwe/JweDecryptionOutput.java | 43 ++++++++++++++++++++ .../rs/security/oauth2/jwe/JweDecryptor.java | 24 +++++++++++ .../rs/security/oauth2/jwe/JweEncryptor.java | 25 ++++++++++++ .../rs/security/oauth2/jwe/RSAJweDecryptor.java | 12 +++--- .../oauth2/jwe/WrappedKeyJweDecryptor.java | 12 +++--- .../oauth2/jwe/JweCompactReaderWriterTest.java | 12 +++--- .../oauth2/utils/crypto/CryptoUtils.java | 32 +++++++++++++++ 10 files changed, 163 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryptor.java index 840001f..6303717 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweDecryptor.java @@ -23,23 +23,27 @@ import java.security.spec.AlgorithmParameterSpec; import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; -public abstract class AbstractJweDecryptor { +public abstract class AbstractJweDecryptor implements JweDecryptor { private JweCompactConsumer jweConsumer; private CeProvider ceProvider = new CeProvider(); - protected AbstractJweDecryptor(String jweContent, JweCryptoProperties props) { - this.jweConsumer = new JweCompactConsumer(jweContent, props); + private JweCryptoProperties props; + protected AbstractJweDecryptor(JweCryptoProperties props) { + this.props = props; } protected abstract byte[] getContentEncryptionKey(); - public byte[] getDecryptedContent() { - - return jweConsumer.getDecryptedContent(ceProvider); - + public JweDecryptionOutput decrypt(String content) { + byte[] bytes = getJweConsumer(content).getDecryptedContent(ceProvider); + return new JweDecryptionOutput(getHeaders(), bytes); } - public String getDecryptedContentText() { - return jweConsumer.getDecryptedContentText(ceProvider); + private JweCompactConsumer getJweConsumer(String jweContent) { + if (jweConsumer == null) { + this.jweConsumer = new JweCompactConsumer(jweContent, props); + } + return jweConsumer; } + protected JweHeaders getHeaders() { return getJweConsumer().getJweHeaders(); } http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java index 2427cc1..7ccbfc1 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/AbstractJweEncryptor.java @@ -29,7 +29,7 @@ import org.apache.cxf.rs.security.oauth2.jwt.JwtTokenReaderWriter; import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties; -public abstract class AbstractJweEncryptor { +public abstract class AbstractJweEncryptor implements JweEncryptor { protected static final int DEFAULT_IV_SIZE = 96; protected static final int DEFAULT_AUTH_TAG_LENGTH = 128; private JweHeaders headers; @@ -85,7 +85,7 @@ public abstract class AbstractJweEncryptor { protected JweHeaders getJweHeaders() { return headers; } - public String getJweContent(byte[] content) { + public String encrypt(byte[] content) { byte[] theCek = getContentEncryptionKey(); String contentEncryptionAlgoJavaName = Algorithm.toJavaName(headers.getContentEncryptionAlgorithm()); KeyProperties keyProps = new KeyProperties(contentEncryptionAlgoJavaName); @@ -110,9 +110,9 @@ public abstract class AbstractJweEncryptor { return producer.getJweContent(); } - public String getJweContent(String text) { + public String encryptText(String text) { try { - return getJweContent(text.getBytes("UTF-8")); + return encrypt(text.getBytes("UTF-8")); } catch (UnsupportedEncodingException ex) { throw new SecurityException(ex); } http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryptor.java index be9378f..aaa76f7 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/DirectKeyJweDecryptor.java @@ -22,11 +22,11 @@ import java.security.Key; public class DirectKeyJweDecryptor extends AbstractJweDecryptor { private byte[] contentDecryptionKey; - public DirectKeyJweDecryptor(String jweContent, Key contentDecryptionKey) { - this(jweContent, contentDecryptionKey, null); + public DirectKeyJweDecryptor(Key contentDecryptionKey) { + this(contentDecryptionKey, null); } - public DirectKeyJweDecryptor(String jweContent, Key contentDecryptionKey, JweCryptoProperties props) { - super(jweContent, props); + public DirectKeyJweDecryptor(Key contentDecryptionKey, JweCryptoProperties props) { + super(props); this.contentDecryptionKey = contentDecryptionKey.getEncoded(); } @Override http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionOutput.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionOutput.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionOutput.java new file mode 100644 index 0000000..e4b7997 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptionOutput.java @@ -0,0 +1,43 @@ +/** + * 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; + +public class JweDecryptionOutput { + private JweHeaders headers; + private byte[] content; + public JweDecryptionOutput(JweHeaders headers, byte[] content) { + this.headers = headers; + this.content = content; + } + public JweHeaders getHeaders() { + return headers; + } + public byte[] getContent() { + return content; + } + public String getContentText() { + try { + return new String(getContent(), "UTF-8"); + } catch (UnsupportedEncodingException ex) { + throw new SecurityException(ex); + } + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptor.java new file mode 100644 index 0000000..e1e2f4d --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweDecryptor.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; + + +public interface JweDecryptor { + JweDecryptionOutput decrypt(String jweContent); +} http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptor.java new file mode 100644 index 0000000..09554fe --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweEncryptor.java @@ -0,0 +1,25 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.jwe; + + +public interface JweEncryptor { + String encrypt(byte[] jweContent); + String encryptText(String jweContent); +} http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java index 17a53d1..f0ea144 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/RSAJweDecryptor.java @@ -24,15 +24,15 @@ import java.security.interfaces.RSAPublicKey; public class RSAJweDecryptor extends WrappedKeyJweDecryptor { - public RSAJweDecryptor(String jweContent, RSAPrivateKey privateKey) { - this(jweContent, privateKey, true); + public RSAJweDecryptor(RSAPrivateKey privateKey) { + this(privateKey, true); } - public RSAJweDecryptor(String jweContent, RSAPrivateKey privateKey, boolean unwrap) { - this(jweContent, privateKey, unwrap, null); + public RSAJweDecryptor(RSAPrivateKey privateKey, boolean unwrap) { + this(privateKey, unwrap, null); } - public RSAJweDecryptor(String jweContent, RSAPrivateKey privateKey, boolean unwrap, + public RSAJweDecryptor(RSAPrivateKey privateKey, boolean unwrap, JweCryptoProperties props) { - super(jweContent, privateKey, unwrap, props); + super(privateKey, unwrap, props); } protected int getKeyCipherBlockSize() { http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryptor.java index 1798c55..771590e 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/WrappedKeyJweDecryptor.java @@ -27,15 +27,15 @@ import org.apache.cxf.rs.security.oauth2.utils.crypto.KeyProperties; public class WrappedKeyJweDecryptor extends AbstractJweDecryptor { private Key cekDecryptionKey; private boolean unwrap; - public WrappedKeyJweDecryptor(String jweContent, Key cekDecryptionKey) { - this(jweContent, cekDecryptionKey, true); + public WrappedKeyJweDecryptor(Key cekDecryptionKey) { + this(cekDecryptionKey, true); } - public WrappedKeyJweDecryptor(String jweContent, Key cekDecryptionKey, boolean unwrap) { - this(jweContent, cekDecryptionKey, unwrap, null); + public WrappedKeyJweDecryptor(Key cekDecryptionKey, boolean unwrap) { + this(cekDecryptionKey, unwrap, null); } - public WrappedKeyJweDecryptor(String jweContent, Key cekDecryptionKey, boolean unwrap, + public WrappedKeyJweDecryptor(Key cekDecryptionKey, boolean unwrap, JweCryptoProperties props) { - super(jweContent, props); + super(props); this.cekDecryptionKey = cekDecryptionKey; this.unwrap = unwrap; } http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/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 eed51d8..fa8bdc2 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 @@ -100,23 +100,23 @@ public class JweCompactReaderWriterTest extends Assert { RSAPublicKey publicKey = CryptoUtils.getRSAPublicKey(RSA_MODULUS_ENCODED, RSA_PUBLIC_EXPONENT_ENCODED); SecretKey key = CryptoUtils.createSecretKeySpec(CONTENT_ENCRYPTION_KEY, "AES"); RSAJweEncryptor encryptor = new RSAJweEncryptor(publicKey, key, JwtConstants.A256GCM_ALGO, INIT_VECTOR); - return encryptor.getJweContent(content); + return encryptor.encryptText(content); } private String encryptContentDirect(String content) throws Exception { SecretKey key = CryptoUtils.createSecretKeySpec(CONTENT_ENCRYPTION_KEY, "AES"); DirectKeyJweEncryptor encryptor = new DirectKeyJweEncryptor(key, INIT_VECTOR); - return encryptor.getJweContent(content); + return encryptor.encryptText(content); } private void decrypt(String jweContent, String plainContent) throws Exception { RSAPrivateKey privateKey = CryptoUtils.getRSAPrivateKey(RSA_MODULUS_ENCODED, RSA_PRIVATE_EXPONENT_ENCODED); - RSAJweDecryptor decryptor = new RSAJweDecryptor(jweContent, privateKey); - String decryptedText = decryptor.getDecryptedContentText(); + RSAJweDecryptor decryptor = new RSAJweDecryptor(privateKey); + String decryptedText = decryptor.decrypt(jweContent).getContentText(); assertEquals(decryptedText, plainContent); } private void decryptDirect(String jweContent, String plainContent) throws Exception { SecretKey key = CryptoUtils.createSecretKeySpec(CONTENT_ENCRYPTION_KEY, "AES"); - DirectKeyJweDecryptor decryptor = new DirectKeyJweDecryptor(jweContent, key); - String decryptedText = decryptor.getDecryptedContentText(); + DirectKeyJweDecryptor decryptor = new DirectKeyJweDecryptor(key); + String decryptedText = decryptor.decrypt(jweContent).getContentText(); assertEquals(decryptedText, plainContent); } } http://git-wip-us.apache.org/repos/asf/cxf/blob/bfd50e97/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 f998bcb..f661b50 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 @@ -19,15 +19,18 @@ package org.apache.cxf.rs.security.oauth2.utils.crypto; +import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.math.BigInteger; import java.security.Key; import java.security.KeyFactory; +import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; +import java.security.cert.Certificate; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; @@ -117,6 +120,35 @@ public final class CryptoUtils { } } + public static PublicKey loadPrivateKey(InputStream storeLocation, char[] storePassword, String alias) { + try { + KeyStore keyStore = loadKeyStore(storeLocation, storePassword); + Certificate cert = keyStore.getCertificate(alias); + return cert.getPublicKey(); + } catch (Exception ex) { + throw new SecurityException(ex); + } + } + + public static PrivateKey loadPrivateKey(InputStream storeLocation, char[] storePassword, + char[] keyPassword, String alias) { + try { + KeyStore keyStore = loadKeyStore(storeLocation, storePassword); + KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) + keyStore.getEntry(alias, new KeyStore.PasswordProtection(keyPassword)); + return pkEntry.getPrivateKey(); + } catch (Exception ex) { + throw new SecurityException(ex); + } + } + + + private static KeyStore loadKeyStore(InputStream storeLocation, char[] storePassword) throws Exception { + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + ks.load(storeLocation, storePassword); + return ks; + } + public static RSAPrivateKey getRSAPrivateKey(String encodedModulus, String encodedPrivateExponent) { try {
