http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/JwkUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/JwkUtils.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/JwkUtils.java deleted file mode 100644 index cb76567..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/JwkUtils.java +++ /dev/null @@ -1,531 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jwk; - -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.net.URI; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.X509Certificate; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.security.interfaces.RSAPrivateCrtKey; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import javax.crypto.SecretKey; - -import org.apache.cxf.Bus; -import org.apache.cxf.common.util.Base64UrlUtility; -import org.apache.cxf.common.util.StringUtils; -import org.apache.cxf.helpers.CastUtils; -import org.apache.cxf.helpers.IOUtils; -import org.apache.cxf.jaxrs.json.basic.JsonMapObjectReaderWriter; -import org.apache.cxf.message.Message; -import org.apache.cxf.message.MessageUtils; -import org.apache.cxf.rs.security.jose.common.JoseConstants; -import org.apache.cxf.rs.security.jose.common.JoseHeaders; -import org.apache.cxf.rs.security.jose.common.JoseUtils; -import org.apache.cxf.rs.security.jose.common.KeyManagementUtils; -import org.apache.cxf.rs.security.jose.common.PrivateKeyPasswordProvider; -import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils; -import org.apache.cxf.rs.security.jose.jwa.ContentAlgorithm; -import org.apache.cxf.rs.security.jose.jwa.KeyAlgorithm; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; -import org.apache.cxf.rs.security.jose.jwe.AesCbcHmacJweDecryption; -import org.apache.cxf.rs.security.jose.jwe.AesCbcHmacJweEncryption; -import org.apache.cxf.rs.security.jose.jwe.JweDecryptionProvider; -import org.apache.cxf.rs.security.jose.jwe.JweEncryptionProvider; -import org.apache.cxf.rs.security.jose.jwe.JweHeaders; -import org.apache.cxf.rs.security.jose.jwe.JweUtils; -import org.apache.cxf.rs.security.jose.jwe.KeyDecryptionProvider; -import org.apache.cxf.rs.security.jose.jwe.KeyEncryptionProvider; -import org.apache.cxf.rs.security.jose.jwe.PbesHmacAesWrapKeyDecryptionAlgorithm; -import org.apache.cxf.rs.security.jose.jwe.PbesHmacAesWrapKeyEncryptionAlgorithm; -import org.apache.cxf.rs.security.jose.jws.JwsUtils; -import org.apache.cxf.rt.security.crypto.CryptoUtils; -import org.apache.cxf.rt.security.crypto.MessageDigestUtils; - -public final class JwkUtils { - private static final Map<KeyType, List<String>> JWK_REQUIRED_FIELDS_MAP; - static { - JWK_REQUIRED_FIELDS_MAP = new HashMap<KeyType, List<String>>(); - JWK_REQUIRED_FIELDS_MAP.put(KeyType.RSA, Arrays.asList( - JsonWebKey.RSA_PUBLIC_EXP, JsonWebKey.KEY_TYPE, JsonWebKey.RSA_MODULUS)); - JWK_REQUIRED_FIELDS_MAP.put(KeyType.EC, Arrays.asList( - JsonWebKey.EC_CURVE, JsonWebKey.KEY_TYPE, JsonWebKey.EC_X_COORDINATE, JsonWebKey.EC_Y_COORDINATE)); - JWK_REQUIRED_FIELDS_MAP.put(KeyType.OCTET, Arrays.asList( - JsonWebKey.OCTET_KEY_VALUE, JsonWebKey.KEY_TYPE)); - } - private JwkUtils() { - - } - public static String getThumbprint(String keySequence) { - return getThumbprint(readJwkKey(keySequence)); - } - public static String getThumbprint(JsonWebKey key) { - List<String> fields = getRequiredFields(key.getKeyType()); - JsonWebKey thumbprintKey = new JsonWebKey(); - for (String f : fields) { - thumbprintKey.setProperty(f, key.getProperty(f)); - } - String json = new JsonMapObjectReaderWriter().toJson(thumbprintKey); - byte[] digest = MessageDigestUtils.createDigest(json, MessageDigestUtils.ALGO_SHA_256); - return Base64UrlUtility.encode(digest); - } - public static List<String> getRequiredFields(KeyType keyType) { - return JWK_REQUIRED_FIELDS_MAP.get(keyType); - } - public static JsonWebKey readJwkKey(URI uri) throws IOException { - return readJwkKey(uri.toURL().openStream()); - } - public static JsonWebKeys readJwkSet(URI uri) throws IOException { - return readJwkSet(uri.toURL().openStream()); - } - public static JsonWebKey readJwkKey(InputStream is) throws IOException { - return readJwkKey(IOUtils.readStringFromStream(is)); - } - public static JsonWebKeys readJwkSet(InputStream is) throws IOException { - return readJwkSet(IOUtils.readStringFromStream(is)); - } - public static JsonWebKey readJwkKey(String jwkJson) { - return new DefaultJwkReaderWriter().jsonToJwk(jwkJson); - } - public static JsonWebKeys readJwkSet(String jwksJson) { - return new DefaultJwkReaderWriter().jsonToJwkSet(jwksJson); - } - public static String jwkKeyToJson(JsonWebKey jwkKey) { - return new DefaultJwkReaderWriter().jwkToJson(jwkKey); - } - public static String jwkSetToJson(JsonWebKeys jwkSet) { - return new DefaultJwkReaderWriter().jwkSetToJson(jwkSet); - } - public static String encodeJwkKey(JsonWebKey jwkKey) { - return Base64UrlUtility.encode(jwkKeyToJson(jwkKey)); - } - public static String encodeJwkSet(JsonWebKeys jwkSet) { - return Base64UrlUtility.encode(jwkSetToJson(jwkSet)); - } - public static JsonWebKey decodeJwkKey(String jwkJson) { - return readJwkKey(JoseUtils.decodeToString(jwkJson)); - } - public static JsonWebKeys decodeJwkSet(String jwksJson) { - return readJwkSet(JoseUtils.decodeToString(jwksJson)); - } - public static String encryptJwkSet(JsonWebKeys jwkSet, char[] password) { - return encryptJwkSet(jwkSet, password, new DefaultJwkReaderWriter()); - } - public static String encryptJwkSet(JsonWebKeys jwkSet, char[] password, JwkReaderWriter writer) { - return encryptJwkSet(jwkSet, createDefaultEncryption(password), writer); - } - public static String encryptJwkSet(JsonWebKeys jwkSet, JweEncryptionProvider jwe, JwkReaderWriter writer) { - return jwe.encrypt(StringUtils.toBytesUTF8(writer.jwkSetToJson(jwkSet)), - toJweHeaders("jwk-set+json")); - } - public static String encryptJwkSet(JsonWebKeys jwkSet, PublicKey key, KeyAlgorithm keyAlgo, - ContentAlgorithm contentAlgo) { - return JweUtils.encrypt(key, keyAlgo, contentAlgo, StringUtils.toBytesUTF8(jwkSetToJson(jwkSet)), - "jwk-set+json"); - } - public static String signJwkSet(JsonWebKeys jwkSet, PrivateKey key, SignatureAlgorithm algo) { - return JwsUtils.sign(key, algo, jwkSetToJson(jwkSet), "jwk-set+json"); - } - public static String encryptJwkSet(JsonWebKeys jwkSet, SecretKey key, KeyAlgorithm keyAlgo, - ContentAlgorithm contentAlgo) { - return JweUtils.encrypt(key, keyAlgo, contentAlgo, StringUtils.toBytesUTF8(jwkSetToJson(jwkSet)), - "jwk-set+json"); - } - public static JsonWebKeys decryptJwkSet(String jsonJwkSet, char[] password) { - return decryptJwkSet(jsonJwkSet, password, new DefaultJwkReaderWriter()); - } - public static JsonWebKeys decryptJwkSet(String jsonJwkSet, char[] password, JwkReaderWriter reader) { - return decryptJwkSet(jsonJwkSet, createDefaultDecryption(password), reader); - } - public static JsonWebKeys decryptJwkSet(String jsonJwkSet, JweDecryptionProvider jwe, JwkReaderWriter reader) { - return reader.jsonToJwkSet(jwe.decrypt(jsonJwkSet).getContentText()); - } - public static JsonWebKeys decryptJwkSet(PrivateKey key, KeyAlgorithm keyAlgo, ContentAlgorithm ctAlgo, - String jsonJwkSet) { - return readJwkSet(toString(JweUtils.decrypt(key, keyAlgo, ctAlgo, jsonJwkSet))); - } - public static JsonWebKeys verifyJwkSet(PublicKey key, SignatureAlgorithm keyAlgo, String jsonJwk) { - return readJwkSet(JwsUtils.verify(key, keyAlgo, jsonJwk)); - } - public static JsonWebKeys decryptJwkSet(SecretKey key, KeyAlgorithm keyAlgo, ContentAlgorithm ctAlgo, - String jsonJwkSet) { - return readJwkSet(toString(JweUtils.decrypt(key, keyAlgo, ctAlgo, jsonJwkSet))); - } - public static JsonWebKeys decryptJwkSet(InputStream is, char[] password) throws IOException { - return decryptJwkSet(is, password, new DefaultJwkReaderWriter()); - } - public static JsonWebKeys decryptJwkSet(InputStream is, char[] password, JwkReaderWriter reader) - throws IOException { - return decryptJwkSet(is, createDefaultDecryption(password), reader); - } - public static JsonWebKeys decryptJwkSet(InputStream is, JweDecryptionProvider jwe, JwkReaderWriter reader) - throws IOException { - return reader.jsonToJwkSet(jwe.decrypt(IOUtils.readStringFromStream(is)).getContentText()); - } - public static String encryptJwkKey(JsonWebKey jwk, char[] password) { - return encryptJwkKey(jwk, password, new DefaultJwkReaderWriter()); - } - public static String encryptJwkKey(JsonWebKey jwkKey, char[] password, JwkReaderWriter writer) { - return encryptJwkKey(jwkKey, createDefaultEncryption(password), writer); - } - public static String encryptJwkKey(JsonWebKey jwkKey, JweEncryptionProvider jwe, JwkReaderWriter writer) { - return jwe.encrypt(StringUtils.toBytesUTF8(writer.jwkToJson(jwkKey)), - toJweHeaders("jwk+json")); - } - public static String encryptJwkKey(JsonWebKey jwkKey, PublicKey key, KeyAlgorithm keyAlgo, - ContentAlgorithm contentAlgo) { - return JweUtils.encrypt(key, keyAlgo, contentAlgo, StringUtils.toBytesUTF8(jwkKeyToJson(jwkKey)), - "jwk+json"); - } - public static String encryptJwkKey(JsonWebKey jwkKey, SecretKey key, KeyAlgorithm keyAlgo, - ContentAlgorithm contentAlgo) { - return JweUtils.encrypt(key, keyAlgo, contentAlgo, StringUtils.toBytesUTF8(jwkKeyToJson(jwkKey)), - "jwk+json"); - } - public static String signJwkKey(JsonWebKey jwkKey, PrivateKey key, SignatureAlgorithm algo) { - return JwsUtils.sign(key, algo, jwkKeyToJson(jwkKey), "jwk+json"); - } - public static JsonWebKey decryptJwkKey(String jsonJwkKey, char[] password) { - return decryptJwkKey(jsonJwkKey, password, new DefaultJwkReaderWriter()); - } - public static JsonWebKey decryptJwkKey(String jsonJwkKey, char[] password, JwkReaderWriter reader) { - return decryptJwkKey(jsonJwkKey, createDefaultDecryption(password), reader); - } - public static JsonWebKey decryptJwkKey(PrivateKey key, KeyAlgorithm keyAlgo, ContentAlgorithm ctAlgo, - String jsonJwk) { - return readJwkKey(toString(JweUtils.decrypt(key, keyAlgo, ctAlgo, jsonJwk))); - } - public static JsonWebKey verifyJwkKey(PublicKey key, SignatureAlgorithm keyAlgo, String jsonJwk) { - return readJwkKey(JwsUtils.verify(key, keyAlgo, jsonJwk)); - } - public static JsonWebKey decryptJwkKey(SecretKey key, KeyAlgorithm keyAlgo, ContentAlgorithm ctAlgo, - String jsonJwk) { - return readJwkKey(toString(JweUtils.decrypt(key, keyAlgo, ctAlgo, jsonJwk))); - } - public static JsonWebKey decryptJwkKey(String jsonJwkKey, JweDecryptionProvider jwe, JwkReaderWriter reader) { - return reader.jsonToJwk(jwe.decrypt(jsonJwkKey).getContentText()); - } - public static JsonWebKey decryptJwkKey(InputStream is, char[] password) throws IOException { - return decryptJwkKey(is, password, new DefaultJwkReaderWriter()); - } - public static JsonWebKey decryptJwkKey(InputStream is, char[] password, JwkReaderWriter reader) - throws IOException { - return decryptJwkKey(is, createDefaultDecryption(password), reader); - } - public static JsonWebKey decryptJwkKey(InputStream is, JweDecryptionProvider jwe, JwkReaderWriter reader) - throws IOException { - return reader.jsonToJwk(jwe.decrypt(IOUtils.readStringFromStream(is)).getContentText()); - } - public static JsonWebKeys loadJwkSet(Message m, Properties props, PrivateKeyPasswordProvider cb) { - return loadJwkSet(m, props, cb, new DefaultJwkReaderWriter()); - } - public static JsonWebKeys loadJwkSet(Message m, Properties props, PrivateKeyPasswordProvider cb, - JwkReaderWriter reader) { - String key = (String)props.get(JoseConstants.RSSEC_KEY_STORE_FILE); - JsonWebKeys jwkSet = key != null ? (JsonWebKeys)m.getExchange().get(key) : null; - if (jwkSet == null) { - jwkSet = loadJwkSet(props, m.getExchange().getBus(), cb, reader); - if (key != null) { - m.getExchange().put(key, jwkSet); - } - } - return jwkSet; - } - public static JsonWebKeys loadJwkSet(Properties props, Bus bus, PrivateKeyPasswordProvider cb) { - return loadJwkSet(props, bus, cb, new DefaultJwkReaderWriter()); - } - public static JsonWebKeys loadJwkSet(Properties props, Bus bus, PrivateKeyPasswordProvider cb, - JwkReaderWriter reader) { - JweDecryptionProvider decryption = cb != null - ? new AesCbcHmacJweDecryption(new PbesHmacAesWrapKeyDecryptionAlgorithm(cb.getPassword(props))) : null; - return loadJwkSet(props, bus, decryption, reader); - } - public static JsonWebKeys loadJwkSet(Properties props, Bus bus, JweDecryptionProvider jwe, JwkReaderWriter reader) { - String keyContent = null; - String keyStoreLoc = props.getProperty(JoseConstants.RSSEC_KEY_STORE_FILE); - if (keyStoreLoc != null) { - try { - InputStream is = JoseUtils.getResourceStream(keyStoreLoc, bus); - if (is == null) { - throw new JwkException("Error in loading keystore location: " + keyStoreLoc); - } - keyContent = IOUtils.readStringFromStream(is); - } catch (Exception ex) { - throw new JwkException(ex); - } - } else { - keyContent = props.getProperty(JoseConstants.RSSEC_KEY_STORE_JWKSET); - if (keyContent == null) { - keyContent = props.getProperty(JoseConstants.RSSEC_KEY_STORE_JWKKEY); - } - } - if (jwe != null) { - keyContent = jwe.decrypt(keyContent).getContentText(); - } - if (props.getProperty(JoseConstants.RSSEC_KEY_STORE_JWKKEY) == null) { - return reader.jsonToJwkSet(keyContent); - } else { - JsonWebKey key = reader.jsonToJwk(keyContent); - JsonWebKeys keys = new JsonWebKeys(); - keys.setKeys(Collections.singletonList(key)); - return keys; - } - } - public static JsonWebKey loadJsonWebKey(Message m, Properties props, KeyOperation keyOper) { - return loadJsonWebKey(m, props, keyOper, null); - } - public static JsonWebKey loadJsonWebKey(Message m, Properties props, KeyOperation keyOper, String inHeaderKid) { - return loadJsonWebKey(m, props, keyOper, inHeaderKid, new DefaultJwkReaderWriter()); - } - public static JsonWebKey loadJsonWebKey(Message m, Properties props, KeyOperation keyOper, String inHeaderKid, - JwkReaderWriter reader) { - PrivateKeyPasswordProvider cb = KeyManagementUtils.loadPasswordProvider(m, props, keyOper); - JsonWebKeys jwkSet = loadJwkSet(m, props, cb, reader); - String kid = null; - if (inHeaderKid != null - && MessageUtils.getContextualBoolean(m, JoseConstants.RSSEC_ACCEPT_PUBLIC_KEY_PROP, true)) { - kid = inHeaderKid; - } else { - kid = KeyManagementUtils.getKeyId(m, props, JoseConstants.RSSEC_KEY_STORE_ALIAS, keyOper); - } - if (kid != null) { - return jwkSet.getKey(kid); - } else if (keyOper != null) { - List<JsonWebKey> keys = jwkSet.getKeyOperationMap().get(keyOper); - if (keys != null && keys.size() == 1) { - return keys.get(0); - } - } - return null; - } - public static List<JsonWebKey> loadJsonWebKeys(Message m, Properties props, KeyOperation keyOper) { - return loadJsonWebKeys(m, props, keyOper, new DefaultJwkReaderWriter()); - } - - public static List<JsonWebKey> loadJsonWebKeys(Message m, Properties props, - KeyOperation keyOper, - JwkReaderWriter reader) { - PrivateKeyPasswordProvider cb = KeyManagementUtils.loadPasswordProvider(m, props, keyOper); - JsonWebKeys jwkSet = loadJwkSet(m, props, cb, reader); - String kid = KeyManagementUtils.getKeyId(m, props, JoseConstants.RSSEC_KEY_STORE_ALIAS, keyOper); - if (kid != null) { - return Collections.singletonList(jwkSet.getKey(kid)); - } - String kids = KeyManagementUtils.getKeyId(m, props, JoseConstants.RSSEC_KEY_STORE_ALIASES, keyOper); - if (kids != null) { - String[] values = kids.split(","); - List<JsonWebKey> keys = new ArrayList<JsonWebKey>(values.length); - for (String value : values) { - keys.add(jwkSet.getKey(value)); - } - return keys; - } - if (keyOper != null) { - List<JsonWebKey> keys = jwkSet.getKeyOperationMap().get(keyOper); - if (keys != null && keys.size() == 1) { - return Collections.singletonList(keys.get(0)); - } - } - return null; - } - public static RSAPublicKey toRSAPublicKey(JsonWebKey jwk) { - return toRSAPublicKey(jwk, false); - } - public static RSAPublicKey toRSAPublicKey(JsonWebKey jwk, boolean checkX509) { - String encodedModulus = (String)jwk.getProperty(JsonWebKey.RSA_MODULUS); - String encodedPublicExponent = (String)jwk.getProperty(JsonWebKey.RSA_PUBLIC_EXP); - if (encodedModulus != null) { - return CryptoUtils.getRSAPublicKey(encodedModulus, encodedPublicExponent); - } else if (checkX509) { - List<X509Certificate> chain = toX509CertificateChain(jwk); - return (RSAPublicKey)chain.get(0).getPublicKey(); - } - return null; - } - public static List<X509Certificate> toX509CertificateChain(JsonWebKey jwk) { - List<String> base64EncodedChain = jwk.getX509Chain(); - return KeyManagementUtils.toX509CertificateChain(base64EncodedChain); - } - public static JsonWebKey fromECPublicKey(ECPublicKey pk, String curve) { - JsonWebKey jwk = new JsonWebKey(); - jwk.setKeyType(KeyType.EC); - jwk.setProperty(JsonWebKey.EC_CURVE, curve); - jwk.setProperty(JsonWebKey.EC_X_COORDINATE, - Base64UrlUtility.encode(pk.getW().getAffineX().toByteArray())); - jwk.setProperty(JsonWebKey.EC_Y_COORDINATE, - Base64UrlUtility.encode(pk.getW().getAffineY().toByteArray())); - return jwk; - } - public static JsonWebKey fromECPrivateKey(ECPrivateKey pk, String curve) { - JsonWebKey jwk = new JsonWebKey(); - jwk.setKeyType(KeyType.EC); - jwk.setProperty(JsonWebKey.EC_CURVE, curve); - jwk.setProperty(JsonWebKey.EC_PRIVATE_KEY, - Base64UrlUtility.encode(pk.getS().toByteArray())); - return jwk; - } - public static JsonWebKey fromRSAPublicKey(RSAPublicKey pk, String algo) { - JsonWebKey jwk = prepareRSAJwk(pk.getModulus(), algo); - String encodedPublicExponent = Base64UrlUtility.encode(pk.getPublicExponent().toByteArray()); - jwk.setProperty(JsonWebKey.RSA_PUBLIC_EXP, encodedPublicExponent); - return jwk; - } - public static JsonWebKey fromX509CertificateChain(List<X509Certificate> chain, String algo) { - JsonWebKey jwk = new JsonWebKey(); - jwk.setAlgorithm(algo); - List<String> encodedChain = KeyManagementUtils.encodeX509CertificateChain(chain); - jwk.setX509Chain(encodedChain); - return jwk; - } - - public static RSAPrivateKey toRSAPrivateKey(JsonWebKey jwk) { - String encodedModulus = (String)jwk.getProperty(JsonWebKey.RSA_MODULUS); - String encodedPrivateExponent = (String)jwk.getProperty(JsonWebKey.RSA_PRIVATE_EXP); - String encodedPrimeP = (String)jwk.getProperty(JsonWebKey.RSA_FIRST_PRIME_FACTOR); - if (encodedPrimeP == null) { - return CryptoUtils.getRSAPrivateKey(encodedModulus, encodedPrivateExponent); - } else { - String encodedPublicExponent = (String)jwk.getProperty(JsonWebKey.RSA_PUBLIC_EXP); - String encodedPrimeQ = (String)jwk.getProperty(JsonWebKey.RSA_SECOND_PRIME_FACTOR); - String encodedPrimeExpP = (String)jwk.getProperty(JsonWebKey.RSA_FIRST_PRIME_CRT); - String encodedPrimeExpQ = (String)jwk.getProperty(JsonWebKey.RSA_SECOND_PRIME_CRT); - String encodedCrtCoefficient = (String)jwk.getProperty(JsonWebKey.RSA_FIRST_CRT_COEFFICIENT); - return CryptoUtils.getRSAPrivateKey(encodedModulus, - encodedPublicExponent, - encodedPrivateExponent, - encodedPrimeP, - encodedPrimeQ, - encodedPrimeExpP, - encodedPrimeExpQ, - encodedCrtCoefficient); - } - } - public static JsonWebKey fromRSAPrivateKey(RSAPrivateKey pk, String algo) { - JsonWebKey jwk = prepareRSAJwk(pk.getModulus(), algo); - String encodedPrivateExponent = Base64UrlUtility.encode(pk.getPrivateExponent().toByteArray()); - jwk.setProperty(JsonWebKey.RSA_PRIVATE_EXP, encodedPrivateExponent); - if (pk instanceof RSAPrivateCrtKey) { - RSAPrivateCrtKey pkCrt = (RSAPrivateCrtKey)pk; - jwk.setProperty(JsonWebKey.RSA_FIRST_PRIME_FACTOR, - Base64UrlUtility.encode(pkCrt.getPrimeP().toByteArray())); - jwk.setProperty(JsonWebKey.RSA_SECOND_PRIME_FACTOR, - Base64UrlUtility.encode(pkCrt.getPrimeQ().toByteArray())); - jwk.setProperty(JsonWebKey.RSA_FIRST_PRIME_CRT, - Base64UrlUtility.encode(pkCrt.getPrimeExponentP().toByteArray())); - jwk.setProperty(JsonWebKey.RSA_SECOND_PRIME_CRT, - Base64UrlUtility.encode(pkCrt.getPrimeExponentQ().toByteArray())); - jwk.setProperty(JsonWebKey.RSA_FIRST_CRT_COEFFICIENT, - Base64UrlUtility.encode(pkCrt.getCrtCoefficient().toByteArray())); - } - // "oth" can be populated too if needed - return jwk; - } - public static ECPublicKey toECPublicKey(JsonWebKey jwk) { - String eCurve = (String)jwk.getProperty(JsonWebKey.EC_CURVE); - String encodedXCoord = (String)jwk.getProperty(JsonWebKey.EC_X_COORDINATE); - String encodedYCoord = (String)jwk.getProperty(JsonWebKey.EC_Y_COORDINATE); - return CryptoUtils.getECPublicKey(eCurve, encodedXCoord, encodedYCoord); - } - public static ECPrivateKey toECPrivateKey(JsonWebKey jwk) { - String eCurve = (String)jwk.getProperty(JsonWebKey.EC_CURVE); - String encodedPrivateKey = (String)jwk.getProperty(JsonWebKey.EC_PRIVATE_KEY); - return CryptoUtils.getECPrivateKey(eCurve, encodedPrivateKey); - } - - public static SecretKey toSecretKey(JsonWebKey jwk) { - return CryptoUtils.createSecretKeySpec((String)jwk.getProperty(JsonWebKey.OCTET_KEY_VALUE), - AlgorithmUtils.toJavaName(jwk.getAlgorithm())); - } - public static JsonWebKey fromSecretKey(SecretKey secretKey, String algo) { - if (!AlgorithmUtils.isOctet(algo)) { - throw new JwkException("Invalid algorithm"); - } - JsonWebKey jwk = new JsonWebKey(); - jwk.setKeyType(KeyType.OCTET); - jwk.setAlgorithm(algo); - String encodedSecretKey = Base64UrlUtility.encode(secretKey.getEncoded()); - jwk.setProperty(JsonWebKey.OCTET_KEY_VALUE, encodedSecretKey); - return jwk; - } - - - private static JweEncryptionProvider createDefaultEncryption(char[] password) { - KeyEncryptionProvider keyEncryption = - new PbesHmacAesWrapKeyEncryptionAlgorithm(password, KeyAlgorithm.PBES2_HS256_A128KW); - return new AesCbcHmacJweEncryption(ContentAlgorithm.A128CBC_HS256, keyEncryption); - } - private static JweDecryptionProvider createDefaultDecryption(char[] password) { - KeyDecryptionProvider keyDecryption = new PbesHmacAesWrapKeyDecryptionAlgorithm(password); - return new AesCbcHmacJweDecryption(keyDecryption); - } - private static JsonWebKey prepareRSAJwk(BigInteger modulus, String algo) { - if (!AlgorithmUtils.isRsa(algo)) { - throw new JwkException("Invalid algorithm"); - } - JsonWebKey jwk = new JsonWebKey(); - jwk.setKeyType(KeyType.RSA); - jwk.setAlgorithm(algo); - String encodedModulus = Base64UrlUtility.encode(modulus.toByteArray()); - jwk.setProperty(JsonWebKey.RSA_MODULUS, encodedModulus); - return jwk; - } - private static String toString(byte[] bytes) { - try { - return new String(bytes, "UTF-8"); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - private static JweHeaders toJweHeaders(String ct) { - return new JweHeaders(Collections.<String, Object>singletonMap(JoseConstants.HEADER_CONTENT_TYPE, ct)); - } - public static void setPublicKeyInfo(JsonWebKey jwk, JoseHeaders headers, String algo, - boolean reportPublicKey, boolean reportPublicKeyId) { - if (reportPublicKey && KeyType.RSA.equals(jwk.getKeyType())) { - List<String> chain = CastUtils.cast((List<?>)jwk.getProperty("x5c")); - //TODO: if needed the chain can be reported as part of a 'jwk' property - if (chain != null) { - headers.setX509Chain(chain); - } else { - JsonWebKey jwkPublic = JwkUtils.fromRSAPublicKey(JwkUtils.toRSAPublicKey(jwk), algo); - if (reportPublicKeyId && jwk.getKeyId() != null) { - jwkPublic.setKeyId(jwk.getKeyId()); - } - headers.setJsonWebKey(jwkPublic); - } - } - if (reportPublicKeyId && jwk.getKeyId() != null) { - headers.setKeyId(jwk.getKeyId()); - } - - } -}
http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/KeyOperation.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/KeyOperation.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/KeyOperation.java deleted file mode 100644 index c258543..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/KeyOperation.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jwk; - - -public enum KeyOperation { - SIGN(JsonWebKey.KEY_OPER_SIGN), - VERIFY(JsonWebKey.KEY_OPER_VERIFY), - ENCRYPT(JsonWebKey.KEY_OPER_ENCRYPT), - DECRYPT(JsonWebKey.KEY_OPER_DECRYPT), - WRAPKEY(JsonWebKey.KEY_OPER_WRAP_KEY), - UNWRAPKEY(JsonWebKey.KEY_OPER_UNWRAP_KEY), - DERIVEKEY(JsonWebKey.KEY_OPER_DERIVE_KEY), - DERIVEBITS(JsonWebKey.KEY_OPER_DERIVE_BITS); - - private final String oper; - private KeyOperation(String oper) { - this.oper = oper; - } - public static KeyOperation getKeyOperation(String oper) { - if (oper == null) { - return null; - } - return valueOf(oper.toUpperCase()); - } - public String toString() { - return oper; - } - -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/KeyType.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/KeyType.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/KeyType.java deleted file mode 100644 index b10afb8..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/KeyType.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jwk; - - -public enum KeyType { - RSA(JsonWebKey.KEY_TYPE_RSA), - EC(JsonWebKey.KEY_TYPE_ELLIPTIC), - OCTET(JsonWebKey.KEY_TYPE_OCTET); - - private final String type; - private KeyType(String type) { - this.type = type; - } - public static KeyType getKeyType(String type) { - if (type == null) { - return null; - } else if (JsonWebKey.KEY_TYPE_OCTET.equals(type)) { - return OCTET; - } else { - return valueOf(type); - } - } - public String toString() { - return type; - } - -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/PublicKeyUse.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/PublicKeyUse.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/PublicKeyUse.java deleted file mode 100644 index 9b46b4f..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jwk/PublicKeyUse.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jwk; - - -public enum PublicKeyUse { - SIGN(JsonWebKey.PUBLIC_KEY_USE_SIGN), - ENCRYPT(JsonWebKey.PUBLIC_KEY_USE_ENCRYPT); - - private final String use; - private PublicKeyUse(String use) { - this.use = use; - } - public static PublicKeyUse getPublicKeyUse(String use) { - if (use == null) { - return null; - } - if (JsonWebKey.PUBLIC_KEY_USE_SIGN.equals(use)) { - return SIGN; - } else if (JsonWebKey.PUBLIC_KEY_USE_ENCRYPT.equals(use)) { - return ENCRYPT; - } else { - return valueOf(use); - } - } - public String toString() { - return use; - } - -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/AbstractJwsSignatureProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/AbstractJwsSignatureProvider.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/AbstractJwsSignatureProvider.java deleted file mode 100644 index df400fa..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/AbstractJwsSignatureProvider.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.util.logging.Logger; - -import org.apache.cxf.common.logging.LogUtils; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; - - -public abstract class AbstractJwsSignatureProvider implements JwsSignatureProvider { - protected static final Logger LOG = LogUtils.getL7dLogger(AbstractJwsSignatureProvider.class); - private SignatureAlgorithm algorithm; - - protected AbstractJwsSignatureProvider(SignatureAlgorithm algo) { - this.algorithm = algo; - } - - protected JwsHeaders prepareHeaders(JwsHeaders headers) { - if (headers == null) { - headers = new JwsHeaders(); - } - SignatureAlgorithm sigAlgo = headers.getSignatureAlgorithm(); - if (sigAlgo != null) { - checkAlgorithm(sigAlgo.getJwaName()); - } else { - checkAlgorithm(algorithm.getJwaName()); - headers.setSignatureAlgorithm(algorithm); - } - return headers; - } - @Override - public SignatureAlgorithm getAlgorithm() { - return algorithm; - } - @Override - public byte[] sign(JwsHeaders headers, byte[] content) { - JwsSignature sig = createJwsSignature(headers); - sig.update(content, 0, content.length); - return sig.sign(); - } - @Override - public JwsSignature createJwsSignature(JwsHeaders headers) { - return doCreateJwsSignature(prepareHeaders(headers)); - } - - protected abstract JwsSignature doCreateJwsSignature(JwsHeaders headers); - - protected void checkAlgorithm(String algo) { - if (algo == null) { - LOG.warning("Signature algorithm is not set"); - throw new JwsException(JwsException.Error.ALGORITHM_NOT_SET); - } - if (!isValidAlgorithmFamily(algo)) { - LOG.warning("Invalid signature algorithm: " + algo); - throw new JwsException(JwsException.Error.INVALID_ALGORITHM); - } - } - protected abstract boolean isValidAlgorithmFamily(String algo); -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/EcDsaJwsSignatureProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/EcDsaJwsSignatureProvider.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/EcDsaJwsSignatureProvider.java deleted file mode 100644 index 3bb92b9..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/EcDsaJwsSignatureProvider.java +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.security.SecureRandom; -import java.security.Signature; -import java.security.interfaces.ECPrivateKey; -import java.security.spec.AlgorithmParameterSpec; - -import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; - -public class EcDsaJwsSignatureProvider extends PrivateKeyJwsSignatureProvider { - public EcDsaJwsSignatureProvider(ECPrivateKey key, SignatureAlgorithm algo) { - this(key, null, algo); - } - public EcDsaJwsSignatureProvider(ECPrivateKey key, AlgorithmParameterSpec spec, SignatureAlgorithm algo) { - this(key, null, spec, algo); - } - public EcDsaJwsSignatureProvider(ECPrivateKey key, SecureRandom random, AlgorithmParameterSpec spec, - SignatureAlgorithm algo) { - super(key, random, spec, algo); - } - @Override - protected boolean isValidAlgorithmFamily(String algo) { - return AlgorithmUtils.isEcDsaSign(algo); - } - @Override - protected JwsSignature doCreateJwsSignature(Signature s) { - return new EcDsaPrivateKeyJwsSignature(s, - EcDsaJwsSignatureVerifier.SIGNATURE_LENGTH_MAP.get(super.getAlgorithm().getJwaName())); - } - - protected static class EcDsaPrivateKeyJwsSignature extends PrivateKeyJwsSignature { - private int outLen; - public EcDsaPrivateKeyJwsSignature(Signature s, int outLen) { - super(s); - this.outLen = outLen; - } - @Override - public byte[] sign() { - byte[] jcaDer = super.sign(); - return jcaOutputToJoseOutput(outLen, jcaDer); - } - } - - private static byte[] jcaOutputToJoseOutput(int jwsSignatureLen, byte jcaDer[]) { - // DER uses a pattern of type-length-value triplets - // http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One#Example_encoded_in_DER - - // The algorithm implementation guarantees the correct DER format so no extra validation - - // ECDSA signature production: - // 48 (SEQUENCE) + Total Length (1 or 2 bytes, the 1st byte is -127 if 2 bytes) - // + R & S triples, where both triples are represented as - // 2(INTEGER TYPE) + length + the actual sequence of a given length; - // The sequence might have the extra leading zeroes which need to be skipped - int requiredPartLen = jwsSignatureLen / 2; - - int rsDataBlockStart = jcaDer[1] == -127 ? 4 : 3; - int rPartLen = jcaDer[rsDataBlockStart]; - int rDataBlockStart = rsDataBlockStart + 1; - int rPartLenDiff = rPartLen - requiredPartLen; - int rValueStart = rDataBlockStart + getDataBlockOffset(jcaDer, rDataBlockStart, rPartLenDiff); - - int sPartStart = rDataBlockStart + rPartLen; - int sPartLen = jcaDer[sPartStart + 1]; - int sPartLenDiff = sPartLen - requiredPartLen; - int sDataBlockStart = sPartStart + 2; - int sValueStart = sDataBlockStart + getDataBlockOffset(jcaDer, sDataBlockStart, sPartLenDiff); - - byte[] result = new byte[jwsSignatureLen]; - System.arraycopy(jcaDer, rValueStart, result, - rPartLenDiff < 0 ? rPartLenDiff * -1 : 0, - rPartLenDiff < 0 ? requiredPartLen + rPartLenDiff : requiredPartLen); - System.arraycopy(jcaDer, sValueStart, result, - sPartLenDiff < 0 ? requiredPartLen + sPartLenDiff * -1 : requiredPartLen, - sPartLenDiff < 0 ? requiredPartLen + sPartLenDiff : requiredPartLen); - return result; - } - private static int getDataBlockOffset(byte[] jcaDer, int blockStart, int partLenDiff) { - // ECDSA productions have 64, 96 or 132 output lengths. The R and S parts would be 32, 48 or 66 bytes each. - // If it is 32 or 48 bytes then we may have occasional extra zeroes in the JCA DER output - int i = 0; - if (partLenDiff > 0) { - while (i < partLenDiff && jcaDer[blockStart + i] == 0) { - i++; - } - } - return i; - } - - -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/EcDsaJwsSignatureVerifier.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/EcDsaJwsSignatureVerifier.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/EcDsaJwsSignatureVerifier.java deleted file mode 100644 index 025cd21..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/EcDsaJwsSignatureVerifier.java +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.security.PublicKey; -import java.security.spec.AlgorithmParameterSpec; -import java.util.HashMap; -import java.util.Map; - -import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; - -public class EcDsaJwsSignatureVerifier extends PublicKeyJwsSignatureVerifier { - static final Map<String, Integer> SIGNATURE_LENGTH_MAP; - static { - SIGNATURE_LENGTH_MAP = new HashMap<String, Integer>(); - SIGNATURE_LENGTH_MAP.put(SignatureAlgorithm.ES256.getJwaName(), 64); - SIGNATURE_LENGTH_MAP.put(SignatureAlgorithm.ES384.getJwaName(), 96); - SIGNATURE_LENGTH_MAP.put(SignatureAlgorithm.ES512.getJwaName(), 132); - } - public EcDsaJwsSignatureVerifier(PublicKey key, SignatureAlgorithm supportedAlgo) { - this(key, null, supportedAlgo); - } - public EcDsaJwsSignatureVerifier(PublicKey key, AlgorithmParameterSpec spec, SignatureAlgorithm supportedAlgo) { - super(key, spec, supportedAlgo); - } - @Override - public boolean verify(JwsHeaders headers, String unsignedText, byte[] signature) { - final String algoName = super.getAlgorithm().getJwaName(); - if (SIGNATURE_LENGTH_MAP.get(algoName) != signature.length) { - LOG.warning("Algorithm " + algoName + " signature length is " + SIGNATURE_LENGTH_MAP.get(algoName) - + ", actual length is " + signature.length); - throw new JwsException(JwsException.Error.INVALID_SIGNATURE); - } - byte[] der = signatureToDer(signature); - return super.verify(headers, unsignedText, der); - } - @Override - protected boolean isValidAlgorithmFamily(String algo) { - return AlgorithmUtils.isEcDsaSign(algo); - } - private static byte[] signatureToDer(byte joseSig[]) { - int partLen = joseSig.length / 2; - int rOffset = joseSig[0] < 0 ? 1 : 0; - int sOffset = joseSig[partLen] < 0 ? 1 : 0; - int rPartLen = partLen + rOffset; - int sPartLen = partLen + sOffset; - int totalLenBytesCount = joseSig.length > 127 ? 2 : 1; - int rPartStart = 1 + totalLenBytesCount + 2; - byte[] der = new byte[rPartStart + 2 + rPartLen + sPartLen]; - der[0] = 48; - if (totalLenBytesCount == 2) { - der[1] = -127; - } - der[totalLenBytesCount] = (byte)(der.length - (1 + totalLenBytesCount)); - der[totalLenBytesCount + 1] = 2; - der[totalLenBytesCount + 2] = (byte)rPartLen; - int sPartStart = rPartStart + rPartLen; - der[sPartStart] = 2; - der[sPartStart + 1] = (byte)sPartLen; - System.arraycopy(joseSig, 0, der, rPartStart + rOffset, partLen); - System.arraycopy(joseSig, partLen, der, sPartStart + 2 + sOffset, partLen); - return der; - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureProvider.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureProvider.java deleted file mode 100644 index ce1db97..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureProvider.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.security.spec.AlgorithmParameterSpec; - -import javax.crypto.Mac; - -import org.apache.cxf.common.util.Base64Exception; -import org.apache.cxf.common.util.Base64UrlUtility; -import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; -import org.apache.cxf.rt.security.crypto.HmacUtils; - -public class HmacJwsSignatureProvider extends AbstractJwsSignatureProvider { - private byte[] key; - private AlgorithmParameterSpec hmacSpec; - - public HmacJwsSignatureProvider(byte[] key, SignatureAlgorithm algo) { - this(key, null, algo); - } - public HmacJwsSignatureProvider(byte[] key, AlgorithmParameterSpec spec, SignatureAlgorithm algo) { - super(algo); - this.key = key; - this.hmacSpec = spec; - } - public HmacJwsSignatureProvider(String encodedKey, SignatureAlgorithm algo) { - super(algo); - try { - this.key = Base64UrlUtility.decode(encodedKey); - } catch (Base64Exception ex) { - LOG.warning("Hmac key can not be decoded"); - throw new JwsException(JwsException.Error.INVALID_KEY, ex); - } - } - - protected JwsSignature doCreateJwsSignature(JwsHeaders headers) { - final String sigAlgo = headers.getSignatureAlgorithm().getJwaName(); - final Mac mac = HmacUtils.getInitializedMac(key, - AlgorithmUtils.toJavaName(sigAlgo), - hmacSpec); - return new JwsSignature() { - - @Override - public void update(byte[] src, int off, int len) { - mac.update(src, off, len); - } - - @Override - public byte[] sign() { - return mac.doFinal(); - } - - }; - } - @Override - protected boolean isValidAlgorithmFamily(String algo) { - return AlgorithmUtils.isHmacSign(algo); - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureVerifier.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureVerifier.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureVerifier.java deleted file mode 100644 index 7910659..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/HmacJwsSignatureVerifier.java +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.security.spec.AlgorithmParameterSpec; -import java.util.Arrays; -import java.util.logging.Logger; - -import org.apache.cxf.common.logging.LogUtils; -import org.apache.cxf.rs.security.jose.common.JoseUtils; -import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; -import org.apache.cxf.rt.security.crypto.HmacUtils; - -public class HmacJwsSignatureVerifier implements JwsSignatureVerifier { - protected static final Logger LOG = LogUtils.getL7dLogger(HmacJwsSignatureVerifier.class); - private byte[] key; - private AlgorithmParameterSpec hmacSpec; - private SignatureAlgorithm supportedAlgo; - - public HmacJwsSignatureVerifier(String encodedKey) { - this(JoseUtils.decode(encodedKey), SignatureAlgorithm.HS256); - } - public HmacJwsSignatureVerifier(String encodedKey, SignatureAlgorithm supportedAlgo) { - this(JoseUtils.decode(encodedKey), supportedAlgo); - } - public HmacJwsSignatureVerifier(byte[] key, SignatureAlgorithm supportedAlgo) { - this(key, null, supportedAlgo); - } - public HmacJwsSignatureVerifier(byte[] key, AlgorithmParameterSpec spec, SignatureAlgorithm supportedAlgo) { - this.key = key; - this.hmacSpec = spec; - this.supportedAlgo = supportedAlgo; - } - - - @Override - public boolean verify(JwsHeaders headers, String unsignedText, byte[] signature) { - byte[] expected = computeMac(headers, unsignedText); - return Arrays.equals(expected, signature); - } - - private byte[] computeMac(JwsHeaders headers, String text) { - final String sigAlgo = checkAlgorithm(headers.getSignatureAlgorithm()); - return HmacUtils.computeHmac(key, - AlgorithmUtils.toJavaName(sigAlgo), - hmacSpec, - text); - } - - protected String checkAlgorithm(SignatureAlgorithm sigAlgo) { - - if (sigAlgo == null) { - LOG.warning("Signature algorithm is not set"); - throw new JwsException(JwsException.Error.ALGORITHM_NOT_SET); - } - String algo = sigAlgo.getJwaName(); - if (!AlgorithmUtils.isHmacSign(algo) - || !algo.equals(supportedAlgo.getJwaName())) { - LOG.warning("Invalid signature algorithm: " + algo); - throw new JwsException(JwsException.Error.INVALID_ALGORITHM); - } - return algo; - } - @Override - public SignatureAlgorithm getAlgorithm() { - return supportedAlgo; - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactConsumer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactConsumer.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactConsumer.java deleted file mode 100644 index 9d57222..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactConsumer.java +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.security.PublicKey; -import java.security.cert.X509Certificate; -import java.util.logging.Logger; - -import org.apache.cxf.common.logging.LogUtils; -import org.apache.cxf.common.util.StringUtils; -import org.apache.cxf.jaxrs.json.basic.JsonMapObject; -import org.apache.cxf.jaxrs.json.basic.JsonMapObjectReaderWriter; -import org.apache.cxf.rs.security.jose.common.JoseUtils; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; -import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; - -public class JwsCompactConsumer { - protected static final Logger LOG = LogUtils.getL7dLogger(JwsCompactConsumer.class); - private JsonMapObjectReaderWriter reader = new JsonMapObjectReaderWriter(); - private String encodedSequence; - private String encodedSignature; - private String headersJson; - private String jwsPayload; - private String decodedJwsPayload; - private JwsHeaders jwsHeaders; - private boolean detached; - public JwsCompactConsumer(String encodedJws) { - this(encodedJws, null, null); - } - public JwsCompactConsumer(String encodedJws, String detachedPayload) { - this(encodedJws, detachedPayload, null); - } - protected JwsCompactConsumer(String encodedJws, String detachedPayload, JsonMapObjectReaderWriter r) { - if (r != null) { - this.reader = r; - } - String[] parts = JoseUtils.getCompactParts(encodedJws); - if (parts.length != 3) { - if (parts.length == 2 && encodedJws.endsWith(".")) { - encodedSignature = ""; - } else { - LOG.warning("Compact JWS does not have 3 parts"); - throw new JwsException(JwsException.Error.INVALID_COMPACT_JWS); - } - } else { - encodedSignature = parts[2]; - } - jwsPayload = parts[1]; - if (detachedPayload != null) { - if (!StringUtils.isEmpty(jwsPayload)) { - LOG.warning("Compact JWS includes a payload expected to be detached"); - throw new JwsException(JwsException.Error.INVALID_COMPACT_JWS); - } - detached = true; - jwsPayload = detachedPayload; - } - encodedSequence = parts[0] + "." + jwsPayload; - headersJson = JoseUtils.decodeToString(parts[0]); - } - public String getUnsignedEncodedSequence() { - return encodedSequence; - } - public String getEncodedSignature() { - return encodedSignature; - } - public String getDecodedJsonHeaders() { - return headersJson; - } - public String getDecodedJwsPayload() { - if (decodedJwsPayload == null) { - if (JwsUtils.isPayloadUnencoded(jwsHeaders)) { - decodedJwsPayload = jwsPayload; - } else { - decodedJwsPayload = JoseUtils.decodeToString(jwsPayload); - } - } - return decodedJwsPayload; - } - public byte[] getDecodedJwsPayloadBytes() { - return StringUtils.toBytesUTF8(getDecodedJwsPayload()); - } - public byte[] getDecodedSignature() { - return encodedSignature.isEmpty() ? new byte[]{} : JoseUtils.decode(encodedSignature); - } - public JwsHeaders getJwsHeaders() { - if (jwsHeaders == null) { - JsonMapObject joseHeaders = reader.fromJsonToJsonObject(headersJson); - if (joseHeaders.getUpdateCount() != null) { - LOG.warning("Duplicate headers have been detected"); - throw new JwsException(JwsException.Error.INVALID_COMPACT_JWS); - } - jwsHeaders = new JwsHeaders(joseHeaders.asMap()); - if (JwsUtils.isPayloadUnencoded(jwsHeaders) && !detached) { - LOG.warning("Only detached payload can be unencoded"); - throw new JwsException(JwsException.Error.INVALID_COMPACT_JWS); - } - } - return jwsHeaders; - } - public boolean verifySignatureWith(JwsSignatureVerifier validator) { - try { - if (validator.verify(getJwsHeaders(), getUnsignedEncodedSequence(), getDecodedSignature())) { - return true; - } - } catch (JwsException ex) { - // ignore - } - LOG.warning("Invalid Signature"); - return false; - } - public boolean verifySignatureWith(JsonWebKey key) { - return verifySignatureWith(JwsUtils.getSignatureVerifier(key)); - } - public boolean verifySignatureWith(JsonWebKey key, SignatureAlgorithm algo) { - return verifySignatureWith(JwsUtils.getSignatureVerifier(key, algo)); - } - public boolean verifySignatureWith(X509Certificate cert, SignatureAlgorithm algo) { - return verifySignatureWith(JwsUtils.getPublicKeySignatureVerifier(cert, algo)); - } - public boolean verifySignatureWith(PublicKey key, SignatureAlgorithm algo) { - return verifySignatureWith(JwsUtils.getPublicKeySignatureVerifier(key, algo)); - } - public boolean verifySignatureWith(byte[] key, SignatureAlgorithm algo) { - return verifySignatureWith(JwsUtils.getHmacSignatureVerifier(key, algo)); - } - public boolean validateCriticalHeaders() { - return JwsUtils.validateCriticalHeaders(getJwsHeaders()); - } - protected JsonMapObjectReaderWriter getReader() { - return reader; - } - -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactProducer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactProducer.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactProducer.java deleted file mode 100644 index 5b4c760..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsCompactProducer.java +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.security.PrivateKey; -import java.util.Properties; - -import org.apache.cxf.common.util.Base64UrlUtility; -import org.apache.cxf.common.util.StringUtils; -import org.apache.cxf.jaxrs.json.basic.JsonMapObjectReaderWriter; -import org.apache.cxf.message.Message; -import org.apache.cxf.phase.PhaseInterceptorChain; -import org.apache.cxf.rs.security.jose.common.JoseConstants; -import org.apache.cxf.rs.security.jose.common.KeyManagementUtils; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; -import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; - -public class JwsCompactProducer { - private JsonMapObjectReaderWriter writer = new JsonMapObjectReaderWriter(); - private JwsHeaders headers; - private String plainJwsPayload; - private String signature; - private boolean detached; - public JwsCompactProducer(String plainJwsPayload) { - this(plainJwsPayload, false); - } - public JwsCompactProducer(String plainJwsPayload, boolean detached) { - this(null, null, plainJwsPayload, detached); - } - public JwsCompactProducer(JwsHeaders headers, String plainJwsPayload) { - this(headers, plainJwsPayload, false); - } - public JwsCompactProducer(JwsHeaders headers, String plainJwsPayload, boolean detached) { - this(headers, null, plainJwsPayload, detached); - } - protected JwsCompactProducer(JwsHeaders headers, JsonMapObjectReaderWriter w, String plainJwsPayload) { - this(headers, w, plainJwsPayload, false); - } - protected JwsCompactProducer(JwsHeaders headers, JsonMapObjectReaderWriter w, String plainJwsPayload, - boolean detached) { - this.headers = headers; - if (w != null) { - this.writer = w; - } - this.plainJwsPayload = plainJwsPayload; - this.detached = detached; - } - public JwsHeaders getJwsHeaders() { - if (headers == null) { - headers = new JwsHeaders(); - } - return headers; - } - public String getUnsignedEncodedJws() { - checkAlgorithm(); - return Base64UrlUtility.encode(writer.toJson(getJwsHeaders())) - + "." - + (detached ? "" : Base64UrlUtility.encode(plainJwsPayload)); - } - private String getSigningInput() { - checkAlgorithm(); - boolean unencoded = JwsUtils.isPayloadUnencoded(getJwsHeaders()); - if (unencoded && !detached) { - throw new JwsException(JwsException.Error.INVALID_COMPACT_JWS); - } - return Base64UrlUtility.encode(writer.toJson(getJwsHeaders())) - + "." - + (unencoded ? plainJwsPayload : Base64UrlUtility.encode(plainJwsPayload)); - } - public String getEncodedSignature() { - return signature; - } - public String getSignedEncodedJws() { - checkAlgorithm(); - boolean noSignature = StringUtils.isEmpty(signature); - if (noSignature && !isPlainText()) { - throw new IllegalStateException("Signature is not available"); - } - return getUnsignedEncodedJws() + "." + (noSignature ? "" : signature); - } - public String signWith(JsonWebKey jwk) { - return signWith(JwsUtils.getSignatureProvider(jwk, - headers.getSignatureAlgorithm())); - } - - public String signWith(PrivateKey key) { - return signWith(JwsUtils.getPrivateKeySignatureProvider(key, - headers.getSignatureAlgorithm())); - } - public String signWith(byte[] key) { - return signWith(JwsUtils.getHmacSignatureProvider(key, - headers.getSignatureAlgorithm())); - } - - public String signWith(JwsSignatureProvider signer) { - byte[] bytes = StringUtils.toBytesUTF8(getSigningInput()); - byte[] sig = signer.sign(getJwsHeaders(), bytes); - return setSignatureBytes(sig); - } - - public String setSignatureText(String signatureText) { - setEncodedSignature(Base64UrlUtility.encode(signatureText)); - return getSignedEncodedJws(); - } - - public boolean isPlainText() { - return SignatureAlgorithm.NONE == getAlgorithm(); - } - - public String setSignatureBytes(byte[] signatureOctets) { - setEncodedSignature(Base64UrlUtility.encode(signatureOctets)); - return getSignedEncodedJws(); - } - - private void setEncodedSignature(String sig) { - this.signature = sig; - } - private SignatureAlgorithm getAlgorithm() { - return getJwsHeaders().getSignatureAlgorithm(); - } - private void checkAlgorithm() { - if (getAlgorithm() == null) { - Message m = PhaseInterceptorChain.getCurrentMessage(); - Properties props = KeyManagementUtils.loadStoreProperties(m, false, - JoseConstants.RSSEC_SIGNATURE_OUT_PROPS, - JoseConstants.RSSEC_SIGNATURE_PROPS); - String signatureAlgo = JwsUtils.getSignatureAlgo(m, props, null, null); - if (signatureAlgo != null) { - getJwsHeaders().setSignatureAlgorithm(SignatureAlgorithm.getAlgorithm(signatureAlgo)); - } - } - - if (getAlgorithm() == null) { - throw new JwsException(JwsException.Error.INVALID_ALGORITHM); - } - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsException.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsException.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsException.java deleted file mode 100644 index 7482b8d..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsException.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import org.apache.cxf.rs.security.jose.common.JoseException; - -public class JwsException extends JoseException { - - private static final long serialVersionUID = 4118589816228511524L; - private Error status; - public JwsException(Error status) { - this(status, null); - } - public JwsException(Error status, Throwable cause) { - super(cause); - this.status = status; - } - public Error getError() { - return status; - } - public static enum Error { - NO_PROVIDER, - NO_VERIFIER, - NO_INIT_PROPERTIES, - ALGORITHM_NOT_SET, - INVALID_ALGORITHM, - INVALID_KEY, - SIGNATURE_FAILURE, - INVALID_SIGNATURE, - INVALID_COMPACT_JWS, - INVALID_JSON_JWS - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsHeaders.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsHeaders.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsHeaders.java deleted file mode 100644 index a2d0e88..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsHeaders.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.util.Map; - -import org.apache.cxf.rs.security.jose.common.JoseConstants; -import org.apache.cxf.rs.security.jose.common.JoseHeaders; -import org.apache.cxf.rs.security.jose.common.JoseType; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; - -public class JwsHeaders extends JoseHeaders { - public JwsHeaders() { - } - public JwsHeaders(JoseType type) { - super(type); - } - public JwsHeaders(JoseHeaders headers) { - super(headers.asMap()); - } - - public JwsHeaders(Map<String, Object> values) { - super(values); - } - public JwsHeaders(SignatureAlgorithm sigAlgo) { - init(sigAlgo); - } - public JwsHeaders(JoseType type, SignatureAlgorithm sigAlgo) { - super(type); - init(sigAlgo); - } - private void init(SignatureAlgorithm sigAlgo) { - setSignatureAlgorithm(sigAlgo); - } - - public void setSignatureAlgorithm(SignatureAlgorithm algo) { - super.setAlgorithm(algo.getJwaName()); - } - - public SignatureAlgorithm getSignatureAlgorithm() { - String algo = super.getAlgorithm(); - return algo == null ? null : SignatureAlgorithm.getAlgorithm(algo); - } - public void setPayloadEncodingStatus(Boolean status) { - super.setProperty(JoseConstants.JWS_HEADER_B64_STATUS_HEADER, status); - } - public Boolean getPayloadEncodingStatus() { - return super.getBooleanProperty(JoseConstants.JWS_HEADER_B64_STATUS_HEADER); - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java deleted file mode 100644 index 3ad5b45..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonConsumer.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.security.PublicKey; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.logging.Logger; - -import org.apache.cxf.common.logging.LogUtils; -import org.apache.cxf.common.util.StringUtils; -import org.apache.cxf.helpers.CastUtils; -import org.apache.cxf.jaxrs.json.basic.JsonMapObject; -import org.apache.cxf.jaxrs.json.basic.JsonMapObjectReaderWriter; -import org.apache.cxf.rs.security.jose.common.JoseUtils; -import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm; -import org.apache.cxf.rs.security.jose.jwk.JsonWebKey; - -public class JwsJsonConsumer { - protected static final Logger LOG = LogUtils.getL7dLogger(JwsJsonConsumer.class); - private String jwsSignedDocument; - private String jwsPayload; - private List<JwsJsonSignatureEntry> signatures = new LinkedList<JwsJsonSignatureEntry>(); - /** - * @param jwsSignedDocument - * signed JWS Document - */ - public JwsJsonConsumer(String jwsSignedDocument) { - this(jwsSignedDocument, null); - } - public JwsJsonConsumer(String jwsSignedDocument, String detachedPayload) { - this.jwsSignedDocument = jwsSignedDocument; - prepare(detachedPayload); - } - - private void prepare(String detachedPayload) { - JsonMapObject jsonObject = new JsonMapObject(); - new JsonMapObjectReaderWriter().fromJson(jsonObject, jwsSignedDocument); - - Map<String, Object> jsonObjectMap = jsonObject.asMap(); - jwsPayload = (String)jsonObjectMap.get("payload"); - if (jwsPayload == null) { - jwsPayload = detachedPayload; - } else if (detachedPayload != null) { - LOG.warning("JSON JWS includes a payload expected to be detached"); - throw new JwsException(JwsException.Error.INVALID_JSON_JWS); - } - if (jwsPayload == null) { - LOG.warning("JSON JWS has no payload"); - throw new JwsException(JwsException.Error.INVALID_JSON_JWS); - } - List<Map<String, Object>> signatureArray = CastUtils.cast((List<?>)jsonObjectMap.get("signatures")); - if (signatureArray != null) { - if (jsonObjectMap.containsKey("signature")) { - LOG.warning("JSON JWS has a flattened 'signature' element and a 'signatures' object"); - throw new JwsException(JwsException.Error.INVALID_JSON_JWS); - } - for (Map<String, Object> signatureEntry : signatureArray) { - this.signatures.add(getSignatureObject(signatureEntry)); - } - } else { - this.signatures.add(getSignatureObject(jsonObjectMap)); - } - if (signatures.isEmpty()) { - LOG.warning("JSON JWS has no signatures"); - throw new JwsException(JwsException.Error.INVALID_JSON_JWS); - } - validateB64Status(); - - - } - private Boolean validateB64Status() { - return JwsJsonProducer.validateB64Status(signatures); - } - protected JwsJsonSignatureEntry getSignatureObject(Map<String, Object> signatureEntry) { - String protectedHeader = (String)signatureEntry.get("protected"); - Map<String, Object> header = CastUtils.cast((Map<?, ?>)signatureEntry.get("header")); - String signature = (String)signatureEntry.get("signature"); - return - new JwsJsonSignatureEntry(jwsPayload, - protectedHeader, - signature, - header != null ? new JwsHeaders(header) : null); - } - public String getSignedDocument() { - return this.jwsSignedDocument; - } - public String getJwsPayload() { - return this.jwsPayload; - } - public String getDecodedJwsPayload() { - if (validateB64Status()) { - return JoseUtils.decodeToString(jwsPayload); - } else { - return jwsPayload; - } - } - public byte[] getDecodedJwsPayloadBytes() { - return StringUtils.toBytesUTF8(getDecodedJwsPayload()); - } - public List<JwsJsonSignatureEntry> getSignatureEntries() { - return Collections.unmodifiableList(signatures); - } - public Map<SignatureAlgorithm, List<JwsJsonSignatureEntry>> getSignatureEntryMap() { - return JwsUtils.getJwsJsonSignatureMap(signatures); - } - public boolean verifySignatureWith(JwsSignatureVerifier validator) { - List<JwsJsonSignatureEntry> theSignatureEntries = - getSignatureEntryMap().get(validator.getAlgorithm()); - if (theSignatureEntries != null) { - for (JwsJsonSignatureEntry signatureEntry : theSignatureEntries) { - if (signatureEntry.verifySignatureWith(validator)) { - return true; - } - } - } - return false; - } - public boolean verifySignatureWith(PublicKey key, SignatureAlgorithm algo) { - return verifySignatureWith(JwsUtils.getPublicKeySignatureVerifier(key, algo)); - } - public boolean verifySignatureWith(byte[] key, SignatureAlgorithm algo) { - return verifySignatureWith(JwsUtils.getHmacSignatureVerifier(key, algo)); - } - public boolean verifySignatureWith(List<JwsSignatureVerifier> validators) { - try { - if (verifyAndGetNonValidated(validators).isEmpty()) { - return true; - } - } catch (JwsException ex) { - // ignore - } - LOG.warning("One of JSON JWS signatures is invalid"); - return false; - } - public List<JwsJsonSignatureEntry> verifyAndGetNonValidated(List<JwsSignatureVerifier> validators) { - // TODO: more effective approach is needed - List<JwsJsonSignatureEntry> validatedSignatures = new LinkedList<JwsJsonSignatureEntry>(); - for (JwsSignatureVerifier validator : validators) { - List<JwsJsonSignatureEntry> theSignatureEntries = - getSignatureEntryMap().get(validator.getAlgorithm()); - if (theSignatureEntries != null) { - for (JwsJsonSignatureEntry sigEntry : theSignatureEntries) { - if (sigEntry.verifySignatureWith(validator)) { - validatedSignatures.add(sigEntry); - break; - } - } - } - } - List<JwsJsonSignatureEntry> nonValidatedSignatures = new LinkedList<JwsJsonSignatureEntry>(); - for (JwsJsonSignatureEntry sigEntry : signatures) { - if (!validatedSignatures.contains(sigEntry)) { - nonValidatedSignatures.add(sigEntry); - } - } - return nonValidatedSignatures; - } - - public boolean verifySignatureWith(JsonWebKey key) { - return verifySignatureWith(JwsUtils.getSignatureVerifier(key)); - } - public boolean verifySignatureWith(JsonWebKey key, SignatureAlgorithm algo) { - return verifySignatureWith(JwsUtils.getSignatureVerifier(key, algo)); - } - public JwsJsonProducer toProducer() { - JwsJsonProducer p = new JwsJsonProducer(getDecodedJwsPayload()); - p.getSignatureEntries().addAll(signatures); - return p; - } -} http://git-wip-us.apache.org/repos/asf/cxf/blob/532c52a7/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonOutputStream.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonOutputStream.java b/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonOutputStream.java deleted file mode 100644 index 7fe6059..0000000 --- a/rt/rs/security/jose/jose-core/src/main/java/org/apache/cxf/rs/security/jose/jws/JwsJsonOutputStream.java +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cxf.rs.security.jose.jws; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import org.apache.cxf.common.util.Base64UrlUtility; -import org.apache.cxf.common.util.StringUtils; - -public class JwsJsonOutputStream extends FilterOutputStream { - private boolean flushed; - private List<String> protectedHeaders; - private List<JwsSignature> signatures; - private ExecutorService executor; - public JwsJsonOutputStream(OutputStream out, - List<String> protectedHeaders, - List<JwsSignature> signatures) { - super(out); - this.protectedHeaders = protectedHeaders; - this.signatures = signatures; - // This can be further optimized by having a dedicated thread per signature, - // can make a difference if a number of signatures to be created is > 2 - this.executor = Executors.newSingleThreadExecutor(); - } - - @Override - public void write(int value) throws IOException { - byte[] bytes = ByteBuffer.allocate(Integer.SIZE / 8).putInt(value).array(); - write(bytes, 0, bytes.length); - } - - @Override - public void write(final byte b[], final int off, final int len) throws IOException { - //TODO: Review if it is at least theoretically possible that a given b[] region - // can be modified in a subsequent write which might affect the signature calculation - executor.execute(new Runnable() { - public void run() { - for (JwsSignature signature : signatures) { - signature.update(b, off, len); - } - } - }); - out.write(b, off, len); - out.flush(); - } - @Override - public void flush() throws IOException { - if (flushed) { - return; - } - out.write(StringUtils.toBytesUTF8("\",\"signatures\":[")); - shutdownExecutor(); - for (int i = 0; i < signatures.size(); i++) { - if (i > 0) { - out.write(new byte[]{','}); - } - out.write(StringUtils.toBytesUTF8("{\"protected\":\"" - + protectedHeaders.get(i) - + "\",\"signature\":\"")); - byte[] sign = signatures.get(i).sign(); - Base64UrlUtility.encodeAndStream(sign, 0, sign.length, out); - out.write(StringUtils.toBytesUTF8("\"}")); - } - out.write(StringUtils.toBytesUTF8("]}")); - flushed = true; - } - private void shutdownExecutor() { - executor.shutdown(); - while (!executor.isTerminated()) { - try { - executor.awaitTermination(1, TimeUnit.MILLISECONDS); - } catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - } - } -}
