/**
* 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<>(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<>(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<>(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<>(Arrays.asList(ES_SHA_256_ALGO,
ES_SHA_384_ALGO,
ES_SHA_512_ALGO));
public static final Set<String> RSA_CEK_SET = new HashSet<>(Arrays.asList(RSA_OAEP_ALGO,
RSA_OAEP_256_ALGO,
RSA1_5_ALGO));
public static final Set<String> AES_GCM_CEK_SET = new HashSet<>(Arrays.asList(A128GCM_ALGO,
A192GCM_ALGO,
A256GCM_ALGO));
public static final Set<String> AES_GCM_KW_SET = new HashSet<>(Arrays.asList(A128GCMKW_ALGO,
A192GCMKW_ALGO,
A256GCMKW_ALGO));
public static final Set<String> AES_KW_SET = new HashSet<>(Arrays.asList(A128KW_ALGO,
A192KW_ALGO,
A256KW_ALGO));
public static final Set<String> ACBC_HS_SET = new HashSet<>(Arrays.asList(A128CBC_HS256_ALGO,
A192CBC_HS384_ALGO,
A256CBC_HS512_ALGO));
public static final Set<String> PBES_HS_SET = new HashSet<>(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<>(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<>();
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<>();
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 isEc(String algo) {
return isEcDsaSign(algo) || isEcdhEsWrap(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 isOctet(String algo) {
return isHmacSign(algo)
|| isAesCbcHmac(algo)
|| isAesGcm(algo)
|| isAesGcmKeyWrap(algo)
|| isAesKeyWrap(algo);
}
public static boolean isHmacSign(String algo) {
return HMAC_SIGN_SET.contains(algo);
}
public static boolean isHmacSign(SignatureAlgorithm algo) {
return isHmacSign(algo.getJwaName());
}
public static boolean isRsaSign(String algo) {
return isRsaShaSign(algo) || isRsaShaPsSign(algo);
}
public static boolean isRsaSign(SignatureAlgorithm algo) {
return isRsaSign(algo.getJwaName());
}
public static boolean isRsaShaSign(String algo) {
return RSA_SHA_SIGN_SET.contains(algo);
}
public static boolean isRsaShaSign(SignatureAlgorithm algo) {
return isRsaShaSign(algo.getJwaName());
}
public static boolean isRsaShaPsSign(String algo) {
return RSA_SHA_PS_SIGN_SET.contains(algo);
}
public static boolean isRsaShaPsSign(SignatureAlgorithm algo) {
return isRsaShaPsSign(algo.getJwaName());
}
public static boolean isEcDsaSign(String algo) {
return EC_SHA_SIGN_SET.contains(algo);
}
public static boolean isEcDsaSign(SignatureAlgorithm algo) {
return isEcDsaSign(algo.getJwaName());
}
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;
}
}