Splitting current jose module into jose-core + jose-jaxrs
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/66a81773 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/66a81773 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/66a81773 Branch: refs/heads/master Commit: 66a8177301f663ee8e635dea395eed2adf0a4751 Parents: 88fb9ee Author: Colm O hEigeartaigh <[email protected]> Authored: Tue Oct 13 11:10:18 2015 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Tue Oct 13 11:10:18 2015 +0100 ---------------------------------------------------------------------- rt/rs/security/jose/jose-core/pom.xml | 69 ++ .../rs/security/jose/AbstractJoseConsumer.java | 51 ++ .../rs/security/jose/AbstractJoseProducer.java | 51 ++ .../cxf/rs/security/jose/JoseConstants.java | 54 ++ .../cxf/rs/security/jose/JoseException.java | 33 + .../cxf/rs/security/jose/JoseHeaders.java | 179 +++++ .../apache/cxf/rs/security/jose/JoseType.java | 43 ++ .../apache/cxf/rs/security/jose/JoseUtils.java | 200 ++++++ .../jose/common/KeyManagementUtils.java | 390 +++++++++++ .../jose/common/PrivateKeyPasswordProvider.java | 25 + .../rs/security/jose/jwa/AlgorithmUtils.java | 271 ++++++++ .../rs/security/jose/jwa/ContentAlgorithm.java | 70 ++ .../cxf/rs/security/jose/jwa/KeyAlgorithm.java | 78 +++ .../security/jose/jwa/SignatureAlgorithm.java | 83 +++ .../jwe/AbstractContentEncryptionAlgorithm.java | 60 ++ ...stractContentEncryptionCipherProperties.java | 51 ++ .../jose/jwe/AbstractJweDecryption.java | 113 ++++ .../jose/jwe/AbstractJweEncryption.java | 243 +++++++ .../jwe/AbstractWrapKeyEncryptionAlgorithm.java | 105 +++ .../jose/jwe/AesCbcHmacJweDecryption.java | 91 +++ .../jose/jwe/AesCbcHmacJweEncryption.java | 175 +++++ .../jwe/AesGcmContentDecryptionAlgorithm.java | 41 ++ .../jwe/AesGcmContentEncryptionAlgorithm.java | 55 ++ .../jwe/AesGcmWrapKeyDecryptionAlgorithm.java | 78 +++ .../jwe/AesGcmWrapKeyEncryptionAlgorithm.java | 65 ++ .../jose/jwe/AesWrapKeyDecryptionAlgorithm.java | 59 ++ .../jose/jwe/AesWrapKeyEncryptionAlgorithm.java | 48 ++ .../jose/jwe/AuthenticationTagProducer.java | 24 + .../jose/jwe/ContentDecryptionProvider.java | 24 + .../jwe/ContentEncryptionCipherProperties.java | 30 + .../jose/jwe/ContentEncryptionProvider.java | 26 + .../jose/jwe/DirectKeyDecryptionAlgorithm.java | 56 ++ .../jose/jwe/DirectKeyEncryptionAlgorithm.java | 42 ++ .../jose/jwe/DirectKeyJweDecryption.java | 32 + .../jose/jwe/DirectKeyJweEncryption.java | 27 + .../jwe/EcdhAesWrapKeyDecryptionAlgorithm.java | 54 ++ .../jwe/EcdhAesWrapKeyEncryptionAlgorithm.java | 82 +++ .../jose/jwe/EcdhDirectKeyJweDecryption.java | 58 ++ .../jose/jwe/EcdhDirectKeyJweEncryption.java | 118 ++++ .../security/jose/jwe/JweCompactConsumer.java | 125 ++++ .../security/jose/jwe/JweCompactProducer.java | 129 ++++ .../cxf/rs/security/jose/jwe/JweDecryption.java | 28 + .../security/jose/jwe/JweDecryptionInput.java | 68 ++ .../security/jose/jwe/JweDecryptionOutput.java | 45 ++ .../jose/jwe/JweDecryptionProvider.java | 26 + .../cxf/rs/security/jose/jwe/JweEncryption.java | 29 + .../security/jose/jwe/JweEncryptionInput.java | 90 +++ .../security/jose/jwe/JweEncryptionOutput.java | 78 +++ .../jose/jwe/JweEncryptionProvider.java | 33 + .../cxf/rs/security/jose/jwe/JweException.java | 53 ++ .../cxf/rs/security/jose/jwe/JweHeaders.java | 118 ++++ .../rs/security/jose/jwe/JweJsonConsumer.java | 191 ++++++ .../jose/jwe/JweJsonEncryptionEntry.java | 60 ++ .../rs/security/jose/jwe/JweJsonProducer.java | 192 ++++++ .../jose/jwe/JweJwtCompactConsumer.java | 63 ++ .../jose/jwe/JweJwtCompactProducer.java | 60 ++ .../rs/security/jose/jwe/JweKeyProperties.java | 29 + .../rs/security/jose/jwe/JweOutputStream.java | 148 +++++ .../cxf/rs/security/jose/jwe/JweUtils.java | 633 ++++++++++++++++++ .../jose/jwe/KeyDecryptionProvider.java | 27 + .../jose/jwe/KeyEncryptionProvider.java | 27 + .../PbesHmacAesWrapKeyDecryptionAlgorithm.java | 77 +++ .../PbesHmacAesWrapKeyEncryptionAlgorithm.java | 192 ++++++ .../jose/jwe/RSAKeyDecryptionAlgorithm.java | 46 ++ .../jose/jwe/RSAKeyEncryptionAlgorithm.java | 34 + .../jose/jwe/WrappedKeyDecryptionAlgorithm.java | 97 +++ .../jose/jwk/DefaultJwkReaderWriter.java | 49 ++ .../cxf/rs/security/jose/jwk/JsonWebKey.java | 180 +++++ .../cxf/rs/security/jose/jwk/JsonWebKeys.java | 130 ++++ .../cxf/rs/security/jose/jwk/JwkException.java | 35 + .../rs/security/jose/jwk/JwkReaderWriter.java | 27 + .../cxf/rs/security/jose/jwk/JwkUtils.java | 532 +++++++++++++++ .../cxf/rs/security/jose/jwk/KeyOperation.java | 46 ++ .../cxf/rs/security/jose/jwk/KeyType.java | 44 ++ .../cxf/rs/security/jose/jwk/PublicKeyUse.java | 46 ++ .../jose/jws/AbstractJwsSignatureProvider.java | 76 +++ .../jose/jws/EcDsaJwsSignatureProvider.java | 110 +++ .../jose/jws/EcDsaJwsSignatureVerifier.java | 81 +++ .../jose/jws/HmacJwsSignatureProvider.java | 76 +++ .../jose/jws/HmacJwsSignatureVerifier.java | 85 +++ .../security/jose/jws/JwsCompactConsumer.java | 149 +++++ .../security/jose/jws/JwsCompactProducer.java | 136 ++++ .../cxf/rs/security/jose/jws/JwsException.java | 49 ++ .../cxf/rs/security/jose/jws/JwsHeaders.java | 66 ++ .../rs/security/jose/jws/JwsJsonConsumer.java | 189 ++++++ .../security/jose/jws/JwsJsonOutputStream.java | 100 +++ .../rs/security/jose/jws/JwsJsonProducer.java | 212 ++++++ .../jose/jws/JwsJsonSignatureEntry.java | 163 +++++ .../jose/jws/JwsJwtCompactConsumer.java | 43 ++ .../jose/jws/JwsJwtCompactProducer.java | 44 ++ .../rs/security/jose/jws/JwsOutputStream.java | 59 ++ .../cxf/rs/security/jose/jws/JwsSignature.java | 25 + .../security/jose/jws/JwsSignatureProvider.java | 31 + .../security/jose/jws/JwsSignatureVerifier.java | 26 + .../cxf/rs/security/jose/jws/JwsUtils.java | 401 +++++++++++ .../jose/jws/NoneJwsSignatureProvider.java | 55 ++ .../jose/jws/NoneJwsSignatureVerifier.java | 36 + .../jws/PrivateKeyJwsSignatureProvider.java | 91 +++ .../jose/jws/PublicKeyJwsSignatureVerifier.java | 80 +++ .../jose/jwt/AbstractJoseJwtConsumer.java | 96 +++ .../jose/jwt/AbstractJoseJwtProducer.java | 84 +++ .../cxf/rs/security/jose/jwt/JwtClaims.java | 102 +++ .../cxf/rs/security/jose/jwt/JwtConstants.java | 38 ++ .../cxf/rs/security/jose/jwt/JwtException.java | 35 + .../cxf/rs/security/jose/jwt/JwtToken.java | 56 ++ .../security/jose/jwt/JwtTokenReaderWriter.java | 55 ++ .../cxf/rs/security/jose/jwt/JwtUtils.java | 107 +++ .../jose/cookbook/JwkJoseCookBookTest.java | 187 ++++++ .../jose/cookbook/JwsJoseCookBookTest.java | 665 +++++++++++++++++++ .../jose/cookbook/cookbookPrivateSet.txt | 24 + .../jose/cookbook/cookbookPublicSet.txt | 16 + .../jose/cookbook/cookbookSecretSet.txt | 16 + .../jose/jwe/JweCompactReaderWriterTest.java | 264 ++++++++ .../security/jose/jwe/JweJsonConsumerTest.java | 167 +++++ .../security/jose/jwe/JweJsonProducerTest.java | 310 +++++++++ .../jose/jwe/JwePbeHmacAesWrapTest.java | 77 +++ .../rs/security/jose/jwk/JsonWebKeyTest.java | 231 +++++++ .../cxf/rs/security/jose/jwk/JwkUtilsTest.java | 94 +++ .../cxf/rs/security/jose/jwk/jwkPrivateSet.txt | 23 + .../cxf/rs/security/jose/jwk/jwkPublicSet.txt | 27 + .../cxf/rs/security/jose/jwk/jwkSecretSet.txt | 13 + .../security/jose/jws/JwsCompactHeaderTest.java | 203 ++++++ .../jose/jws/JwsCompactReaderWriterTest.java | 307 +++++++++ .../security/jose/jws/JwsJsonConsumerTest.java | 89 +++ .../security/jose/jws/JwsJsonProducerTest.java | 126 ++++ .../jose/jws/jwkPublicJsonConsumerSet.txt | 18 + rt/rs/security/jose/jose-jaxrs/pom.xml | 61 ++ .../jose/jaxrs/AbstractJweDecryptingFilter.java | 62 ++ .../jaxrs/AbstractJwsJsonReaderProvider.java | 91 +++ .../jaxrs/AbstractJwsJsonWriterProvider.java | 86 +++ .../jose/jaxrs/AbstractJwsReaderProvider.java | 48 ++ .../jose/jaxrs/AbstractJwsWriterProvider.java | 58 ++ .../jose/jaxrs/JsonWebKeysProvider.java | 48 ++ .../jose/jaxrs/JweClientResponseFilter.java | 46 ++ .../jose/jaxrs/JweContainerRequestFilter.java | 50 ++ .../jose/jaxrs/JweWriterInterceptor.java | 133 ++++ .../jose/jaxrs/JwsClientResponseFilter.java | 53 ++ .../jose/jaxrs/JwsContainerRequestFilter.java | 61 ++ .../jose/jaxrs/JwsJsonClientResponseFilter.java | 59 ++ .../jaxrs/JwsJsonContainerRequestFilter.java | 65 ++ .../jose/jaxrs/JwsJsonWriterInterceptor.java | 138 ++++ .../jose/jaxrs/JwsWriterInterceptor.java | 107 +++ .../jaxrs/JwtAuthenticationClientFilter.java | 83 +++ .../jose/jaxrs/JwtAuthenticationFilter.java | 113 ++++ .../jose/jaxrs/JwtTokenSecurityContext.java | 81 +++ .../cxf/rs/security/jose/jaxrs/Priorities.java | 34 + rt/rs/security/jose/pom.xml | 52 +- .../rs/security/jose/AbstractJoseConsumer.java | 51 -- .../rs/security/jose/AbstractJoseProducer.java | 51 -- .../cxf/rs/security/jose/JoseConstants.java | 54 -- .../cxf/rs/security/jose/JoseException.java | 33 - .../cxf/rs/security/jose/JoseHeaders.java | 179 ----- .../apache/cxf/rs/security/jose/JoseType.java | 43 -- .../apache/cxf/rs/security/jose/JoseUtils.java | 125 ---- .../jose/jaxrs/AbstractJweDecryptingFilter.java | 62 -- .../jaxrs/AbstractJwsJsonReaderProvider.java | 91 --- .../jaxrs/AbstractJwsJsonWriterProvider.java | 86 --- .../jose/jaxrs/AbstractJwsReaderProvider.java | 48 -- .../jose/jaxrs/AbstractJwsWriterProvider.java | 58 -- .../jose/jaxrs/JsonWebKeysProvider.java | 48 -- .../jose/jaxrs/JweClientResponseFilter.java | 46 -- .../jose/jaxrs/JweContainerRequestFilter.java | 50 -- .../jose/jaxrs/JweWriterInterceptor.java | 133 ---- .../jose/jaxrs/JwsClientResponseFilter.java | 53 -- .../jose/jaxrs/JwsContainerRequestFilter.java | 61 -- .../jose/jaxrs/JwsJsonClientResponseFilter.java | 59 -- .../jaxrs/JwsJsonContainerRequestFilter.java | 65 -- .../jose/jaxrs/JwsJsonWriterInterceptor.java | 138 ---- .../jose/jaxrs/JwsWriterInterceptor.java | 107 --- .../jaxrs/JwtAuthenticationClientFilter.java | 83 --- .../jose/jaxrs/JwtAuthenticationFilter.java | 113 ---- .../jose/jaxrs/JwtTokenSecurityContext.java | 81 --- .../security/jose/jaxrs/KeyManagementUtils.java | 389 ----------- .../cxf/rs/security/jose/jaxrs/Priorities.java | 34 - .../jose/jaxrs/PrivateKeyPasswordProvider.java | 25 - .../rs/security/jose/jwa/AlgorithmUtils.java | 271 -------- .../rs/security/jose/jwa/ContentAlgorithm.java | 70 -- .../cxf/rs/security/jose/jwa/KeyAlgorithm.java | 78 --- .../security/jose/jwa/SignatureAlgorithm.java | 83 --- .../jwe/AbstractContentEncryptionAlgorithm.java | 60 -- ...stractContentEncryptionCipherProperties.java | 51 -- .../jose/jwe/AbstractJweDecryption.java | 113 ---- .../jose/jwe/AbstractJweEncryption.java | 243 ------- .../jwe/AbstractWrapKeyEncryptionAlgorithm.java | 105 --- .../jose/jwe/AesCbcHmacJweDecryption.java | 91 --- .../jose/jwe/AesCbcHmacJweEncryption.java | 175 ----- .../jwe/AesGcmContentDecryptionAlgorithm.java | 41 -- .../jwe/AesGcmContentEncryptionAlgorithm.java | 55 -- .../jwe/AesGcmWrapKeyDecryptionAlgorithm.java | 78 --- .../jwe/AesGcmWrapKeyEncryptionAlgorithm.java | 65 -- .../jose/jwe/AesWrapKeyDecryptionAlgorithm.java | 59 -- .../jose/jwe/AesWrapKeyEncryptionAlgorithm.java | 48 -- .../jose/jwe/AuthenticationTagProducer.java | 24 - .../jose/jwe/ContentDecryptionProvider.java | 24 - .../jwe/ContentEncryptionCipherProperties.java | 30 - .../jose/jwe/ContentEncryptionProvider.java | 26 - .../jose/jwe/DirectKeyDecryptionAlgorithm.java | 56 -- .../jose/jwe/DirectKeyEncryptionAlgorithm.java | 42 -- .../jose/jwe/DirectKeyJweDecryption.java | 32 - .../jose/jwe/DirectKeyJweEncryption.java | 27 - .../jwe/EcdhAesWrapKeyDecryptionAlgorithm.java | 54 -- .../jwe/EcdhAesWrapKeyEncryptionAlgorithm.java | 82 --- .../jose/jwe/EcdhDirectKeyJweDecryption.java | 58 -- .../jose/jwe/EcdhDirectKeyJweEncryption.java | 118 ---- .../security/jose/jwe/JweCompactConsumer.java | 125 ---- .../security/jose/jwe/JweCompactProducer.java | 129 ---- .../cxf/rs/security/jose/jwe/JweDecryption.java | 28 - .../security/jose/jwe/JweDecryptionInput.java | 68 -- .../security/jose/jwe/JweDecryptionOutput.java | 45 -- .../jose/jwe/JweDecryptionProvider.java | 26 - .../cxf/rs/security/jose/jwe/JweEncryption.java | 29 - .../security/jose/jwe/JweEncryptionInput.java | 90 --- .../security/jose/jwe/JweEncryptionOutput.java | 78 --- .../jose/jwe/JweEncryptionProvider.java | 33 - .../cxf/rs/security/jose/jwe/JweException.java | 53 -- .../cxf/rs/security/jose/jwe/JweHeaders.java | 118 ---- .../rs/security/jose/jwe/JweJsonConsumer.java | 191 ------ .../jose/jwe/JweJsonEncryptionEntry.java | 60 -- .../rs/security/jose/jwe/JweJsonProducer.java | 192 ------ .../jose/jwe/JweJwtCompactConsumer.java | 63 -- .../jose/jwe/JweJwtCompactProducer.java | 60 -- .../rs/security/jose/jwe/JweKeyProperties.java | 29 - .../rs/security/jose/jwe/JweOutputStream.java | 148 ----- .../cxf/rs/security/jose/jwe/JweUtils.java | 634 ------------------ .../jose/jwe/KeyDecryptionProvider.java | 27 - .../jose/jwe/KeyEncryptionProvider.java | 27 - .../PbesHmacAesWrapKeyDecryptionAlgorithm.java | 77 --- .../PbesHmacAesWrapKeyEncryptionAlgorithm.java | 192 ------ .../jose/jwe/RSAKeyDecryptionAlgorithm.java | 46 -- .../jose/jwe/RSAKeyEncryptionAlgorithm.java | 34 - .../jose/jwe/WrappedKeyDecryptionAlgorithm.java | 97 --- .../jose/jwk/DefaultJwkReaderWriter.java | 49 -- .../cxf/rs/security/jose/jwk/JsonWebKey.java | 180 ----- .../cxf/rs/security/jose/jwk/JsonWebKeys.java | 130 ---- .../cxf/rs/security/jose/jwk/JwkException.java | 35 - .../rs/security/jose/jwk/JwkReaderWriter.java | 27 - .../cxf/rs/security/jose/jwk/JwkUtils.java | 533 --------------- .../cxf/rs/security/jose/jwk/KeyOperation.java | 46 -- .../cxf/rs/security/jose/jwk/KeyType.java | 44 -- .../cxf/rs/security/jose/jwk/PublicKeyUse.java | 46 -- .../jose/jws/AbstractJwsSignatureProvider.java | 76 --- .../jose/jws/EcDsaJwsSignatureProvider.java | 110 --- .../jose/jws/EcDsaJwsSignatureVerifier.java | 81 --- .../jose/jws/HmacJwsSignatureProvider.java | 76 --- .../jose/jws/HmacJwsSignatureVerifier.java | 85 --- .../security/jose/jws/JwsCompactConsumer.java | 149 ----- .../security/jose/jws/JwsCompactProducer.java | 136 ---- .../cxf/rs/security/jose/jws/JwsException.java | 49 -- .../cxf/rs/security/jose/jws/JwsHeaders.java | 66 -- .../rs/security/jose/jws/JwsJsonConsumer.java | 191 ------ .../security/jose/jws/JwsJsonOutputStream.java | 100 --- .../rs/security/jose/jws/JwsJsonProducer.java | 210 ------ .../jose/jws/JwsJsonSignatureEntry.java | 163 ----- .../jose/jws/JwsJwtCompactConsumer.java | 43 -- .../jose/jws/JwsJwtCompactProducer.java | 44 -- .../rs/security/jose/jws/JwsOutputStream.java | 59 -- .../cxf/rs/security/jose/jws/JwsSignature.java | 25 - .../security/jose/jws/JwsSignatureProvider.java | 31 - .../security/jose/jws/JwsSignatureVerifier.java | 26 - .../cxf/rs/security/jose/jws/JwsUtils.java | 396 ----------- .../jose/jws/NoneJwsSignatureProvider.java | 55 -- .../jose/jws/NoneJwsSignatureVerifier.java | 36 - .../jws/PrivateKeyJwsSignatureProvider.java | 91 --- .../jose/jws/PublicKeyJwsSignatureVerifier.java | 80 --- .../jose/jwt/AbstractJoseJwtConsumer.java | 96 --- .../jose/jwt/AbstractJoseJwtProducer.java | 84 --- .../cxf/rs/security/jose/jwt/JwtClaims.java | 102 --- .../cxf/rs/security/jose/jwt/JwtConstants.java | 38 -- .../cxf/rs/security/jose/jwt/JwtException.java | 35 - .../cxf/rs/security/jose/jwt/JwtToken.java | 56 -- .../security/jose/jwt/JwtTokenReaderWriter.java | 55 -- .../cxf/rs/security/jose/jwt/JwtUtils.java | 107 --- .../jose/cookbook/JwkJoseCookBookTest.java | 187 ------ .../jose/cookbook/JwsJoseCookBookTest.java | 665 ------------------- .../jose/cookbook/cookbookPrivateSet.txt | 24 - .../jose/cookbook/cookbookPublicSet.txt | 16 - .../jose/cookbook/cookbookSecretSet.txt | 16 - .../jose/jwe/JweCompactReaderWriterTest.java | 264 -------- .../security/jose/jwe/JweJsonConsumerTest.java | 167 ----- .../security/jose/jwe/JweJsonProducerTest.java | 310 --------- .../jose/jwe/JwePbeHmacAesWrapTest.java | 77 --- .../rs/security/jose/jwk/JsonWebKeyTest.java | 231 ------- .../cxf/rs/security/jose/jwk/JwkUtilsTest.java | 94 --- .../cxf/rs/security/jose/jwk/jwkPrivateSet.txt | 23 - .../cxf/rs/security/jose/jwk/jwkPublicSet.txt | 27 - .../cxf/rs/security/jose/jwk/jwkSecretSet.txt | 13 - .../security/jose/jws/JwsCompactHeaderTest.java | 203 ------ .../jose/jws/JwsCompactReaderWriterTest.java | 307 --------- .../security/jose/jws/JwsJsonConsumerTest.java | 89 --- .../security/jose/jws/JwsJsonProducerTest.java | 126 ---- .../jose/jws/jwkPublicJsonConsumerSet.txt | 18 - 291 files changed, 14441 insertions(+), 14264 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/pom.xml ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/pom.xml b/rt/rs/security/jose/jose-core/pom.xml new file mode 100644 index 0000000..3903acf --- /dev/null +++ b/rt/rs/security/jose/jose-core/pom.xml @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>cxf-rt-rs-security-jose-core</artifactId> + <packaging>bundle</packaging> + <name>Apache CXF Runtime JOSE Core</name> + <description>Apache CXF Runtime JOSE Core</description> + <url>http://cxf.apache.org</url> + <parent> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-parent</artifactId> + <version>3.1.4-SNAPSHOT</version> + <relativePath>../../../../../parent/pom.xml</relativePath> + </parent> + <dependencies> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-security</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-extension-providers</artifactId> + <version>${project.version}</version> + <exclusions> + <exclusion> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-ext-jdk15on</artifactId> + <version>${cxf.bcprov.version}</version> + <scope>provided</scope> + <optional>true</optional> + </dependency> + <!--test dependencies--> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseConsumer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseConsumer.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseConsumer.java new file mode 100644 index 0000000..98886ce --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseConsumer.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; + +import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider; +import org.apache.cxf.rs.security.jose.jwe.JweUtils; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureVerifier; +import org.apache.cxf.rs.security.jose.jws.JwsUtils; + +public abstract class AbstractJoseConsumer { + private JweDecryptionProvider jweDecryptor; + private JwsSignatureVerifier jwsVerifier; + + public void setJweDecryptor(JweDecryptionProvider jweDecryptor) { + this.jweDecryptor = jweDecryptor; + } + + public void setJwsVerifier(JwsSignatureVerifier theJwsVerifier) { + this.jwsVerifier = theJwsVerifier; + } + + protected JweDecryptionProvider getInitializedDecryptionProvider() { + if (jweDecryptor != null) { + return jweDecryptor; + } + return JweUtils.loadDecryptionProvider(false); + } + protected JwsSignatureVerifier getInitializedSignatureVerifier() { + if (jwsVerifier != null) { + return jwsVerifier; + } + return JwsUtils.loadSignatureVerifier(false); + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseProducer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseProducer.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseProducer.java new file mode 100644 index 0000000..f506943 --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/AbstractJoseProducer.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; + +import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider; +import org.apache.cxf.rs.security.jose.jwe.JweUtils; +import org.apache.cxf.rs.security.jose.jws.JwsSignatureProvider; +import org.apache.cxf.rs.security.jose.jws.JwsUtils; + +public abstract class AbstractJoseProducer { + private JwsSignatureProvider sigProvider; + private JweEncryptionProvider encryptionProvider; + + protected JwsSignatureProvider getInitializedSignatureProvider() { + if (sigProvider != null) { + return sigProvider; + } + + return JwsUtils.loadSignatureProvider(false); + } + protected JweEncryptionProvider getInitializedEncryptionProvider() { + if (encryptionProvider != null) { + return encryptionProvider; + } + return JweUtils.loadEncryptionProvider(false); + } + + public void setEncryptionProvider(JweEncryptionProvider encryptionProvider) { + this.encryptionProvider = encryptionProvider; + } + + public void setSignatureProvider(JwsSignatureProvider signatureProvider) { + this.sigProvider = signatureProvider; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java new file mode 100644 index 0000000..0c04791 --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseConstants.java @@ -0,0 +1,54 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.rs.security.jose; + +public final class JoseConstants { + public static final String HEADER_TYPE = "typ"; + public static final String HEADER_ALGORITHM = "alg"; + public static final String HEADER_CONTENT_TYPE = "cty"; + public static final String HEADER_CRITICAL = "crit"; + + public static final String HEADER_KEY_ID = "kid"; + public static final String HEADER_X509_URL = "x5u"; + public static final String HEADER_X509_CHAIN = "x5c"; + public static final String HEADER_X509_THUMBPRINT = "x5t"; + public static final String HEADER_X509_THUMBPRINT_SHA256 = "x5t#S256"; + public static final String HEADER_JSON_WEB_KEY = "jwk"; + public static final String HEADER_JSON_WEB_KEY_SET = "jku"; + + public static final String JWE_HEADER_KEY_ENC_ALGORITHM = HEADER_ALGORITHM; + public static final String JWE_HEADER_CONTENT_ENC_ALGORITHM = "enc"; + public static final String JWE_HEADER_ZIP_ALGORITHM = "zip"; + public static final String JWE_DEFLATE_ZIP_ALGORITHM = "DEF"; + + public static final String JWS_HEADER_B64_STATUS_HEADER = "b64"; + + public static final String TYPE_JWT = "JWT"; + public static final String TYPE_JOSE = "JOSE"; + public static final String TYPE_JOSE_JSON = "JOSE+JSON"; + public static final String MEDIA_TYPE_JOSE = "application/jose"; + public static final String MEDIA_TYPE_JOSE_JSON = "application/jose+json"; + + public static final String JOSE_CONTEXT_PROPERTY = "org.apache.cxf.jose.context"; + + private JoseConstants() { + + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseException.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseException.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseException.java new file mode 100644 index 0000000..a71a098 --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseException.java @@ -0,0 +1,33 @@ +/** + * 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; + +public class JoseException extends RuntimeException { + + private static final long serialVersionUID = 4118589816228511524L; + public JoseException() { + + } + public JoseException(String error) { + super(error); + } + public JoseException(Throwable cause) { + super(cause); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java new file mode 100644 index 0000000..add5408 --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseHeaders.java @@ -0,0 +1,179 @@ +/** + * 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; + +import java.util.List; +import java.util.Map; + +import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.jaxrs.provider.json.JsonMapObject; +import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; + +public abstract class JoseHeaders extends JsonMapObject { + public JoseHeaders() { + } + + public JoseHeaders(JoseType type) { + init(type); + } + + public JoseHeaders(JoseHeaders headers) { + this(headers.asMap()); + } + + public JoseHeaders(Map<String, Object> values) { + super(values); + } + private void init(JoseType type) { + setType(type); + } + public void setType(JoseType type) { + setHeader(JoseConstants.HEADER_TYPE, type.toString()); + } + + public JoseType getType() { + Object prop = getHeader(JoseConstants.HEADER_TYPE); + return prop == null ? null : JoseType.getType(prop.toString()); + } + + public void setContentType(String type) { + setHeader(JoseConstants.HEADER_CONTENT_TYPE, type); + } + + public String getContentType() { + return (String)getHeader(JoseConstants.HEADER_CONTENT_TYPE); + } + + public void setAlgorithm(String algo) { + setHeader(JoseConstants.HEADER_ALGORITHM, algo); + } + + public String getAlgorithm() { + Object prop = getHeader(JoseConstants.HEADER_ALGORITHM); + return prop == null ? null : prop.toString(); + } + + public void setKeyId(String kid) { + setHeader(JoseConstants.HEADER_KEY_ID, kid); + } + + public String getKeyId() { + return (String)getHeader(JoseConstants.HEADER_KEY_ID); + } + + public void setX509Url(String x509Url) { + setHeader(JoseConstants.HEADER_X509_URL, x509Url); + } + + public String getX509Url() { + return (String)getHeader(JoseConstants.HEADER_X509_URL); + } + + public void setX509Chain(List<String> x509Chain) { + setProperty(JoseConstants.HEADER_X509_CHAIN, x509Chain); + } + + public List<String> getX509Chain() { + return CastUtils.cast((List<?>)getProperty(JoseConstants.HEADER_X509_CHAIN)); + } + + public void setX509Thumbprint(String x509Thumbprint) { + setHeader(JoseConstants.HEADER_X509_THUMBPRINT, x509Thumbprint); + } + + public String getX509Thumbprint() { + return (String)getHeader(JoseConstants.HEADER_X509_THUMBPRINT); + } + + public void setX509ThumbprintSHA256(String x509Thumbprint) { + setHeader(JoseConstants.HEADER_X509_THUMBPRINT_SHA256, x509Thumbprint); + } + + public String getX509ThumbprintSHA256() { + return (String)getHeader(JoseConstants.HEADER_X509_THUMBPRINT_SHA256); + } + + public void setCritical(List<String> crit) { + setHeader(JoseConstants.HEADER_CRITICAL, crit); + } + + public List<String> getCritical() { + return CastUtils.cast((List<?>)getHeader(JoseConstants.HEADER_CRITICAL)); + } + + public void setJsonWebKey(JsonWebKey key) { + setJsonWebKey(JoseConstants.HEADER_JSON_WEB_KEY, key); + } + + public void setJsonWebKey(String headerName, JsonWebKey key) { + setHeader(headerName, key); + } + + public void setJsonWebKeysUrl(String url) { + setHeader(JoseConstants.HEADER_JSON_WEB_KEY_SET, url); + } + + public String getJsonWebKeysUrl() { + return (String)getHeader(JoseConstants.HEADER_JSON_WEB_KEY_SET); + } + + public JsonWebKey getJsonWebKey() { + return getJsonWebKey(JoseConstants.HEADER_JSON_WEB_KEY); + } + public JsonWebKey getJsonWebKey(String headerName) { + Object jsonWebKey = getHeader(headerName); + if (jsonWebKey == null || jsonWebKey instanceof JsonWebKey) { + return (JsonWebKey)jsonWebKey; + } + Map<String, Object> map = CastUtils.cast((Map<?, ?>)jsonWebKey); + return new JsonWebKey(map); + } + + public JoseHeaders setHeader(String name, Object value) { + setProperty(name, value); + return this; + } + + public Object getHeader(String name) { + return getProperty(name); + } + + public JoseHeaders setIntegerHeader(String name, Integer value) { + setHeader(name, value); + return this; + } + + public Integer getIntegerHeader(String name) { + return getIntegerProperty(name); + } + public JoseHeaders setLongHeader(String name, Long value) { + setHeader(name, value); + return this; + } + + public Long getLongHeader(String name) { + return getLongProperty(name); + } + + public boolean containsHeader(String name) { + return containsProperty(name); + } + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseType.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseType.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseType.java new file mode 100644 index 0000000..57a16c7 --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseType.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.jose; + + +public enum JoseType { + JOSE(JoseConstants.TYPE_JOSE), + JOSE_JSON(JoseConstants.TYPE_JOSE_JSON), + JWT(JoseConstants.TYPE_JWT); + + private final String type; + JoseType(String type) { + this.type = type; + } + public static JoseType getType(String type) { + if (type == null) { + return null; + } else if (JoseConstants.TYPE_JOSE_JSON.equals(type)) { + return JOSE_JSON; + } else { + return valueOf(type); + } + } + public String toString() { + return type; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseUtils.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseUtils.java new file mode 100644 index 0000000..7efaab7 --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/JoseUtils.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; + +import java.io.File; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.logging.Logger; + +import org.apache.cxf.Bus; +import org.apache.cxf.common.classloader.ClassLoaderUtils; +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.util.StringUtils; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.PhaseInterceptorChain; +import org.apache.cxf.resource.ResourceManager; +import org.apache.cxf.rt.security.crypto.CryptoUtils; + +public final class JoseUtils { + private static final Logger LOG = LogUtils.getL7dLogger(JoseUtils.class); + private static final String CLASSPATH_PREFIX = "classpath:"; + + private JoseUtils() { + + } + public static String[] getCompactParts(String compactContent) { + if (compactContent.startsWith("\"") && compactContent.endsWith("\"")) { + compactContent = compactContent.substring(1, compactContent.length() - 1); + } + return StringUtils.split(compactContent, "\\."); + } + public static void setJoseContextProperty(JoseHeaders headers) { + Message message = PhaseInterceptorChain.getCurrentMessage(); + String context = (String)message.get(JoseConstants.JOSE_CONTEXT_PROPERTY); + if (context != null) { + headers.setHeader(JoseConstants.JOSE_CONTEXT_PROPERTY, context); + } + } + public static void setJoseMessageContextProperty(JoseHeaders headers, String value) { + headers.setHeader(JoseConstants.JOSE_CONTEXT_PROPERTY, value); + Message message = PhaseInterceptorChain.getCurrentMessage(); + message.put(JoseConstants.JOSE_CONTEXT_PROPERTY, value); + } + public static void setMessageContextProperty(JoseHeaders headers) { + String context = (String)headers.getHeader(JoseConstants.JOSE_CONTEXT_PROPERTY); + if (context != null) { + Message message = PhaseInterceptorChain.getCurrentMessage(); + message.put(JoseConstants.JOSE_CONTEXT_PROPERTY, context); + } + } + public static void validateRequestContextProperty(JoseHeaders headers) { + Message message = PhaseInterceptorChain.getCurrentMessage(); + Object requestContext = message.get(JoseConstants.JOSE_CONTEXT_PROPERTY); + Object headerContext = headers.getHeader(JoseConstants.JOSE_CONTEXT_PROPERTY); + if (requestContext == null && headerContext == null) { + return; + } + if (requestContext == null && headerContext != null + || requestContext != null && headerContext == null + || !requestContext.equals(headerContext)) { + LOG.warning("Invalid JOSE context property"); + throw new JoseException(); + } + } + + public static String checkContentType(String contentType, String defaultType) { + if (contentType != null) { + int paramIndex = contentType.indexOf(';'); + String typeWithoutParams = paramIndex == -1 ? contentType : contentType.substring(0, paramIndex); + if (typeWithoutParams.indexOf('/') == -1) { + contentType = "application/" + contentType; + } + } else { + contentType = defaultType; + } + return contentType; + } + public static String expandContentType(String contentType) { + int paramIndex = contentType.indexOf(';'); + String typeWithoutParams = paramIndex == -1 ? contentType : contentType.substring(0, paramIndex); + if (typeWithoutParams.indexOf('/') == -1) { + contentType = "application/" + contentType; + } + return contentType; + } + + public static String decodeToString(String encoded) { + try { + return new String(decode(encoded), "UTF-8"); + } catch (UnsupportedEncodingException ex) { + throw new JoseException(ex); + } + + } + public static byte[] decode(String encoded) { + return CryptoUtils.decodeSequence(encoded); + } + + public static boolean validateCriticalHeaders(JoseHeaders headers) { + List<String> critical = headers.getCritical(); + if (critical == null) { + return true; + } + // The "crit" value MUST NOT be empty "[]" or contain either duplicate values or "crit" + if (critical.isEmpty() + || detectDoubleEntry(critical) + || critical.contains(JoseConstants.HEADER_CRITICAL)) { + return false; + } + + // Check that the headers contain these critical headers + return headers.asMap().keySet().containsAll(critical); + } + private static boolean detectDoubleEntry(List<?> list) { + Set<Object> inputSet = new HashSet<Object>(list); + return list.size() > inputSet.size(); + } + + // + // <Start> Copied from JAX-RS RT FRONTEND ResourceUtils + // + + public static InputStream getResourceStream(String loc, Bus bus) throws Exception { + URL url = getResourceURL(loc, bus); + return url == null ? null : url.openStream(); + } + + public static URL getResourceURL(String loc, Bus bus) throws Exception { + URL url = null; + if (loc.startsWith(CLASSPATH_PREFIX)) { + String path = loc.substring(CLASSPATH_PREFIX.length()); + url = JoseUtils.getClasspathResourceURL(path, JoseUtils.class, bus); + } else { + try { + url = new URL(loc); + } catch (Exception ex) { + // it can be either a classpath or file resource without a scheme + url = JoseUtils.getClasspathResourceURL(loc, JoseUtils.class, bus); + if (url == null) { + File file = new File(loc); + if (file.exists()) { + url = file.toURI().toURL(); + } + } + } + } + if (url == null) { + LOG.warning("No resource " + loc + " is available"); + } + return url; + } + + public static URL getClasspathResourceURL(String path, Class<?> callingClass, Bus bus) { + URL url = ClassLoaderUtils.getResource(path, callingClass); + return url == null ? getResource(path, URL.class, bus) : url; + } + + public static <T> T getResource(String path, Class<T> resourceClass, Bus bus) { + if (bus != null) { + ResourceManager rm = bus.getExtension(ResourceManager.class); + if (rm != null) { + return rm.resolveResource(path, resourceClass); + } + } + return null; + } + + public static Properties loadProperties(String propertiesLocation, Bus bus) throws Exception { + Properties props = new Properties(); + InputStream is = getResourceStream(propertiesLocation, bus); + props.load(is); + return props; + } + + // + // <End> Copied from JAX-RS RT FRONTEND ResourceUtils + // + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java new file mode 100644 index 0000000..8a63fa8 --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/common/KeyManagementUtils.java @@ -0,0 +1,390 @@ +/** + * 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.common; + +import java.io.InputStream; +import java.security.KeyStore; +import java.security.Principal; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.cert.CertPath; +import java.security.cert.CertPathBuilder; +import java.security.cert.CertPathBuilderResult; +import java.security.cert.CertPathValidator; +import java.security.cert.CertStore; +import java.security.cert.Certificate; +import java.security.cert.CollectionCertStoreParameters; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.X509CertSelector; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; +import java.util.Properties; +import java.util.logging.Logger; + +import org.apache.cxf.Bus; +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.util.PropertyUtils; +import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageUtils; +import org.apache.cxf.phase.PhaseInterceptorChain; +import org.apache.cxf.rs.security.jose.JoseException; +import org.apache.cxf.rs.security.jose.JoseUtils; +import org.apache.cxf.rs.security.jose.jwk.KeyOperation; +import org.apache.cxf.rt.security.crypto.CryptoUtils; +import org.apache.cxf.security.SecurityContext; + + +/** + * Encryption helpers + */ +public final class KeyManagementUtils { + public static final String RSSEC_KEY_STORE_TYPE = "rs.security.keystore.type"; + public static final String RSSEC_KEY_STORE_PSWD = "rs.security.keystore.password"; + public static final String RSSEC_KEY_PSWD = "rs.security.key.password"; + public static final String RSSEC_KEY_STORE_ALIAS = "rs.security.keystore.alias"; + public static final String RSSEC_KEY_STORE_ALIASES = "rs.security.keystore.aliases"; + public static final String RSSEC_KEY_STORE_FILE = "rs.security.keystore.file"; + public static final String RSSEC_PRINCIPAL_NAME = "rs.security.principal.name"; + public static final String RSSEC_KEY_PSWD_PROVIDER = "rs.security.key.password.provider"; + public static final String RSSEC_SIG_KEY_PSWD_PROVIDER = "rs.security.signature.key.password.provider"; + public static final String RSSEC_DECRYPT_KEY_PSWD_PROVIDER = "rs.security.decryption.key.password.provider"; + public static final String RSSEC_DEFAULT_ALGORITHMS = "rs.security.default.algorithms"; + public static final String RSSEC_REPORT_KEY_PROP = "rs.security.report.public.key"; + public static final String RSSEC_REPORT_KEY_ID_PROP = "rs.security.report.public.key.id"; + public static final String RSSEC_ACCEPT_PUBLIC_KEY_PROP = "rs.security.accept.public.key.properties"; + private static final Logger LOG = LogUtils.getL7dLogger(KeyManagementUtils.class); + + private KeyManagementUtils() { + } + public static List<String> loadAndEncodeX509CertificateOrChain(Message m, Properties props) { + X509Certificate[] chain = loadX509CertificateOrChain(m, props); + return encodeX509CertificateChain(chain); + } + public static X509Certificate[] loadX509CertificateOrChain(Message m, Properties props) { + KeyStore keyStore = KeyManagementUtils.loadPersistKeyStore(m, props); + String alias = props.getProperty(RSSEC_KEY_STORE_ALIAS); + return loadX509CertificateOrChain(keyStore, alias); + } + private static X509Certificate[] loadX509CertificateOrChain(KeyStore keyStore, String alias) { + try { + Certificate[] certs = keyStore.getCertificateChain(alias); + if (certs != null) { + return Arrays.copyOf(certs, certs.length, X509Certificate[].class); + } else { + return new X509Certificate[]{(X509Certificate)CryptoUtils.loadCertificate(keyStore, alias)}; + } + } catch (Exception ex) { + LOG.warning("X509 Certificates can not be created"); + throw new JoseException(ex); + } + } + + public static PublicKey loadPublicKey(Message m, Properties props) { + KeyStore keyStore = KeyManagementUtils.loadPersistKeyStore(m, props); + return CryptoUtils.loadPublicKey(keyStore, props.getProperty(RSSEC_KEY_STORE_ALIAS)); + } + public static PublicKey loadPublicKey(Message m, String keyStoreLocProp) { + return loadPublicKey(m, keyStoreLocProp, null); + } + public static PublicKey loadPublicKey(Message m, String keyStoreLocPropPreferred, String keyStoreLocPropDefault) { + String keyStoreLoc = getMessageProperty(m, keyStoreLocPropPreferred, keyStoreLocPropDefault); + Bus bus = m.getExchange().getBus(); + try { + Properties props = JoseUtils.loadProperties(keyStoreLoc, bus); + return KeyManagementUtils.loadPublicKey(m, props); + } catch (Exception ex) { + LOG.warning("Public key can not be loaded"); + throw new JoseException(ex); + } + } + private static String getMessageProperty(Message m, String keyStoreLocPropPreferred, + String keyStoreLocPropDefault) { + String propLoc = + (String)MessageUtils.getContextualProperty(m, keyStoreLocPropPreferred, keyStoreLocPropDefault); + if (propLoc == null) { + LOG.warning("Properties resource is not identified"); + throw new JoseException(); + } + return propLoc; + } + private static PrivateKey loadPrivateKey(KeyStore keyStore, + Message m, + Properties props, + Bus bus, + PrivateKeyPasswordProvider provider, + KeyOperation keyOper, + String alias) { + + String keyPswd = props.getProperty(RSSEC_KEY_PSWD); + String theAlias = alias != null ? alias : getKeyId(m, props, RSSEC_KEY_STORE_ALIAS, keyOper); + char[] keyPswdChars = provider != null ? provider.getPassword(props) + : keyPswd != null ? keyPswd.toCharArray() : null; + return CryptoUtils.loadPrivateKey(keyStore, keyPswdChars, theAlias); + } + + public static PrivateKey loadPrivateKey(Message m, String keyStoreLocProp, KeyOperation keyOper) { + return loadPrivateKey(m, keyStoreLocProp, null, keyOper); + } + public static PrivateKey loadPrivateKey(Message m, String keyStoreLocPropPreferred, + String keyStoreLocPropDefault, KeyOperation keyOper) { + String keyStoreLoc = getMessageProperty(m, keyStoreLocPropPreferred, keyStoreLocPropDefault); + Bus bus = m.getExchange().getBus(); + try { + Properties props = JoseUtils.loadProperties(keyStoreLoc, bus); + return loadPrivateKey(m, props, keyOper); + } catch (Exception ex) { + throw new SecurityException(ex); + } + } + + public static String getKeyId(Message m, Properties props, + String preferredPropertyName, + KeyOperation keyOper) { + String kid = null; + String altPropertyName = null; + if (keyOper != null) { + if (keyOper == KeyOperation.ENCRYPT || keyOper == KeyOperation.DECRYPT) { + altPropertyName = preferredPropertyName + ".jwe"; + } else if (keyOper == KeyOperation.SIGN || keyOper == KeyOperation.VERIFY) { + altPropertyName = preferredPropertyName + ".jws"; + } + String direction = m.getExchange().getOutMessage() == m ? ".out" : ".in"; + kid = (String)MessageUtils.getContextualProperty(m, preferredPropertyName, altPropertyName + direction); + // Check whether the direction is not set for the altPropertyName + if (kid == null && altPropertyName != null) { + kid = (String)m.getContextualProperty(altPropertyName); + } + } + + if (kid == null) { + kid = props.getProperty(preferredPropertyName); + } + if (kid == null && altPropertyName != null) { + kid = props.getProperty(altPropertyName); + } + return kid; + } + public static PrivateKeyPasswordProvider loadPasswordProvider(Message m, Properties props, KeyOperation keyOper) { + PrivateKeyPasswordProvider cb = + (PrivateKeyPasswordProvider)m.getContextualProperty(RSSEC_KEY_PSWD_PROVIDER); + if (cb == null && keyOper != null) { + String propName = keyOper == KeyOperation.SIGN ? RSSEC_SIG_KEY_PSWD_PROVIDER + : keyOper == KeyOperation.DECRYPT + ? RSSEC_DECRYPT_KEY_PSWD_PROVIDER : null; + if (propName != null) { + cb = (PrivateKeyPasswordProvider)m.getContextualProperty(propName); + } + } + return cb; + } + + public static PrivateKey loadPrivateKey(Message m, Properties props, KeyOperation keyOper) { + KeyStore keyStore = loadPersistKeyStore(m, props); + return loadPrivateKey(keyStore, m, props, keyOper, null); + } + private static PrivateKey loadPrivateKey(KeyStore keyStore, Message m, Properties props, KeyOperation keyOper, + String alias) { + Bus bus = m.getExchange().getBus(); + PrivateKeyPasswordProvider cb = loadPasswordProvider(m, props, keyOper); + if (cb != null && m.getExchange().getInMessage() != null) { + SecurityContext sc = m.getExchange().getInMessage().get(SecurityContext.class); + if (sc != null) { + Principal p = sc.getUserPrincipal(); + if (p != null) { + props.setProperty(RSSEC_PRINCIPAL_NAME, p.getName()); + } + } + } + return loadPrivateKey(keyStore, m, props, bus, cb, keyOper, alias); + } + public static KeyStore loadPersistKeyStore(Message m, Properties props) { + if (!props.containsKey(RSSEC_KEY_STORE_FILE)) { + LOG.warning("No keystore file has been configured"); + throw new JoseException("No keystore file has been configured"); + } + KeyStore keyStore = (KeyStore)m.getExchange().get(props.get(RSSEC_KEY_STORE_FILE)); + if (keyStore == null) { + keyStore = loadKeyStore(props, m.getExchange().getBus()); + m.getExchange().put((String)props.get(RSSEC_KEY_STORE_FILE), keyStore); + } + return keyStore; + } + public static KeyStore loadKeyStore(Properties props, Bus bus) { + String keyStoreType = props.getProperty(RSSEC_KEY_STORE_TYPE); + String keyStoreLoc = props.getProperty(RSSEC_KEY_STORE_FILE); + String keyStorePswd = props.getProperty(RSSEC_KEY_STORE_PSWD); + + if (keyStorePswd == null) { + throw new JoseException("No keystore password was defined"); + } + try { + InputStream is = JoseUtils.getResourceStream(keyStoreLoc, bus); + return CryptoUtils.loadKeyStore(is, keyStorePswd.toCharArray(), keyStoreType); + } catch (Exception ex) { + LOG.warning("Key store can not be loaded"); + throw new JoseException(ex); + } + } + public static List<String> encodeX509CertificateChain(X509Certificate[] chain) { + return encodeX509CertificateChain(Arrays.asList(chain)); + } + public static List<String> encodeX509CertificateChain(List<X509Certificate> chain) { + List<String> encodedChain = new ArrayList<String>(chain.size()); + for (X509Certificate cert : chain) { + try { + encodedChain.add(CryptoUtils.encodeCertificate(cert)); + } catch (Exception ex) { + LOG.warning("X509 Certificate can not be encoded"); + throw new JoseException(ex); + } + } + return encodedChain; + } + public static List<X509Certificate> toX509CertificateChain(List<String> base64EncodedChain) { + if (base64EncodedChain != null) { + List<X509Certificate> certs = new ArrayList<X509Certificate>(base64EncodedChain.size()); + for (String encodedCert : base64EncodedChain) { + try { + certs.add((X509Certificate)CryptoUtils.decodeCertificate(encodedCert)); + } catch (Exception ex) { + LOG.warning("X509 Certificate can not be decoded"); + throw new JoseException(ex); + } + } + return certs; + } else { + return null; + } + } + //TODO: enhance the certificate validation code + public static void validateCertificateChain(Properties storeProperties, List<X509Certificate> inCerts) { + Message message = PhaseInterceptorChain.getCurrentMessage(); + KeyStore ks = loadPersistKeyStore(message, storeProperties); + validateCertificateChain(ks, inCerts); + } + public static void validateCertificateChain(KeyStore ks, List<X509Certificate> inCerts) { + // Initial chain validation, to be enhanced as needed + try { + X509CertSelector certSelect = new X509CertSelector(); + certSelect.setCertificate((X509Certificate) inCerts.get(0)); + PKIXBuilderParameters pbParams = new PKIXBuilderParameters(ks, certSelect); + pbParams.addCertStore(CertStore.getInstance("Collection", + new CollectionCertStoreParameters(inCerts))); + pbParams.setMaxPathLength(-1); + pbParams.setRevocationEnabled(false); + CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams); + CertPath certPath = buildResult.getCertPath(); + CertPathValidator.getInstance("PKIX").validate(certPath, pbParams); + } catch (Exception ex) { + LOG.warning("Certificate path validation error"); + throw new JoseException(ex); + } + } + public static X509Certificate[] toX509CertificateChainArray(List<String> base64EncodedChain) { + List<X509Certificate> chain = toX509CertificateChain(base64EncodedChain); + return chain == null ? null : chain.toArray(new X509Certificate[]{}); + } + public static String getKeyAlgorithm(Message m, Properties props, String propName, String defaultAlg) { + String algo = props.getProperty(propName); + if (algo == null) { + algo = (String)m.getContextualProperty(propName); + } + if (algo == null && PropertyUtils.isTrue(m.getContextualProperty(RSSEC_DEFAULT_ALGORITHMS))) { + algo = defaultAlg; + } + return algo; + } + + public static Properties loadStoreProperties(Message m, boolean required, + String storeProp1, String storeProp2) { + if (m == null) { + if (required) { + throw new JoseException(); + } + return null; + } + Properties props = null; + String propLoc = + (String)MessageUtils.getContextualProperty(m, storeProp1, storeProp2); + if (propLoc != null) { + try { + props = JoseUtils.loadProperties(propLoc, m.getExchange().getBus()); + } catch (Exception ex) { + LOG.warning("Properties resource is not identified"); + throw new JoseException(ex); + } + } else { + String keyFile = (String)m.getContextualProperty(RSSEC_KEY_STORE_FILE); + if (keyFile != null) { + props = new Properties(); + props.setProperty(RSSEC_KEY_STORE_FILE, keyFile); + String type = (String)m.getContextualProperty(RSSEC_KEY_STORE_TYPE); + if (type == null) { + type = "jwk"; + } + props.setProperty(RSSEC_KEY_STORE_TYPE, type); + String alias = (String)m.getContextualProperty(RSSEC_KEY_STORE_ALIAS); + if (alias != null) { + props.setProperty(RSSEC_KEY_STORE_ALIAS, alias); + } + String keystorePassword = (String)m.getContextualProperty(RSSEC_KEY_STORE_PSWD); + if (keystorePassword != null) { + props.setProperty(RSSEC_KEY_STORE_PSWD, keystorePassword); + } + String keyPassword = (String)m.getContextualProperty(RSSEC_KEY_PSWD); + if (keyPassword != null) { + props.setProperty(RSSEC_KEY_PSWD, keyPassword); + } + } + } + if (props == null && required) { + LOG.warning("Properties resource is not identified"); + throw new JoseException(); + } + return props; + } + public static PrivateKey loadPrivateKey(Message m, Properties props, + List<X509Certificate> inCerts, + KeyOperation keyOper) { + KeyStore ks = loadPersistKeyStore(m, props); + + try { + String alias = ks.getCertificateAlias(inCerts.get(0)); + if (alias != null) { + for (Enumeration<String> e = ks.aliases(); e.hasMoreElements();) { + String currentAlias = e.nextElement(); + X509Certificate[] currentCertArray = loadX509CertificateOrChain(ks, currentAlias); + if (currentCertArray != null) { + alias = currentAlias; + break; + } + } + } + return loadPrivateKey(ks, m, props, keyOper, alias); + + } catch (Exception ex) { + LOG.warning("Private key can not be loaded"); + throw new JoseException(ex); + } + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/common/PrivateKeyPasswordProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/common/PrivateKeyPasswordProvider.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/common/PrivateKeyPasswordProvider.java new file mode 100644 index 0000000..fc58ee5 --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/common/PrivateKeyPasswordProvider.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.jose.common; + +import java.util.Properties; + +public interface PrivateKeyPasswordProvider { + char[] getPassword(Properties storeProperties); +} http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/AlgorithmUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/AlgorithmUtils.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/AlgorithmUtils.java new file mode 100644 index 0000000..76854ca --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/AlgorithmUtils.java @@ -0,0 +1,271 @@ +/** + * 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.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + + + + +public final class AlgorithmUtils { + public static final String AES = "AES"; + + // Key Encryption + // JWA + public static final String RSA_OAEP_ALGO = "RSA-OAEP"; + public static final String RSA_OAEP_256_ALGO = "RSA-OAEP-256"; + public static final String RSA1_5_ALGO = "RSA1_5"; + public static final String A128KW_ALGO = "A128KW"; + public static final String A192KW_ALGO = "A192KW"; + public static final String A256KW_ALGO = "A256KW"; + public static final String A128GCMKW_ALGO = "A128GCMKW"; + public static final String A192GCMKW_ALGO = "A192GCMKW"; + public static final String A256GCMKW_ALGO = "A256GCMKW"; + public static final String ECDH_ES_A128KW_ALGO = "ECDH-ES+A128KW"; + public static final String ECDH_ES_A192KW_ALGO = "ECDH-ES+A192KW"; + public static final String ECDH_ES_A256KW_ALGO = "ECDH-ES+A256KW"; + public static final String PBES2_HS256_A128KW_ALGO = "PBES2-HS256+A128KW"; + public static final String PBES2_HS384_A192KW_ALGO = "PBES2-HS384+A192KW"; + public static final String PBES2_HS512_A256KW_ALGO = "PBES2-HS512+A256KW"; + public static final String ECDH_ES_DIRECT_ALGO = "ECDH-ES"; + // Java + 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_WRAP_ALGO_JAVA = AES + "Wrap"; + // Content Encryption + // JWA + public static final String A128CBC_HS256_ALGO = "A128CBC-HS256"; + public static final String A192CBC_HS384_ALGO = "A192CBC-HS384"; + public static final String A256CBC_HS512_ALGO = "A256CBC-HS512"; + public static final String A128GCM_ALGO = "A128GCM"; + public static final String A192GCM_ALGO = "A192GCM"; + public static final String A256GCM_ALGO = "A256GCM"; + // Java + public static final String AES_GCM_ALGO_JAVA = AES + "/GCM/NoPadding"; + public static final String AES_CBC_ALGO_JAVA = AES + "/CBC/PKCS7Padding"; + // Signature + // JWA + public static final String HMAC_SHA_256_ALGO = "HS256"; + public static final String HMAC_SHA_384_ALGO = "HS384"; + public static final String HMAC_SHA_512_ALGO = "HS512"; + public static final String RS_SHA_256_ALGO = "RS256"; + public static final String RS_SHA_384_ALGO = "RS384"; + public static final String RS_SHA_512_ALGO = "RS512"; + public static final String PS_SHA_256_ALGO = "PS256"; + public static final String PS_SHA_384_ALGO = "PS384"; + public static final String PS_SHA_512_ALGO = "PS512"; + public static final String ES_SHA_256_ALGO = "ES256"; + public static final String ES_SHA_384_ALGO = "ES384"; + public static final String ES_SHA_512_ALGO = "ES512"; + public static final String NONE_TEXT_ALGO = "none"; + // Java + 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 PS_SHA_256_JAVA = "SHA256withRSAandMGF1"; + public static final String PS_SHA_384_JAVA = "SHA384withRSAandMGF1"; + public static final String PS_SHA_512_JAVA = "SHA512withRSAandMGF1"; + 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 Set<String> HMAC_SIGN_SET = new HashSet<String>(Arrays.asList(HMAC_SHA_256_ALGO, + HMAC_SHA_384_ALGO, + HMAC_SHA_512_ALGO)); + public static final Set<String> RSA_SHA_SIGN_SET = new HashSet<String>(Arrays.asList(RS_SHA_256_ALGO, + RS_SHA_384_ALGO, + RS_SHA_512_ALGO)); + public static final Set<String> RSA_SHA_PS_SIGN_SET = new HashSet<String>(Arrays.asList(PS_SHA_256_ALGO, + PS_SHA_384_ALGO, + PS_SHA_512_ALGO)); + public static final Set<String> EC_SHA_SIGN_SET = new HashSet<String>(Arrays.asList(ES_SHA_256_ALGO, + ES_SHA_384_ALGO, + ES_SHA_512_ALGO)); + public static final Set<String> RSA_CEK_SET = new HashSet<String>(Arrays.asList(RSA_OAEP_ALGO, + RSA_OAEP_256_ALGO, + RSA1_5_ALGO)); + public static final Set<String> AES_GCM_CEK_SET = new HashSet<String>(Arrays.asList(A128GCM_ALGO, + A192GCM_ALGO, + A256GCM_ALGO)); + public static final Set<String> AES_GCM_KW_SET = new HashSet<String>(Arrays.asList(A128GCMKW_ALGO, + A192GCMKW_ALGO, + A256GCMKW_ALGO)); + public static final Set<String> AES_KW_SET = new HashSet<String>(Arrays.asList(A128KW_ALGO, + A192KW_ALGO, + A256KW_ALGO)); + public static final Set<String> ACBC_HS_SET = new HashSet<String>(Arrays.asList(A128CBC_HS256_ALGO, + A192CBC_HS384_ALGO, + A256CBC_HS512_ALGO)); + public static final Set<String> PBES_HS_SET = new HashSet<String>(Arrays.asList(PBES2_HS256_A128KW_ALGO, + PBES2_HS384_A192KW_ALGO, + PBES2_HS512_A256KW_ALGO)); + public static final Set<String> ECDH_ES_WRAP_SET = new HashSet<String>(Arrays.asList(ECDH_ES_A128KW_ALGO, + ECDH_ES_A192KW_ALGO, + ECDH_ES_A256KW_ALGO)); + + private static final Map<String, String> JAVA_TO_JWA_NAMES; + private static final Map<String, String> JWA_TO_JAVA_NAMES; + static { + JAVA_TO_JWA_NAMES = new HashMap<String, String>(); + JAVA_TO_JWA_NAMES.put(HMAC_SHA_256_JAVA, HMAC_SHA_256_ALGO); + JAVA_TO_JWA_NAMES.put(HMAC_SHA_384_JAVA, HMAC_SHA_384_ALGO); + JAVA_TO_JWA_NAMES.put(HMAC_SHA_512_JAVA, HMAC_SHA_512_ALGO); + JAVA_TO_JWA_NAMES.put(RS_SHA_256_JAVA, RS_SHA_256_ALGO); + JAVA_TO_JWA_NAMES.put(RS_SHA_384_JAVA, RS_SHA_384_ALGO); + JAVA_TO_JWA_NAMES.put(RS_SHA_512_JAVA, RS_SHA_512_ALGO); + JAVA_TO_JWA_NAMES.put(PS_SHA_256_JAVA, PS_SHA_256_ALGO); + JAVA_TO_JWA_NAMES.put(PS_SHA_384_JAVA, PS_SHA_384_ALGO); + JAVA_TO_JWA_NAMES.put(PS_SHA_512_JAVA, PS_SHA_512_ALGO); + JAVA_TO_JWA_NAMES.put(ES_SHA_256_JAVA, ES_SHA_256_ALGO); + JAVA_TO_JWA_NAMES.put(ES_SHA_384_JAVA, ES_SHA_384_ALGO); + JAVA_TO_JWA_NAMES.put(ES_SHA_512_JAVA, ES_SHA_512_ALGO); + JAVA_TO_JWA_NAMES.put(RSA_OAEP_ALGO_JAVA, RSA_OAEP_ALGO); + JAVA_TO_JWA_NAMES.put(RSA_OAEP_256_ALGO_JAVA, RSA_OAEP_256_ALGO); + JAVA_TO_JWA_NAMES.put(RSA_1_5_ALGO_JAVA, RSA1_5_ALGO); + JAVA_TO_JWA_NAMES.put(AES_GCM_ALGO_JAVA, A256GCM_ALGO); + JAVA_TO_JWA_NAMES.put(AES_GCM_ALGO_JAVA, A192GCM_ALGO); + JAVA_TO_JWA_NAMES.put(AES_GCM_ALGO_JAVA, A128GCM_ALGO); + JAVA_TO_JWA_NAMES.put(AES_WRAP_ALGO_JAVA, A128KW_ALGO); + JAVA_TO_JWA_NAMES.put(AES_WRAP_ALGO_JAVA, A192KW_ALGO); + JAVA_TO_JWA_NAMES.put(AES_WRAP_ALGO_JAVA, A256KW_ALGO); + JAVA_TO_JWA_NAMES.put(AES_CBC_ALGO_JAVA, A128CBC_HS256_ALGO); + JAVA_TO_JWA_NAMES.put(AES_CBC_ALGO_JAVA, A192CBC_HS384_ALGO); + JAVA_TO_JWA_NAMES.put(AES_CBC_ALGO_JAVA, A256CBC_HS512_ALGO); + JWA_TO_JAVA_NAMES = new HashMap<String, String>(); + JWA_TO_JAVA_NAMES.put(HMAC_SHA_256_ALGO, HMAC_SHA_256_JAVA); + JWA_TO_JAVA_NAMES.put(HMAC_SHA_384_ALGO, HMAC_SHA_384_JAVA); + JWA_TO_JAVA_NAMES.put(HMAC_SHA_512_ALGO, HMAC_SHA_512_JAVA); + JWA_TO_JAVA_NAMES.put(RS_SHA_256_ALGO, RS_SHA_256_JAVA); + JWA_TO_JAVA_NAMES.put(RS_SHA_384_ALGO, RS_SHA_384_JAVA); + JWA_TO_JAVA_NAMES.put(RS_SHA_512_ALGO, RS_SHA_512_JAVA); + JWA_TO_JAVA_NAMES.put(PS_SHA_256_ALGO, PS_SHA_256_JAVA); + JWA_TO_JAVA_NAMES.put(PS_SHA_384_ALGO, PS_SHA_384_JAVA); + JWA_TO_JAVA_NAMES.put(PS_SHA_512_ALGO, PS_SHA_512_JAVA); + JWA_TO_JAVA_NAMES.put(ES_SHA_256_ALGO, ES_SHA_256_JAVA); + JWA_TO_JAVA_NAMES.put(ES_SHA_384_ALGO, ES_SHA_384_JAVA); + JWA_TO_JAVA_NAMES.put(ES_SHA_512_ALGO, ES_SHA_512_JAVA); + JWA_TO_JAVA_NAMES.put(RSA_OAEP_ALGO, RSA_OAEP_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(RSA_OAEP_256_ALGO, RSA_OAEP_256_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(RSA1_5_ALGO, RSA_1_5_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A128KW_ALGO, AES_WRAP_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A192KW_ALGO, AES_WRAP_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A256KW_ALGO, AES_WRAP_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A256GCM_ALGO, AES_GCM_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A192GCM_ALGO, AES_GCM_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A128GCM_ALGO, AES_GCM_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A256GCMKW_ALGO, AES_GCM_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A192GCMKW_ALGO, AES_GCM_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A128GCMKW_ALGO, AES_GCM_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A128CBC_HS256_ALGO, AES_CBC_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A192CBC_HS384_ALGO, AES_CBC_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(A256CBC_HS512_ALGO, AES_CBC_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(PBES2_HS256_A128KW_ALGO, AES_WRAP_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(PBES2_HS384_A192KW_ALGO, AES_WRAP_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(PBES2_HS512_A256KW_ALGO, AES_WRAP_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(ECDH_ES_A128KW_ALGO, AES_WRAP_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(ECDH_ES_A192KW_ALGO, AES_WRAP_ALGO_JAVA); + JWA_TO_JAVA_NAMES.put(ECDH_ES_A256KW_ALGO, AES_WRAP_ALGO_JAVA); + } + + private AlgorithmUtils() { + } + public static boolean isRsa(String algo) { + return isRsaKeyWrap(algo) || isRsaSign(algo); + } + public static boolean isRsaKeyWrap(String algo) { + return RSA_CEK_SET.contains(algo); + } + public static boolean isAesKeyWrap(String algo) { + return AES_KW_SET.contains(algo); + } + public static boolean isAesGcmKeyWrap(String algo) { + return AES_GCM_KW_SET.contains(algo); + } + public static boolean isPbesHsWrap(String algo) { + return PBES_HS_SET.contains(algo); + } + public static boolean isEcdhEsWrap(String algo) { + return ECDH_ES_WRAP_SET.contains(algo); + } + public static boolean isEcdhEsDirect(String algo) { + return ECDH_ES_DIRECT_ALGO.equals(algo); + } + public static boolean isAesGcm(String algo) { + return AES_GCM_CEK_SET.contains(algo); + } + public static boolean isAesCbcHmac(String algo) { + return ACBC_HS_SET.contains(algo); + } + public static boolean isHmacSign(String algo) { + return HMAC_SIGN_SET.contains(algo); + } + public static boolean isOctet(String algo) { + return isHmacSign(algo) + || isAesCbcHmac(algo) + || isAesGcm(algo) + || isAesGcmKeyWrap(algo) + || isAesKeyWrap(algo); + } + public static boolean isRsaSign(String algo) { + return isRsaShaSign(algo) || isRsaShaPsSign(algo); + } + public static boolean isRsaShaSign(String algo) { + return RSA_SHA_SIGN_SET.contains(algo); + } + public static boolean isRsaShaPsSign(String algo) { + return RSA_SHA_PS_SIGN_SET.contains(algo); + } + public static boolean isEcDsaSign(String algo) { + return EC_SHA_SIGN_SET.contains(algo); + } + + public static String toJwaName(String javaName, int keyBitSize) { + //TODO: perhaps a key should be a name+keysize pair + String name = JAVA_TO_JWA_NAMES.get(javaName); + if (name == null && javaName.startsWith(AES)) { + name = "A" + keyBitSize + "GCM"; + } + return name; + } + public static String toJavaName(String jwtName) { + return JWA_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; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf/blob/66a81773/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/ContentAlgorithm.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/ContentAlgorithm.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/ContentAlgorithm.java new file mode 100644 index 0000000..1cc806c --- /dev/null +++ b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwa/ContentAlgorithm.java @@ -0,0 +1,70 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.rs.security.jose.jwa; + + + + +public enum ContentAlgorithm { + A128GCM(AlgorithmUtils.A128GCM_ALGO, "AES/GCM/NoPadding", 128), + A192GCM(AlgorithmUtils.A192GCM_ALGO, "AES/GCM/NoPadding", 192), + A256GCM(AlgorithmUtils.A256GCM_ALGO, "AES/GCM/NoPadding", 256), + //TODO: default to "AES/CBC/PKCS5Padding" if Cipher "AES/CBC/PKCS7Padding" + // can not be initialized, apparently Java 8 has decided to settle on PKCS5Padding only + A128CBC_HS256(AlgorithmUtils.A128CBC_HS256_ALGO, "AES/CBC/PKCS7Padding", 128), + A192CBC_HS384(AlgorithmUtils.A192CBC_HS384_ALGO, "AES/CBC/PKCS7Padding", 192), + A256CBC_HS512(AlgorithmUtils.A256CBC_HS512_ALGO, "AES/CBC/PKCS7Padding", 256); + + private final String jwaName; + private final String javaName; + private final int keySizeBits; + + ContentAlgorithm(String jwaName, String javaName, int keySizeBits) { + this.jwaName = jwaName; + this.javaName = javaName; + this.keySizeBits = keySizeBits; + } + + public String getJwaName() { + return jwaName; + } + + public String getJavaName() { + return javaName == null ? name() : javaName; + } + + public String getJavaAlgoName() { + return AlgorithmUtils.stripAlgoProperties(getJavaName()); + } + + public int getKeySizeBits() { + return keySizeBits; + } + + public static ContentAlgorithm getAlgorithm(String algo) { + if (algo == null) { + return null; + } + return ContentAlgorithm.valueOf(algo.replace('-', '_') + .replace('+', '_')); + + } + +} \ No newline at end of file
