Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DCF0C11EE9 for ; Wed, 17 Sep 2014 17:21:28 +0000 (UTC) Received: (qmail 49482 invoked by uid 500); 17 Sep 2014 17:21:28 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 49302 invoked by uid 500); 17 Sep 2014 17:21:28 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 48809 invoked by uid 99); 17 Sep 2014 17:21:28 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 17 Sep 2014 17:21:28 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 0A3B0A18E11; Wed, 17 Sep 2014 17:21:28 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sergeyb@apache.org To: commits@cxf.apache.org Date: Wed, 17 Sep 2014 17:21:35 -0000 Message-Id: <0a1965ab61e5449f82b835b23566f33d@git.apache.org> In-Reply-To: <18d45db943e247258990a947d051f0d7@git.apache.org> References: <18d45db943e247258990a947d051f0d7@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [9/9] git commit: [CXF-5944] Changing packages and the module name based on the feedback from Luigi Lo Iacono [CXF-5944] Changing packages and the module name based on the feedback from Luigi Lo Iacono Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/707d938a Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/707d938a Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/707d938a Branch: refs/heads/3.0.x-fixes Commit: 707d938abf40906f7f6b57b537495aef8b946e91 Parents: 0885ab9 Author: Sergey Beryozkin Authored: Wed Sep 17 18:19:42 2014 +0100 Committer: Sergey Beryozkin Committed: Wed Sep 17 18:21:06 2014 +0100 ---------------------------------------------------------------------- rt/rs/security/oauth-parent/oauth2-jwt/pom.xml | 6 +- .../jose/jaxrs/AbstractJweDecryptingFilter.java | 133 ++++++++++ .../jose/jaxrs/AbstractJwsReaderProvider.java | 106 ++++++++ .../jose/jaxrs/AbstractJwsWriterProvider.java | 105 ++++++++ .../jose/jaxrs/JweClientResponseFilter.java | 46 ++++ .../jose/jaxrs/JweContainerRequestFilter.java | 46 ++++ .../jose/jaxrs/JweWriterInterceptor.java | 200 +++++++++++++++ .../jose/jaxrs/JwsClientResponseFilter.java | 51 ++++ .../jose/jaxrs/JwsContainerRequestFilter.java | 53 ++++ .../jose/jaxrs/JwsJwtMessageBodyReader.java | 55 ++++ .../jose/jaxrs/JwsJwtMessageBodyWriter.java | 60 +++++ .../jose/jaxrs/JwsWriterInterceptor.java | 98 +++++++ .../cxf/rs/security/jose/jaxrs/Priorities.java | 31 +++ .../cxf/rs/security/jose/jwa/Algorithm.java | 209 +++++++++++++++ .../jwe/AbstractContentEncryptionAlgorithm.java | 60 +++++ ...stractContentEncryptionCipherProperties.java | 39 +++ .../jose/jwe/AbstractJweDecryption.java | 108 ++++++++ .../jose/jwe/AbstractJweEncryption.java | 184 +++++++++++++ .../jwe/AbstractWrapKeyEncryptionAlgorithm.java | 96 +++++++ .../jose/jwe/AesCbcHmacJweDecryption.java | 76 ++++++ .../jose/jwe/AesCbcHmacJweEncryption.java | 194 ++++++++++++++ .../jwe/AesGcmContentDecryptionAlgorithm.java | 30 +++ .../jwe/AesGcmContentEncryptionAlgorithm.java | 43 ++++ .../jwe/AesGcmWrapKeyDecryptionAlgorithm.java | 57 +++++ .../jwe/AesGcmWrapKeyEncryptionAlgorithm.java | 64 +++++ .../jose/jwe/AesWrapKeyDecryptionAlgorithm.java | 38 +++ .../jose/jwe/AesWrapKeyEncryptionAlgorithm.java | 48 ++++ .../jose/jwe/AuthenticationTagProducer.java | 24 ++ .../jose/jwe/ContentDecryptionAlgorithm.java | 24 ++ .../jose/jwe/ContentEncryptionAlgorithm.java | 26 ++ .../jwe/ContentEncryptionCipherProperties.java | 27 ++ .../jose/jwe/DirectKeyDecryptionAlgorithm.java | 39 +++ .../jose/jwe/DirectKeyEncryptionAlgorithm.java | 29 +++ .../jose/jwe/DirectKeyJweDecryption.java | 45 ++++ .../jose/jwe/DirectKeyJweEncryption.java | 47 ++++ .../security/jose/jwe/JweCompactConsumer.java | 113 ++++++++ .../security/jose/jwe/JweCompactProducer.java | 155 +++++++++++ .../security/jose/jwe/JweCryptoProperties.java | 22 ++ .../security/jose/jwe/JweDecryptionOutput.java | 43 ++++ .../jose/jwe/JweDecryptionProvider.java | 26 ++ .../jose/jwe/JweEncryptionProvider.java | 26 ++ .../security/jose/jwe/JweEncryptionState.java | 63 +++++ .../cxf/rs/security/jose/jwe/JweHeaders.java | 102 ++++++++ .../rs/security/jose/jwe/JweOutputStream.java | 145 +++++++++++ .../jose/jwe/KeyDecryptionAlgorithm.java | 24 ++ .../jose/jwe/KeyEncryptionAlgorithm.java | 24 ++ .../PbesHmacAesWrapKeyDecryptionAlgorithm.java | 54 ++++ .../PbesHmacAesWrapKeyEncryptionAlgorithm.java | 169 ++++++++++++ .../jose/jwe/RSAOaepKeyDecryptionAlgorithm.java | 33 +++ .../jose/jwe/RSAOaepKeyEncryptionAlgorithm.java | 39 +++ .../jose/jwe/WrappedKeyDecryptionAlgorithm.java | 74 ++++++ .../jose/jwe/WrappedKeyJweDecryption.java | 56 ++++ .../jose/jwe/WrappedKeyJweEncryption.java | 41 +++ .../jose/jwk/DefaultJwkReaderWriter.java | 48 ++++ .../cxf/rs/security/jose/jwk/JsonWebKey.java | 213 +++++++++++++++ .../cxf/rs/security/jose/jwk/JsonWebKeys.java | 131 ++++++++++ .../rs/security/jose/jwk/JwkReaderWriter.java | 27 ++ .../cxf/rs/security/jose/jwk/JwkUtils.java | 190 ++++++++++++++ .../jose/jws/AbstractJwsSignatureProvider.java | 62 +++++ .../jose/jws/EcDsaJwsSignatureProvider.java | 45 ++++ .../jose/jws/HmacJwsSignatureProvider.java | 89 +++++++ .../security/jose/jws/JwsCompactConsumer.java | 122 +++++++++ .../security/jose/jws/JwsCompactProducer.java | 109 ++++++++ .../jose/jws/JwsJwtCompactConsumer.java | 55 ++++ .../jose/jws/JwsJwtCompactProducer.java | 51 ++++ .../rs/security/jose/jws/JwsOutputStream.java | 66 +++++ .../cxf/rs/security/jose/jws/JwsSignature.java | 25 ++ .../jose/jws/JwsSignatureProperties.java | 23 ++ .../security/jose/jws/JwsSignatureProvider.java | 25 ++ .../security/jose/jws/JwsSignatureVerifier.java | 25 ++ .../jws/PrivateKeyJwsSignatureProvider.java | 91 +++++++ .../jose/jws/PublicKeyJwsSignatureVerifier.java | 52 ++++ .../rs/security/jose/jwt/AbstractJwtObject.java | 61 +++++ .../jose/jwt/AbstractJwtObjectReaderWriter.java | 212 +++++++++++++++ .../cxf/rs/security/jose/jwt/JwtClaims.java | 100 ++++++++ .../cxf/rs/security/jose/jwt/JwtConstants.java | 89 +++++++ .../cxf/rs/security/jose/jwt/JwtHeaders.java | 172 +++++++++++++ .../rs/security/jose/jwt/JwtHeadersReader.java | 24 ++ .../rs/security/jose/jwt/JwtHeadersWriter.java | 27 ++ .../cxf/rs/security/jose/jwt/JwtToken.java | 45 ++++ .../cxf/rs/security/jose/jwt/JwtTokenJson.java | 37 +++ .../rs/security/jose/jwt/JwtTokenReader.java | 25 ++ .../security/jose/jwt/JwtTokenReaderWriter.java | 67 +++++ .../rs/security/jose/jwt/JwtTokenWriter.java | 28 ++ .../cxf/rs/security/jose/jwt/JwtUtils.java | 46 ++++ .../jose/jwt/grant/AbstractJwtBearerGrant.java | 69 +++++ .../jose/jwt/grant/AbstractJwtHandler.java | 100 ++++++++ .../rs/security/jose/jwt/grant/Constants.java | 33 +++ .../grant/JwtBearerClientCredentialsGrant.java | 41 +++ .../security/jose/jwt/grant/JwtBearerGrant.java | 48 ++++ .../jose/jwt/grant/JwtBearerGrantHandler.java | 91 +++++++ .../security/jose/jwt/grant/JwtUserSubject.java | 34 +++ .../jwe/AbstractContentEncryptionAlgorithm.java | 60 ----- ...stractContentEncryptionCipherProperties.java | 39 --- .../oauth2/jwe/AbstractJweDecryption.java | 108 -------- .../oauth2/jwe/AbstractJweEncryption.java | 184 ------------- .../jwe/AbstractWrapKeyEncryptionAlgorithm.java | 96 ------- .../oauth2/jwe/AesCbcHmacJweDecryption.java | 76 ------ .../oauth2/jwe/AesCbcHmacJweEncryption.java | 194 -------------- .../jwe/AesGcmContentDecryptionAlgorithm.java | 30 --- .../jwe/AesGcmContentEncryptionAlgorithm.java | 43 ---- .../jwe/AesGcmWrapKeyDecryptionAlgorithm.java | 57 ----- .../jwe/AesGcmWrapKeyEncryptionAlgorithm.java | 64 ----- .../jwe/AesWrapKeyDecryptionAlgorithm.java | 38 --- .../jwe/AesWrapKeyEncryptionAlgorithm.java | 48 ---- .../oauth2/jwe/AuthenticationTagProducer.java | 24 -- .../oauth2/jwe/ContentDecryptionAlgorithm.java | 24 -- .../oauth2/jwe/ContentEncryptionAlgorithm.java | 26 -- .../jwe/ContentEncryptionCipherProperties.java | 27 -- .../jwe/DirectKeyDecryptionAlgorithm.java | 39 --- .../jwe/DirectKeyEncryptionAlgorithm.java | 29 --- .../oauth2/jwe/DirectKeyJweDecryption.java | 45 ---- .../oauth2/jwe/DirectKeyJweEncryption.java | 47 ---- .../security/oauth2/jwe/JweCompactConsumer.java | 113 -------- .../security/oauth2/jwe/JweCompactProducer.java | 155 ----------- .../oauth2/jwe/JweCryptoProperties.java | 22 -- .../oauth2/jwe/JweDecryptionOutput.java | 43 ---- .../oauth2/jwe/JweDecryptionProvider.java | 26 -- .../oauth2/jwe/JweEncryptionProvider.java | 26 -- .../security/oauth2/jwe/JweEncryptionState.java | 63 ----- .../cxf/rs/security/oauth2/jwe/JweHeaders.java | 102 -------- .../rs/security/oauth2/jwe/JweOutputStream.java | 145 ----------- .../oauth2/jwe/KeyDecryptionAlgorithm.java | 24 -- .../oauth2/jwe/KeyEncryptionAlgorithm.java | 24 -- .../PbesHmacAesWrapKeyDecryptionAlgorithm.java | 54 ---- .../PbesHmacAesWrapKeyEncryptionAlgorithm.java | 169 ------------ .../jwe/RSAOaepKeyDecryptionAlgorithm.java | 33 --- .../jwe/RSAOaepKeyEncryptionAlgorithm.java | 39 --- .../jwe/WrappedKeyDecryptionAlgorithm.java | 74 ------ .../oauth2/jwe/WrappedKeyJweDecryption.java | 56 ---- .../oauth2/jwe/WrappedKeyJweEncryption.java | 41 --- .../oauth2/jwk/DefaultJwkReaderWriter.java | 48 ---- .../cxf/rs/security/oauth2/jwk/JsonWebKey.java | 213 --------------- .../cxf/rs/security/oauth2/jwk/JsonWebKeys.java | 131 ---------- .../rs/security/oauth2/jwk/JwkReaderWriter.java | 27 -- .../cxf/rs/security/oauth2/jwk/JwkUtils.java | 190 -------------- .../jws/AbstractJwsSignatureProvider.java | 62 ----- .../oauth2/jws/EcDsaJwsSignatureProvider.java | 45 ---- .../oauth2/jws/HmacJwsSignatureProvider.java | 89 ------- .../security/oauth2/jws/JwsCompactConsumer.java | 122 --------- .../security/oauth2/jws/JwsCompactProducer.java | 109 -------- .../oauth2/jws/JwsJwtCompactConsumer.java | 55 ---- .../oauth2/jws/JwsJwtCompactProducer.java | 51 ---- .../rs/security/oauth2/jws/JwsOutputStream.java | 66 ----- .../rs/security/oauth2/jws/JwsSignature.java | 25 -- .../oauth2/jws/JwsSignatureProperties.java | 23 -- .../oauth2/jws/JwsSignatureProvider.java | 25 -- .../oauth2/jws/JwsSignatureVerifier.java | 25 -- .../jws/PrivateKeyJwsSignatureProvider.java | 91 ------- .../jws/PublicKeyJwsSignatureVerifier.java | 52 ---- .../security/oauth2/jwt/AbstractJwtObject.java | 61 ----- .../jwt/AbstractJwtObjectReaderWriter.java | 212 --------------- .../cxf/rs/security/oauth2/jwt/Algorithm.java | 207 --------------- .../cxf/rs/security/oauth2/jwt/JwtClaims.java | 100 -------- .../rs/security/oauth2/jwt/JwtConstants.java | 89 ------- .../cxf/rs/security/oauth2/jwt/JwtHeaders.java | 171 ------------- .../security/oauth2/jwt/JwtHeadersReader.java | 24 -- .../security/oauth2/jwt/JwtHeadersWriter.java | 27 -- .../cxf/rs/security/oauth2/jwt/JwtToken.java | 45 ---- .../rs/security/oauth2/jwt/JwtTokenJson.java | 37 --- .../rs/security/oauth2/jwt/JwtTokenReader.java | 25 -- .../oauth2/jwt/JwtTokenReaderWriter.java | 67 ----- .../rs/security/oauth2/jwt/JwtTokenWriter.java | 28 -- .../cxf/rs/security/oauth2/jwt/JwtUtils.java | 46 ---- .../jwt/grant/AbstractJwtBearerGrant.java | 69 ----- .../oauth2/jwt/grant/AbstractJwtHandler.java | 100 -------- .../rs/security/oauth2/jwt/grant/Constants.java | 33 --- .../grant/JwtBearerClientCredentialsGrant.java | 41 --- .../oauth2/jwt/grant/JwtBearerGrant.java | 48 ---- .../oauth2/jwt/grant/JwtBearerGrantHandler.java | 91 ------- .../oauth2/jwt/grant/JwtUserSubject.java | 34 --- .../jwt/jaxrs/AbstractJweDecryptingFilter.java | 133 ---------- .../jwt/jaxrs/AbstractJwsReaderProvider.java | 106 -------- .../jwt/jaxrs/AbstractJwsWriterProvider.java | 105 -------- .../jwt/jaxrs/JweClientResponseFilter.java | 46 ---- .../jwt/jaxrs/JweContainerRequestFilter.java | 46 ---- .../oauth2/jwt/jaxrs/JweWriterInterceptor.java | 200 --------------- .../jwt/jaxrs/JwsClientResponseFilter.java | 51 ---- .../jwt/jaxrs/JwsContainerRequestFilter.java | 53 ---- .../jwt/jaxrs/JwsJwtMessageBodyReader.java | 55 ---- .../jwt/jaxrs/JwsJwtMessageBodyWriter.java | 60 ----- .../oauth2/jwt/jaxrs/JwsWriterInterceptor.java | 98 ------- .../security/oauth2/jwt/jaxrs/Priorities.java | 31 --- .../jose/jwe/JweCompactReaderWriterTest.java | 210 +++++++++++++++ .../jose/jwe/JwePbeHmacAesWrapTest.java | 78 ++++++ .../rs/security/jose/jwk/JsonWebKeyTest.java | 224 ++++++++++++++++ .../cxf/rs/security/jose/jwk/jwkPrivateSet.txt | 23 ++ .../cxf/rs/security/jose/jwk/jwkPublicSet.txt | 17 ++ .../cxf/rs/security/jose/jwk/jwkSecretSet.txt | 13 + .../jose/jws/JwsCompactReaderWriterTest.java | 256 +++++++++++++++++++ .../oauth2/jwe/JweCompactReaderWriterTest.java | 210 --------------- .../oauth2/jwe/JwePbeHmacAesWrapTest.java | 78 ------ .../rs/security/oauth2/jwk/JsonWebKeyTest.java | 224 ---------------- .../rs/security/oauth2/jwk/jwkPrivateSet.txt | 23 -- .../cxf/rs/security/oauth2/jwk/jwkPublicSet.txt | 17 -- .../cxf/rs/security/oauth2/jwk/jwkSecretSet.txt | 13 - .../oauth2/jws/JwsCompactReaderWriterTest.java | 256 ------------------- systests/rs-security/pom.xml | 2 +- .../jaxrs/security/jwt/JAXRSJweJwsTest.java | 22 +- .../cxf/systest/jaxrs/security/jwt/server.xml | 24 +- 200 files changed, 7346 insertions(+), 7343 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/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 d72c91c..69b05d0 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/pom.xml +++ b/rt/rs/security/oauth-parent/oauth2-jwt/pom.xml @@ -19,10 +19,10 @@ --> 4.0.0 - cxf-rt-rs-security-oauth2-jwt + cxf-rt-rs-security-oauth2-jose bundle - Apache CXF Runtime OAuth 2.0 JWT - Apache CXF Runtime OAuth 2.0 JWT + Apache CXF Runtime OAuth 2.0 JOSE + Apache CXF Runtime OAuth 2.0 JOSE http://cxf.apache.org cxf-rt-rs-security-oauth-parent http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java new file mode 100644 index 0000000..fbd91d4 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJweDecryptingFilter.java @@ -0,0 +1,133 @@ +/** + * 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.jaxrs; + +import java.io.IOException; +import java.io.InputStream; +import java.security.interfaces.RSAPrivateKey; +import java.util.Properties; + +import javax.crypto.SecretKey; + +import org.apache.cxf.Bus; +import org.apache.cxf.helpers.IOUtils; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; +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.jose.jwa.Algorithm; +import org.apache.cxf.rs.security.jose.jwe.AesCbcHmacJweDecryption; +import org.apache.cxf.rs.security.jose.jwe.AesGcmWrapKeyDecryptionAlgorithm; +import org.apache.cxf.rs.security.jose.jwe.AesWrapKeyDecryptionAlgorithm; +import org.apache.cxf.rs.security.jose.jwe.JweCryptoProperties; +import org.apache.cxf.rs.security.jose.jwe.JweDecryptionOutput; +import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider; +import org.apache.cxf.rs.security.jose.jwe.JweHeaders; +import org.apache.cxf.rs.security.jose.jwe.RSAOaepKeyDecryptionAlgorithm; +import org.apache.cxf.rs.security.jose.jwe.WrappedKeyDecryptionAlgorithm; +import org.apache.cxf.rs.security.jose.jwe.WrappedKeyJweDecryption; +import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; +import org.apache.cxf.rs.security.jose.jwk.JwkUtils; +import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; + +public class AbstractJweDecryptingFilter { + private static final String RSSEC_ENCRYPTION_IN_PROPS = "rs.security.encryption.in.properties"; + private static final String RSSEC_ENCRYPTION_PROPS = "rs.security.encryption.properties"; + private static final String JSON_WEB_ENCRYPTION_CEK_ALGO_PROP = "rs.security.jwe.content.encryption.algorithm"; + private JweDecryptionProvider decryption; + private JweCryptoProperties cryptoProperties; + private String defaultMediaType; + protected JweDecryptionOutput decrypt(InputStream is) throws IOException { + JweDecryptionProvider theDecryptor = getInitializedDecryptionProvider(); + JweDecryptionOutput out = theDecryptor.decrypt(new String(IOUtils.readBytesFromStream(is), "UTF-8")); + validateHeaders(out.getHeaders()); + return out; + } + + protected void validateHeaders(JweHeaders headers) { + // complete + } + public void setDecryptionProvider(JweDecryptionProvider decryptor) { + this.decryption = decryptor; + } + protected JweDecryptionProvider getInitializedDecryptionProvider() { + if (decryption != null) { + return decryption; + } + Message m = JAXRSUtils.getCurrentMessage(); + String propLoc = + (String)MessageUtils.getContextualProperty(m, RSSEC_ENCRYPTION_IN_PROPS, RSSEC_ENCRYPTION_PROPS); + if (propLoc == null) { + throw new SecurityException(); + } + Bus bus = m.getExchange().getBus(); + try { + WrappedKeyDecryptionAlgorithm keyDecryptionProvider = null; + Properties props = ResourceUtils.loadProperties(propLoc, bus); + if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(CryptoUtils.RSSEC_KEY_STORE_TYPE))) { + //TODO: Private JWK sets can be JWE encrypted + JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_ENCRYPT); + if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) { + keyDecryptionProvider = new RSAOaepKeyDecryptionAlgorithm(jwk.toRSAPrivateKey()); + } else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType())) { + SecretKey key = jwk.toSecretKey(); + if (Algorithm.isAesKeyWrap(jwk.getAlgorithm())) { + keyDecryptionProvider = new AesWrapKeyDecryptionAlgorithm(key); + } else if (Algorithm.isAesGcmKeyWrap(jwk.getAlgorithm())) { + keyDecryptionProvider = new AesGcmWrapKeyDecryptionAlgorithm(key); + } + } else { + // TODO: support elliptic curve keys + } + } else { + keyDecryptionProvider = new RSAOaepKeyDecryptionAlgorithm( + (RSAPrivateKey)CryptoUtils.loadPrivateKey(m, props, CryptoUtils.RSSEC_DECRYPT_KEY_PSWD_PROVIDER)); + } + if (keyDecryptionProvider == null) { + throw new SecurityException(); + } + String contentEncryptionAlgo = props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP); + boolean isAesHmac = Algorithm.isAesCbcHmac(contentEncryptionAlgo); + if (isAesHmac) { + return new AesCbcHmacJweDecryption(keyDecryptionProvider); + } else { + return new WrappedKeyJweDecryption(keyDecryptionProvider, cryptoProperties, null); + } + + } catch (SecurityException ex) { + throw ex; + } catch (Exception ex) { + throw new SecurityException(ex); + } + + } + + public void setCryptoProperties(JweCryptoProperties cryptoProperties) { + this.cryptoProperties = cryptoProperties; + } + + public String getDefaultMediaType() { + return defaultMediaType; + } + + public void setDefaultMediaType(String defaultMediaType) { + this.defaultMediaType = defaultMediaType; + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java new file mode 100644 index 0000000..0a39c6b --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsReaderProvider.java @@ -0,0 +1,106 @@ +/** + * 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.jaxrs; + +import java.security.interfaces.RSAPublicKey; +import java.util.Properties; + +import org.apache.cxf.Bus; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; +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.jose.jwa.Algorithm; +import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; +import org.apache.cxf.rs.security.jose.jwk.JwkUtils; +import org.apache.cxf.rs.security.jose.jws.HmacJwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureProperties; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; +import org.apache.cxf.rs.security.jose.jws.PublicKeyJwsSignatureVerifier; +import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; + +public class AbstractJwsReaderProvider { + private static final String RSSEC_SIGNATURE_IN_PROPS = "rs.security.signature.in.properties"; + private static final String RSSEC_SIGNATURE_PROPS = "rs.security.signature.properties"; + + private JwsSignatureVerifier sigVerifier; + private JwsSignatureProperties sigProperties; + private String defaultMediaType; + + public void setSignatureVerifier(JwsSignatureVerifier signatureVerifier) { + this.sigVerifier = signatureVerifier; + } + + public void setSignatureProperties(JwsSignatureProperties signatureProperties) { + this.sigProperties = signatureProperties; + } + + public JwsSignatureProperties getSigProperties() { + return sigProperties; + } + + protected JwsSignatureVerifier getInitializedSigVerifier() { + if (sigVerifier != null) { + return sigVerifier; + } + + Message m = JAXRSUtils.getCurrentMessage(); + String propLoc = + (String)MessageUtils.getContextualProperty(m, RSSEC_SIGNATURE_IN_PROPS, RSSEC_SIGNATURE_PROPS); + if (propLoc == null) { + throw new SecurityException(); + } + Bus bus = m.getExchange().getBus(); + try { + Properties props = ResourceUtils.loadProperties(propLoc, bus); + JwsSignatureVerifier theVerifier = null; + if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(CryptoUtils.RSSEC_KEY_STORE_TYPE))) { + JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_VERIFY); + if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) { + theVerifier = new PublicKeyJwsSignatureVerifier(jwk.toRSAPublicKey()); + } else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType()) + && Algorithm.isHmacSign(jwk.getAlgorithm())) { + theVerifier = + new HmacJwsSignatureProvider((String)jwk.getProperty(JsonWebKey.OCTET_KEY_VALUE)); + } else if (JsonWebKey.KEY_TYPE_ELLIPTIC.equals(jwk.getKeyType())) { + theVerifier = new PublicKeyJwsSignatureVerifier(jwk.toECPublicKey()); + } + + } else { + theVerifier = new PublicKeyJwsSignatureVerifier( + (RSAPublicKey)CryptoUtils.loadPublicKey(m, props)); + } + return theVerifier; + } catch (SecurityException ex) { + throw ex; + } catch (Exception ex) { + throw new SecurityException(ex); + } + } + + public String getDefaultMediaType() { + return defaultMediaType; + } + + public void setDefaultMediaType(String defaultMediaType) { + this.defaultMediaType = defaultMediaType; + } + + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.java new file mode 100644 index 0000000..6fc81f0 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/AbstractJwsWriterProvider.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.jaxrs; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.security.interfaces.RSAPrivateKey; +import java.util.Properties; + +import org.apache.cxf.helpers.IOUtils; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; +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.jose.jwa.Algorithm; +import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; +import org.apache.cxf.rs.security.jose.jwk.JwkUtils; +import org.apache.cxf.rs.security.jose.jws.EcDsaJwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jws.HmacJwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jws.JwsCompactProducer; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jws.PrivateKeyJwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jwt.JwtHeaders; +import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; + +public class AbstractJwsWriterProvider { + private static final String RSSEC_SIGNATURE_OUT_PROPS = "rs.security.signature.out.properties"; + private static final String RSSEC_SIGNATURE_PROPS = "rs.security.signature.properties"; + private static final String JSON_WEB_SIGNATURE_ALGO_PROP = "rs.security.jws.content.signature.algorithm"; + + private JwsSignatureProvider sigProvider; + + public void setSignatureProvider(JwsSignatureProvider signatureProvider) { + this.sigProvider = signatureProvider; + } + + protected JwsSignatureProvider getInitializedSigProvider(JwtHeaders headers) { + if (sigProvider != null) { + return sigProvider; + } + Message m = JAXRSUtils.getCurrentMessage(); + String propLoc = + (String)MessageUtils.getContextualProperty(m, RSSEC_SIGNATURE_OUT_PROPS, RSSEC_SIGNATURE_PROPS); + if (propLoc == null) { + throw new SecurityException(); + } + try { + Properties props = ResourceUtils.loadProperties(propLoc, m.getExchange().getBus()); + JwsSignatureProvider theSigProvider = null; + String rsaSignatureAlgo = null; + if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(CryptoUtils.RSSEC_KEY_STORE_TYPE))) { + //TODO: Private JWK sets can be JWE encrypted + JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_SIGN); + rsaSignatureAlgo = jwk.getAlgorithm(); + if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) { + theSigProvider = new PrivateKeyJwsSignatureProvider(jwk.toRSAPrivateKey()); + } else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType()) + && Algorithm.isHmacSign(rsaSignatureAlgo)) { + theSigProvider = + new HmacJwsSignatureProvider((String)jwk.getProperty(JsonWebKey.OCTET_KEY_VALUE)); + } else if (JsonWebKey.KEY_TYPE_ELLIPTIC.equals(jwk.getKeyType())) { + theSigProvider = new EcDsaJwsSignatureProvider(jwk.toECPrivateKey()); + } + } else { + RSAPrivateKey pk = (RSAPrivateKey)CryptoUtils.loadPrivateKey(m, props, + CryptoUtils.RSSEC_SIG_KEY_PSWD_PROVIDER); + theSigProvider = new PrivateKeyJwsSignatureProvider(pk); + } + if (rsaSignatureAlgo == null) { + rsaSignatureAlgo = props.getProperty(JSON_WEB_SIGNATURE_ALGO_PROP); + } + headers.setAlgorithm(rsaSignatureAlgo); + if (theSigProvider == null) { + throw new SecurityException(); + } + return theSigProvider; + } catch (SecurityException ex) { + throw ex; + } catch (Exception ex) { + throw new SecurityException(ex); + } + } + protected void writeJws(JwsCompactProducer p, JwsSignatureProvider theSigProvider, OutputStream os) + throws IOException { + p.signWith(theSigProvider); + IOUtils.copy(new ByteArrayInputStream(p.getSignedEncodedJws().getBytes("UTF-8")), os); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweClientResponseFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweClientResponseFilter.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweClientResponseFilter.java new file mode 100644 index 0000000..596d3db --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweClientResponseFilter.java @@ -0,0 +1,46 @@ +/** + * 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.jaxrs; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import javax.annotation.Priority; +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientResponseContext; +import javax.ws.rs.client.ClientResponseFilter; + +import org.apache.cxf.rs.security.jose.jwe.JweDecryptionOutput; +import org.apache.cxf.rs.security.jose.jwt.JwtUtils; + +@Priority(Priorities.JWE_CLIENT_READ_PRIORITY) +public class JweClientResponseFilter extends AbstractJweDecryptingFilter implements ClientResponseFilter { + @Override + public void filter(ClientRequestContext req, ClientResponseContext res) throws IOException { + JweDecryptionOutput out = decrypt(res.getEntityStream()); + byte[] bytes = out.getContent(); + res.setEntityStream(new ByteArrayInputStream(bytes)); + res.getHeaders().putSingle("Content-Length", Integer.toString(bytes.length)); + String ct = JwtUtils.checkContentType(out.getHeaders().getContentType(), getDefaultMediaType()); + if (ct != null) { + res.getHeaders().putSingle("Content-Type", ct); + } + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweContainerRequestFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweContainerRequestFilter.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweContainerRequestFilter.java new file mode 100644 index 0000000..449a3a3 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweContainerRequestFilter.java @@ -0,0 +1,46 @@ +/** + * 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.jaxrs; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import javax.annotation.Priority; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; + +import org.apache.cxf.rs.security.jose.jwe.JweDecryptionOutput; +import org.apache.cxf.rs.security.jose.jwt.JwtUtils; + +@PreMatching +@Priority(Priorities.JWE_SERVER_READ_PRIORITY) +public class JweContainerRequestFilter extends AbstractJweDecryptingFilter implements ContainerRequestFilter { + @Override + public void filter(ContainerRequestContext context) throws IOException { + JweDecryptionOutput out = decrypt(context.getEntityStream()); + byte[] bytes = out.getContent(); + context.setEntityStream(new ByteArrayInputStream(bytes)); + context.getHeaders().putSingle("Content-Length", Integer.toString(bytes.length)); + String ct = JwtUtils.checkContentType(out.getHeaders().getContentType(), getDefaultMediaType()); + if (ct != null) { + context.getHeaders().putSingle("Content-Type", ct); + } + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java new file mode 100644 index 0000000..2fac63e --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JweWriterInterceptor.java @@ -0,0 +1,200 @@ +/** + * 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.jaxrs; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.security.interfaces.RSAPublicKey; +import java.util.Properties; +import java.util.zip.DeflaterOutputStream; + +import javax.annotation.Priority; +import javax.crypto.SecretKey; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.ext.WriterInterceptor; +import javax.ws.rs.ext.WriterInterceptorContext; + +import org.apache.cxf.Bus; +import org.apache.cxf.helpers.IOUtils; +import org.apache.cxf.io.CachedOutputStream; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; +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.jose.jwa.Algorithm; +import org.apache.cxf.rs.security.jose.jwe.AesCbcHmacJweEncryption; +import org.apache.cxf.rs.security.jose.jwe.AesGcmWrapKeyEncryptionAlgorithm; +import org.apache.cxf.rs.security.jose.jwe.AesWrapKeyEncryptionAlgorithm; +import org.apache.cxf.rs.security.jose.jwe.JweCompactProducer; +import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider; +import org.apache.cxf.rs.security.jose.jwe.JweEncryptionState; +import org.apache.cxf.rs.security.jose.jwe.JweHeaders; +import org.apache.cxf.rs.security.jose.jwe.JweOutputStream; +import org.apache.cxf.rs.security.jose.jwe.KeyEncryptionAlgorithm; +import org.apache.cxf.rs.security.jose.jwe.RSAOaepKeyEncryptionAlgorithm; +import org.apache.cxf.rs.security.jose.jwe.WrappedKeyJweEncryption; +import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; +import org.apache.cxf.rs.security.jose.jwk.JwkUtils; +import org.apache.cxf.rs.security.jose.jwt.JwtHeadersWriter; +import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter; +import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; + +@Priority(Priorities.JWE_WRITE_PRIORITY) +public class JweWriterInterceptor implements WriterInterceptor { + private static final String RSSEC_ENCRYPTION_OUT_PROPS = "rs.security.encryption.out.properties"; + private static final String RSSEC_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; + private boolean useJweOutputStream; + private JwtHeadersWriter writer = new JwtTokenReaderWriter(); + @Override + public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException, WebApplicationException { + + //ctx.setMediaType(JAXRSUtils.toMediaType(JwtConstants.MEDIA_TYPE_JOSE_JSON)); + + OutputStream actualOs = ctx.getOutputStream(); + + JweEncryptionProvider theEncryptionProvider = getInitializedEncryptionProvider(); + + String ctString = null; + if (contentTypeRequired) { + MediaType mt = ctx.getMediaType(); + if (mt != null) { + if ("application".equals(mt.getType())) { + ctString = mt.getSubtype(); + } else { + ctString = JAXRSUtils.mediaTypeToString(mt); + } + } + } + + + if (useJweOutputStream) { + JweEncryptionState encryption = theEncryptionProvider.createJweEncryptionState(ctString); + try { + JweCompactProducer.startJweContent(actualOs, + encryption.getHeaders(), + writer, + encryption.getContentEncryptionKey(), + encryption.getIv()); + } catch (IOException ex) { + throw new SecurityException(ex); + } + OutputStream jweStream = new JweOutputStream(actualOs, encryption.getCipher(), + encryption.getAuthTagProducer()); + if (encryption.isCompressionSupported()) { + jweStream = new DeflaterOutputStream(jweStream); + } + + ctx.setOutputStream(jweStream); + ctx.proceed(); + jweStream.flush(); + } else { + CachedOutputStream cos = new CachedOutputStream(); + ctx.setOutputStream(cos); + ctx.proceed(); + String jweContent = theEncryptionProvider.encrypt(cos.getBytes(), ctString); + IOUtils.copy(new ByteArrayInputStream(jweContent.getBytes("UTF-8")), actualOs); + actualOs.flush(); + } + } + + protected JweEncryptionProvider getInitializedEncryptionProvider() { + if (encryptionProvider != null) { + return encryptionProvider; + } + Message m = JAXRSUtils.getCurrentMessage(); + String propLoc = + (String)MessageUtils.getContextualProperty(m, RSSEC_ENCRYPTION_OUT_PROPS, RSSEC_ENCRYPTION_PROPS); + if (propLoc == null) { + throw new SecurityException(); + } + Bus bus = m.getExchange().getBus(); + try { + KeyEncryptionAlgorithm keyEncryptionProvider = null; + String keyEncryptionAlgo = null; + Properties props = ResourceUtils.loadProperties(propLoc, bus); + if (JwkUtils.JWK_KEY_STORE_TYPE.equals(props.get(CryptoUtils.RSSEC_KEY_STORE_TYPE))) { + JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, JsonWebKey.KEY_OPER_ENCRYPT); + keyEncryptionAlgo = jwk.getAlgorithm(); + // TODO: Put it into some factory code + if (JsonWebKey.KEY_TYPE_RSA.equals(jwk.getKeyType())) { + keyEncryptionProvider = new RSAOaepKeyEncryptionAlgorithm(jwk.toRSAPublicKey(), + getKeyEncryptionAlgo(props, keyEncryptionAlgo)); + } else if (JsonWebKey.KEY_TYPE_OCTET.equals(jwk.getKeyType())) { + SecretKey key = jwk.toSecretKey(); + if (Algorithm.isAesKeyWrap(keyEncryptionAlgo)) { + keyEncryptionProvider = new AesWrapKeyEncryptionAlgorithm(key, keyEncryptionAlgo); + } else if (Algorithm.isAesGcmKeyWrap(keyEncryptionAlgo)) { + keyEncryptionProvider = new AesGcmWrapKeyEncryptionAlgorithm(key, keyEncryptionAlgo); + } + } else { + // TODO: support elliptic curve keys + } + + } else { + keyEncryptionProvider = new RSAOaepKeyEncryptionAlgorithm( + (RSAPublicKey)CryptoUtils.loadPublicKey(m, props), + getKeyEncryptionAlgo(props, keyEncryptionAlgo)); + } + if (keyEncryptionProvider == null) { + throw new SecurityException(); + } + + String contentEncryptionAlgo = props.getProperty(JSON_WEB_ENCRYPTION_CEK_ALGO_PROP); + JweHeaders headers = new JweHeaders(getKeyEncryptionAlgo(props, keyEncryptionAlgo), + contentEncryptionAlgo); + String compression = props.getProperty(JSON_WEB_ENCRYPTION_ZIP_ALGO_PROP); + if (compression != null) { + headers.setZipAlgorithm(compression); + } + boolean isAesHmac = Algorithm.isAesCbcHmac(contentEncryptionAlgo); + if (isAesHmac) { + return new AesCbcHmacJweEncryption( + keyEncryptionAlgo, contentEncryptionAlgo, keyEncryptionProvider); + } else { + return new WrappedKeyJweEncryption(headers, keyEncryptionProvider); + } + } catch (SecurityException ex) { + throw ex; + } catch (Exception ex) { + throw new SecurityException(ex); + } + } + private String getKeyEncryptionAlgo(Properties props, String algo) { + return algo == null ? props.getProperty(JSON_WEB_ENCRYPTION_KEY_ALGO_PROP) : algo; + } + public void setUseJweOutputStream(boolean useJweOutputStream) { + this.useJweOutputStream = useJweOutputStream; + } + + public void setWriter(JwtHeadersWriter writer) { + this.writer = writer; + } + + public void setEncryptionProvider(JweEncryptionProvider encryptionProvider) { + this.encryptionProvider = encryptionProvider; + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsClientResponseFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsClientResponseFilter.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsClientResponseFilter.java new file mode 100644 index 0000000..aeaa742 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsClientResponseFilter.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.jaxrs; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import javax.annotation.Priority; +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientResponseContext; +import javax.ws.rs.client.ClientResponseFilter; + +import org.apache.cxf.helpers.IOUtils; +import org.apache.cxf.rs.security.jose.jws.JwsCompactConsumer; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; +import org.apache.cxf.rs.security.jose.jwt.JwtUtils; + +@Priority(Priorities.JWS_CLIENT_READ_PRIORITY) +public class JwsClientResponseFilter extends AbstractJwsReaderProvider implements ClientResponseFilter { + @Override + public void filter(ClientRequestContext req, ClientResponseContext res) throws IOException { + JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier(); + JwsCompactConsumer p = new JwsCompactConsumer(IOUtils.readStringFromStream(res.getEntityStream()), + getSigProperties()); + p.verifySignatureWith(theSigVerifier); + byte[] bytes = p.getDecodedJwsPayloadBytes(); + res.setEntityStream(new ByteArrayInputStream(bytes)); + res.getHeaders().putSingle("Content-Length", Integer.toString(bytes.length)); + String ct = JwtUtils.checkContentType(p.getJwtHeaders().getContentType(), getDefaultMediaType()); + if (ct != null) { + res.getHeaders().putSingle("Content-Type", ct); + } + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsContainerRequestFilter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsContainerRequestFilter.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsContainerRequestFilter.java new file mode 100644 index 0000000..d80aa38 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsContainerRequestFilter.java @@ -0,0 +1,53 @@ +/** + * 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.jaxrs; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import javax.annotation.Priority; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; + +import org.apache.cxf.helpers.IOUtils; +import org.apache.cxf.rs.security.jose.jws.JwsCompactConsumer; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; +import org.apache.cxf.rs.security.jose.jwt.JwtUtils; + +@PreMatching +@Priority(Priorities.JWS_SERVER_READ_PRIORITY) +public class JwsContainerRequestFilter extends AbstractJwsReaderProvider implements ContainerRequestFilter { + @Override + public void filter(ContainerRequestContext context) throws IOException { + + JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier(); + JwsCompactConsumer p = new JwsCompactConsumer(IOUtils.readStringFromStream(context.getEntityStream()), + getSigProperties()); + p.verifySignatureWith(theSigVerifier); + byte[] bytes = p.getDecodedJwsPayloadBytes(); + context.setEntityStream(new ByteArrayInputStream(bytes)); + context.getHeaders().putSingle("Content-Length", Integer.toString(bytes.length)); + + String ct = JwtUtils.checkContentType(p.getJwtHeaders().getContentType(), getDefaultMediaType()); + if (ct != null) { + context.getHeaders().putSingle("Content-Type", ct); + } + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJwtMessageBodyReader.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJwtMessageBodyReader.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJwtMessageBodyReader.java new file mode 100644 index 0000000..831d114 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJwtMessageBodyReader.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.jaxrs; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; + +import org.apache.cxf.helpers.IOUtils; +import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; +import org.apache.cxf.rs.security.jose.jwt.JwtToken; + +public class JwsJwtMessageBodyReader extends AbstractJwsReaderProvider + implements MessageBodyReader { + + @Override + public boolean isReadable(Class cls, Type type, Annotation[] anns, MediaType mt) { + return cls == JwtToken.class; + } + + @Override + public JwtToken readFrom(Class cls, Type t, Annotation[] anns, MediaType mt, + MultivaluedMap headers, InputStream is) throws IOException, + WebApplicationException { + JwsSignatureVerifier theSigVerifier = getInitializedSigVerifier(); + JwsJwtCompactConsumer p = new JwsJwtCompactConsumer(IOUtils.readStringFromStream(is), + getSigProperties()); + p.verifySignatureWith(theSigVerifier); + return p.getJwtToken(); + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJwtMessageBodyWriter.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJwtMessageBodyWriter.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJwtMessageBodyWriter.java new file mode 100644 index 0000000..17b11f5 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsJwtMessageBodyWriter.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.jaxrs; + +import java.io.IOException; +import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyWriter; + +import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactProducer; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jwt.JwtConstants; +import org.apache.cxf.rs.security.jose.jwt.JwtHeaders; +import org.apache.cxf.rs.security.jose.jwt.JwtToken; + +public class JwsJwtMessageBodyWriter extends AbstractJwsWriterProvider + implements MessageBodyWriter { + + @Override + public long getSize(JwtToken token, Class cls, Type type, Annotation[] anns, MediaType mt) { + return -1; + } + + @Override + public boolean isWriteable(Class cls, Type type, Annotation[] anns, MediaType mt) { + return cls == JwtToken.class; + } + + @Override + public void writeTo(JwtToken token, Class cls, Type type, Annotation[] anns, MediaType mt, + MultivaluedMap headers, OutputStream os) throws IOException, + WebApplicationException { + JwsJwtCompactProducer p = new JwsJwtCompactProducer(token); + JwtHeaders jwtHeaders = new JwtHeaders(); + JwsSignatureProvider sigProvider = getInitializedSigProvider(jwtHeaders); + jwtHeaders.setContentType(JwtConstants.TYPE_JWT); + writeJws(p, sigProvider, os); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java new file mode 100644 index 0000000..c99ec15 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/JwsWriterInterceptor.java @@ -0,0 +1,98 @@ +/** + * 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.jaxrs; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.annotation.Priority; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.ext.WriterInterceptor; +import javax.ws.rs.ext.WriterInterceptorContext; + +import org.apache.cxf.io.CachedOutputStream; +import org.apache.cxf.jaxrs.utils.JAXRSUtils; +import org.apache.cxf.rs.security.jose.jws.JwsCompactProducer; +import org.apache.cxf.rs.security.jose.jws.JwsOutputStream; +import org.apache.cxf.rs.security.jose.jws.JwsSignature; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jwt.JwtHeaders; +import org.apache.cxf.rs.security.jose.jwt.JwtHeadersWriter; +import org.apache.cxf.rs.security.jose.jwt.JwtTokenReaderWriter; +import org.apache.cxf.rs.security.oauth2.utils.Base64UrlOutputStream; +import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility; + +@Priority(Priorities.JWS_WRITE_PRIORITY) +public class JwsWriterInterceptor extends AbstractJwsWriterProvider implements WriterInterceptor { + private boolean contentTypeRequired = true; + private boolean useJwsOutputStream; + private JwtHeadersWriter writer = new JwtTokenReaderWriter(); + @Override + public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException, WebApplicationException { + //ctx.setMediaType(JAXRSUtils.toMediaType(JwtConstants.MEDIA_TYPE_JOSE_JSON)); + JwtHeaders headers = new JwtHeaders(); + JwsSignatureProvider sigProvider = getInitializedSigProvider(headers); + setContentTypeIfNeeded(headers, ctx); + + OutputStream actualOs = ctx.getOutputStream(); + if (useJwsOutputStream) { + JwsSignature jwsSignature = sigProvider.createJwsSignature(headers); + JwsOutputStream jwsStream = new JwsOutputStream(actualOs, jwsSignature); + byte[] headerBytes = writer.headersToJson(headers).getBytes("UTF-8"); + Base64UrlUtility.encodeAndStream(headerBytes, 0, headerBytes.length, jwsStream); + jwsStream.write(new byte[]{'.'}); + + Base64UrlOutputStream base64Stream = new Base64UrlOutputStream(jwsStream); + ctx.setOutputStream(base64Stream); + ctx.proceed(); + base64Stream.flush(); + jwsStream.flush(); + } else { + CachedOutputStream cos = new CachedOutputStream(); + ctx.setOutputStream(cos); + ctx.proceed(); + JwsCompactProducer p = new JwsCompactProducer(headers, new String(cos.getBytes(), "UTF-8")); + writeJws(p, sigProvider, actualOs); + } + } + + public void setContentTypeRequired(boolean contentTypeRequired) { + this.contentTypeRequired = contentTypeRequired; + } + + public void setUseJwsOutputStream(boolean useJwsOutputStream) { + this.useJwsOutputStream = useJwsOutputStream; + } + public void setWriter(JwtHeadersWriter writer) { + this.writer = writer; + } + private void setContentTypeIfNeeded(JwtHeaders headers, WriterInterceptorContext ctx) { + if (contentTypeRequired) { + MediaType mt = ctx.getMediaType(); + if (mt != null) { + 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/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/Priorities.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/Priorities.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/Priorities.java new file mode 100644 index 0000000..fc48ebc --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jaxrs/Priorities.java @@ -0,0 +1,31 @@ +/** + * 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.jaxrs; + +public final class Priorities { + public static final int JWE_SERVER_READ_PRIORITY = 1000; + public static final int JWE_WRITE_PRIORITY = 1000; + public static final int JWE_CLIENT_READ_PRIORITY = 1001; + public static final int JWS_SERVER_READ_PRIORITY = 1001; + public static final int JWS_WRITE_PRIORITY = 1001; + public static final int JWS_CLIENT_READ_PRIORITY = 1000; + private Priorities() { + + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java new file mode 100644 index 0000000..800bd1a --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwa/Algorithm.java @@ -0,0 +1,209 @@ +/** + * 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; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.cxf.rs.security.jose.jwt.JwtConstants; + + + + +public enum Algorithm { + // Signature + HmacSHA256(JwtConstants.HMAC_SHA_256_ALGO, 256), + HmacSHA384(JwtConstants.HMAC_SHA_384_ALGO, 384), + HmacSHA512(JwtConstants.HMAC_SHA_512_ALGO, 512), + + SHA256withRSA(JwtConstants.RS_SHA_256_ALGO, 256), + SHA384withRSA(JwtConstants.RS_SHA_384_ALGO, 384), + SHA512withRSA(JwtConstants.RS_SHA_512_ALGO, 512), + + SHA256withECDSA(JwtConstants.ES_SHA_256_ALGO, 256), + SHA384withECDSA(JwtConstants.ES_SHA_384_ALGO, 384), + SHA512withECDSA(JwtConstants.ES_SHA_512_ALGO, 512), + + // Key Encryption + RSA_OAEP(JwtConstants.RSA_OAEP_ALGO, "RSA/ECB/OAEPWithSHA-1AndMGF1Padding", -1), + RSA_OAEP_256(JwtConstants.RSA_OAEP_256_ALGO, "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", -1), + RSA_1_5(JwtConstants.RSA_1_5_ALGO, "RSA/ECB/PKCS1Padding", -1), + A128KW(JwtConstants.A128KW_ALGO, "AESWrap", 128), + A192KW(JwtConstants.A192KW_ALGO, "AESWrap", 192), + A256KW(JwtConstants.A256KW_ALGO, "AESWrap", 256), + 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), + A256GCM(JwtConstants.A256GCM_ALGO, "AES/GCM/NoPadding", 256), + A128CBC_HS256(JwtConstants.A128CBC_HS256_ALGO, "AES/CBC/PKCS7Padding", 128), + A192CBC_HS384(JwtConstants.A192CBC_HS384_ALGO, "AES/CBC/PKCS7Padding", 192), + A256CBC_HS512(JwtConstants.A256CBC_HS512_ALGO, "AES/CBC/PKCS7Padding", 256); + + public static final String HMAC_SHA_256_JAVA = "HmacSHA256"; + public static final String HMAC_SHA_384_JAVA = "HmacSHA384"; + public static final String HMAC_SHA_512_JAVA = "HmacSHA512"; + public static final String RS_SHA_256_JAVA = "SHA256withRSA"; + public static final String RS_SHA_384_JAVA = "SHA384withRSA"; + public static final String RS_SHA_512_JAVA = "SHA512withRSA"; + public static final String ES_SHA_256_JAVA = "SHA256withECDSA"; + public static final String ES_SHA_384_JAVA = "SHA384withECDSA"; + public static final String ES_SHA_512_JAVA = "SHA512withECDSA"; + public static final String RSA_OAEP_ALGO_JAVA = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"; + public static final String RSA_OAEP_256_ALGO_JAVA = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"; + public static final String RSA_1_5_ALGO_JAVA = "RSA/ECB/PKCS1Padding"; + public static final String AES_ALGO_JAVA = "AES"; + public static final String AES_WRAP_ALGO_JAVA = "AESWrap"; + public static final String AES_GCM_ALGO_JAVA = "AES/GCM/NoPadding"; + public static final String AES_CBC_ALGO_JAVA = "AES/CBC/PKCS7Padding"; + + private static final Map JAVA_TO_JWT_NAMES; + private static final Map JWT_TO_JAVA_NAMES; + static { + JAVA_TO_JWT_NAMES = new HashMap(); + JAVA_TO_JWT_NAMES.put(HMAC_SHA_256_JAVA, JwtConstants.HMAC_SHA_256_ALGO); + JAVA_TO_JWT_NAMES.put(HMAC_SHA_384_JAVA, JwtConstants.HMAC_SHA_384_ALGO); + JAVA_TO_JWT_NAMES.put(HMAC_SHA_512_JAVA, JwtConstants.HMAC_SHA_512_ALGO); + JAVA_TO_JWT_NAMES.put(RS_SHA_256_JAVA, JwtConstants.RS_SHA_256_ALGO); + JAVA_TO_JWT_NAMES.put(RS_SHA_384_JAVA, JwtConstants.RS_SHA_384_ALGO); + JAVA_TO_JWT_NAMES.put(RS_SHA_512_JAVA, JwtConstants.RS_SHA_512_ALGO); + JAVA_TO_JWT_NAMES.put(ES_SHA_256_JAVA, JwtConstants.ES_SHA_256_ALGO); + JAVA_TO_JWT_NAMES.put(ES_SHA_384_JAVA, JwtConstants.ES_SHA_384_ALGO); + JAVA_TO_JWT_NAMES.put(ES_SHA_512_JAVA, JwtConstants.ES_SHA_512_ALGO); + JAVA_TO_JWT_NAMES.put(RSA_OAEP_ALGO_JAVA, JwtConstants.RSA_OAEP_ALGO); + JAVA_TO_JWT_NAMES.put(RSA_OAEP_256_ALGO_JAVA, JwtConstants.RSA_OAEP_256_ALGO); + JAVA_TO_JWT_NAMES.put(RSA_1_5_ALGO_JAVA, JwtConstants.RSA_1_5_ALGO); + 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_HS384_ALGO); + JAVA_TO_JWT_NAMES.put(AES_CBC_ALGO_JAVA, JwtConstants.A256CBC_HS512_ALGO); + JWT_TO_JAVA_NAMES = new HashMap(); + JWT_TO_JAVA_NAMES.put(JwtConstants.HMAC_SHA_256_ALGO, HMAC_SHA_256_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.HMAC_SHA_384_ALGO, HMAC_SHA_384_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.HMAC_SHA_512_ALGO, HMAC_SHA_512_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.RS_SHA_256_ALGO, RS_SHA_256_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.RS_SHA_384_ALGO, RS_SHA_384_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.RS_SHA_512_ALGO, RS_SHA_512_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.ES_SHA_256_ALGO, ES_SHA_256_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.ES_SHA_384_ALGO, ES_SHA_384_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.ES_SHA_512_ALGO, ES_SHA_512_JAVA); + 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); + JWT_TO_JAVA_NAMES.put(JwtConstants.A256GCMKW_ALGO, AES_GCM_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.A192GCMKW_ALGO, AES_GCM_ALGO_JAVA); + JWT_TO_JAVA_NAMES.put(JwtConstants.A128GCMKW_ALGO, AES_GCM_ALGO_JAVA); + 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; + private final int keySizeBits; + + private Algorithm(String jwtName, int keySizeBits) { + this(jwtName, null, keySizeBits); + } + private Algorithm(String jwtName, String javaName, int keySizeBits) { + this.jwtName = jwtName; + this.javaName = javaName; + this.keySizeBits = keySizeBits; + } + + public String getJwtName() { + return jwtName; + } + + public String getJavaName() { + return javaName == null ? name() : javaName; + } + + public String getJavaAlgoName() { + return stripAlgoProperties(getJavaName()); + } + + public int getKeySizeBits() { + return keySizeBits; + } + + public static String toJwtName(String javaName, int keyBitSize) { + //TODO: perhaps a key should be a name+keysize pair + String name = JAVA_TO_JWT_NAMES.get(javaName); + if (name == null && javaName.startsWith(AES_ALGO_JAVA)) { + name = "A" + keyBitSize + "GCM"; + } + return name; + } + public static String toJavaName(String jwtName) { + return JWT_TO_JAVA_NAMES.get(jwtName); + } + public static String toJavaAlgoNameOnly(String jwtName) { + return stripAlgoProperties(toJavaName(jwtName)); + } + public static String stripAlgoProperties(String javaName) { + if (javaName != null) { + int index = javaName.indexOf('/'); + if (index != -1) { + javaName = javaName.substring(0, index); + } + } + return javaName; + } + public static boolean isAesKeyWrap(String algo) { + return JwtConstants.A128KW_ALGO.equals(algo) + || JwtConstants.A192KW_ALGO.equals(algo) + || JwtConstants.A256KW_ALGO.equals(algo); + } + public static boolean isAesGcmKeyWrap(String algo) { + return JwtConstants.A128GCM_ALGO.equals(algo) + || JwtConstants.A192GCMKW_ALGO.equals(algo) + || JwtConstants.A256GCMKW_ALGO.equals(algo); + } + public static boolean isHmacSign(String algo) { + return JwtConstants.HMAC_SHA_256_ALGO.equals(algo) + || JwtConstants.HMAC_SHA_384_ALGO.equals(algo) + || JwtConstants.HMAC_SHA_512_ALGO.equals(algo); + } + public static boolean isAesCbcHmac(String algo) { + return JwtConstants.A128CBC_HS256_ALGO.equals(algo) + || JwtConstants.A192CBC_HS384_ALGO.equals(algo) + || JwtConstants.A256CBC_HS512_ALGO.equals(algo); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java new file mode 100644 index 0000000..ef1fbbb --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/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 javax.crypto.SecretKey; + +import org.apache.cxf.rs.security.oauth2.utils.crypto.CryptoUtils; + + +public abstract class AbstractContentEncryptionAlgorithm extends AbstractContentEncryptionCipherProperties + implements ContentEncryptionAlgorithm { + private static final int DEFAULT_IV_SIZE = 128; + private byte[] cek; + private byte[] iv; + private AtomicInteger providedIvUsageCount; + protected AbstractContentEncryptionAlgorithm(SecretKey key, byte[] iv) { + this(key.getEncoded(), iv); + } + protected AbstractContentEncryptionAlgorithm(byte[] cek, byte[] iv) { + 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) { + throw new SecurityException(); + } else { + return iv; + } + } + protected int getIvSize() { + return DEFAULT_IV_SIZE; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/707d938a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionCipherProperties.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionCipherProperties.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionCipherProperties.java new file mode 100644 index 0000000..291b8cb --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionCipherProperties.java @@ -0,0 +1,39 @@ +/** + * 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.oauth2.utils.crypto.CryptoUtils; + + +public abstract class AbstractContentEncryptionCipherProperties implements ContentEncryptionCipherProperties { + private static final int DEFAULT_AUTH_TAG_LENGTH = 128; + private int authTagLen = DEFAULT_AUTH_TAG_LENGTH; + + public AlgorithmParameterSpec getAlgorithmParameterSpec(byte[] theIv) { + return CryptoUtils.getContentEncryptionCipherSpec(getAuthTagLen(), theIv); + } + public byte[] getAdditionalAuthenticationData(String headersJson) { + return JweHeaders.toCipherAdditionalAuthData(headersJson); + } + protected int getAuthTagLen() { + return authTagLen; + } +}