/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed 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 io.undertow.server.protocol.http;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author Stuart Douglas
 */
class ALPNBannedCiphers {

    static class Key {

        private final byte b1, b2;

        Key(int b1, int b2) {
            this.b1 = (byte) b1;
            this.b2 = (byte) b2;
        }
    }
    private static final Map<String, Key> CIPHERS;
    private static final Map<Key, String> REVERSE_CIPHERS;
    private static final Set<String> ALPN_BANNED_CIPHERS;

    static {

        Map<String, Key> ciphers = new HashMap<>();
        ciphers.put("TLS_NULL_WITH_NULL_NULL", new Key(0x00, 0x00));
        ciphers.put("TLS_RSA_WITH_NULL_MD5", new Key(0x00, 0x01));
        ciphers.put("TLS_RSA_WITH_NULL_SHA", new Key(0x00, 0x02));
        ciphers.put("TLS_RSA_EXPORT_WITH_RC4_40_MD5", new Key(0x00, 0x03));
        ciphers.put("TLS_RSA_WITH_RC4_128_MD5", new Key(0x00, 0x04));
        ciphers.put("TLS_RSA_WITH_RC4_128_SHA", new Key(0x00, 0x05));
        ciphers.put("TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", new Key(0x00, 0x06));
        ciphers.put("TLS_RSA_WITH_IDEA_CBC_SHA", new Key(0x00, 0x07));
        ciphers.put("TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", new Key(0x00, 0x08));
        ciphers.put("TLS_RSA_WITH_DES_CBC_SHA", new Key(0x00, 0x09));
        ciphers.put("TLS_RSA_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x0A));
        ciphers.put("TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", new Key(0x00, 0x0B));
        ciphers.put("TLS_DH_DSS_WITH_DES_CBC_SHA", new Key(0x00, 0x0C));
        ciphers.put("TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x0D));
        ciphers.put("TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", new Key(0x00, 0x0E));
        ciphers.put("TLS_DH_RSA_WITH_DES_CBC_SHA", new Key(0x00, 0x0F));
        ciphers.put("TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x10));
        ciphers.put("TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", new Key(0x00, 0x11));
        ciphers.put("TLS_DHE_DSS_WITH_DES_CBC_SHA", new Key(0x00, 0x12));
        ciphers.put("TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x13));
        ciphers.put("TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", new Key(0x00, 0x14));
        ciphers.put("TLS_DHE_RSA_WITH_DES_CBC_SHA", new Key(0x00, 0x15));
        ciphers.put("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x16));
        ciphers.put("TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", new Key(0x00, 0x17));
        ciphers.put("TLS_DH_anon_WITH_RC4_128_MD5", new Key(0x00, 0x18));
        ciphers.put("TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", new Key(0x00, 0x19));
        ciphers.put("TLS_DH_anon_WITH_DES_CBC_SHA", new Key(0x00, 0x1A));
        ciphers.put("TLS_DH_anon_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x1B));
        ciphers.put("TLS_KRB5_WITH_DES_CBC_SHA", new Key(0x00, 0x1E));
        ciphers.put("TLS_KRB5_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x1F));
        ciphers.put("TLS_KRB5_WITH_RC4_128_SHA", new Key(0x00, 0x20));
        ciphers.put("TLS_KRB5_WITH_IDEA_CBC_SHA", new Key(0x00, 0x21));
        ciphers.put("TLS_KRB5_WITH_DES_CBC_MD5", new Key(0x00, 0x22));
        ciphers.put("TLS_KRB5_WITH_3DES_EDE_CBC_MD5", new Key(0x00, 0x23));
        ciphers.put("TLS_KRB5_WITH_RC4_128_MD5", new Key(0x00, 0x24));
        ciphers.put("TLS_KRB5_WITH_IDEA_CBC_MD5", new Key(0x00, 0x25));
        ciphers.put("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", new Key(0x00, 0x26));
        ciphers.put("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", new Key(0x00, 0x27));
        ciphers.put("TLS_KRB5_EXPORT_WITH_RC4_40_SHA", new Key(0x00, 0x28));
        ciphers.put("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", new Key(0x00, 0x29));
        ciphers.put("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", new Key(0x00, 0x2A));
        ciphers.put("TLS_KRB5_EXPORT_WITH_RC4_40_MD5", new Key(0x00, 0x2B));
        ciphers.put("TLS_PSK_WITH_NULL_SHA", new Key(0x00, 0x2C));
        ciphers.put("TLS_DHE_PSK_WITH_NULL_SHA", new Key(0x00, 0x2D));
        ciphers.put("TLS_RSA_PSK_WITH_NULL_SHA", new Key(0x00, 0x2E));
        ciphers.put("TLS_RSA_WITH_AES_128_CBC_SHA", new Key(0x00, 0x2F));
        ciphers.put("TLS_DH_DSS_WITH_AES_128_CBC_SHA", new Key(0x00, 0x30));
        ciphers.put("TLS_DH_RSA_WITH_AES_128_CBC_SHA", new Key(0x00, 0x31));
        ciphers.put("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", new Key(0x00, 0x32));
        ciphers.put("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", new Key(0x00, 0x33));
        ciphers.put("TLS_DH_anon_WITH_AES_128_CBC_SHA", new Key(0x00, 0x34));
        ciphers.put("TLS_RSA_WITH_AES_256_CBC_SHA", new Key(0x00, 0x35));
        ciphers.put("TLS_DH_DSS_WITH_AES_256_CBC_SHA", new Key(0x00, 0x36));
        ciphers.put("TLS_DH_RSA_WITH_AES_256_CBC_SHA", new Key(0x00, 0x37));
        ciphers.put("TLS_DHE_DSS_WITH_AES_256_CBC_SHA", new Key(0x00, 0x38));
        ciphers.put("TLS_DHE_RSA_WITH_AES_256_CBC_SHA", new Key(0x00, 0x39));
        ciphers.put("TLS_DH_anon_WITH_AES_256_CBC_SHA", new Key(0x00, 0x3A));
        ciphers.put("TLS_RSA_WITH_NULL_SHA256", new Key(0x00, 0x3B));
        ciphers.put("TLS_RSA_WITH_AES_128_CBC_SHA256", new Key(0x00, 0x3C));
        ciphers.put("TLS_RSA_WITH_AES_256_CBC_SHA256", new Key(0x00, 0x3D));
        ciphers.put("TLS_DH_DSS_WITH_AES_128_CBC_SHA256", new Key(0x00, 0x3E));
        ciphers.put("TLS_DH_RSA_WITH_AES_128_CBC_SHA256", new Key(0x00, 0x3F));
        ciphers.put("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", new Key(0x00, 0x40));
        ciphers.put("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", new Key(0x00, 0x41));
        ciphers.put("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", new Key(0x00, 0x42));
        ciphers.put("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", new Key(0x00, 0x43));
        ciphers.put("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", new Key(0x00, 0x44));
        ciphers.put("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", new Key(0x00, 0x45));
        ciphers.put("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", new Key(0x00, 0x46));
        ciphers.put("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", new Key(0x00, 0x67));
        ciphers.put("TLS_DH_DSS_WITH_AES_256_CBC_SHA256", new Key(0x00, 0x68));
        ciphers.put("TLS_DH_RSA_WITH_AES_256_CBC_SHA256", new Key(0x00, 0x69));
        ciphers.put("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", new Key(0x00, 0x6A));
        ciphers.put("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", new Key(0x00, 0x6B));
        ciphers.put("TLS_DH_anon_WITH_AES_128_CBC_SHA256", new Key(0x00, 0x6C));
        ciphers.put("TLS_DH_anon_WITH_AES_256_CBC_SHA256", new Key(0x00, 0x6D));
        ciphers.put("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", new Key(0x00, 0x84));
        ciphers.put("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", new Key(0x00, 0x85));
        ciphers.put("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", new Key(0x00, 0x86));
        ciphers.put("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", new Key(0x00, 0x87));
        ciphers.put("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", new Key(0x00, 0x88));
        ciphers.put("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", new Key(0x00, 0x89));
        ciphers.put("TLS_PSK_WITH_RC4_128_SHA", new Key(0x00, 0x8A));
        ciphers.put("TLS_PSK_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x8B));
        ciphers.put("TLS_PSK_WITH_AES_128_CBC_SHA", new Key(0x00, 0x8C));
        ciphers.put("TLS_PSK_WITH_AES_256_CBC_SHA", new Key(0x00, 0x8D));
        ciphers.put("TLS_DHE_PSK_WITH_RC4_128_SHA", new Key(0x00, 0x8E));
        ciphers.put("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x8F));
        ciphers.put("TLS_DHE_PSK_WITH_AES_128_CBC_SHA", new Key(0x00, 0x90));
        ciphers.put("TLS_DHE_PSK_WITH_AES_256_CBC_SHA", new Key(0x00, 0x91));
        ciphers.put("TLS_RSA_PSK_WITH_RC4_128_SHA", new Key(0x00, 0x92));
        ciphers.put("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", new Key(0x00, 0x93));
        ciphers.put("TLS_RSA_PSK_WITH_AES_128_CBC_SHA", new Key(0x00, 0x94));
        ciphers.put("TLS_RSA_PSK_WITH_AES_256_CBC_SHA", new Key(0x00, 0x95));
        ciphers.put("TLS_RSA_WITH_SEED_CBC_SHA", new Key(0x00, 0x96));
        ciphers.put("TLS_DH_DSS_WITH_SEED_CBC_SHA", new Key(0x00, 0x97));
        ciphers.put("TLS_DH_RSA_WITH_SEED_CBC_SHA", new Key(0x00, 0x98));
        ciphers.put("TLS_DHE_DSS_WITH_SEED_CBC_SHA", new Key(0x00, 0x99));
        ciphers.put("TLS_DHE_RSA_WITH_SEED_CBC_SHA", new Key(0x00, 0x9A));
        ciphers.put("TLS_DH_anon_WITH_SEED_CBC_SHA", new Key(0x00, 0x9B));
        ciphers.put("TLS_RSA_WITH_AES_128_GCM_SHA256", new Key(0x00, 0x9C));
        ciphers.put("TLS_RSA_WITH_AES_256_GCM_SHA384", new Key(0x00, 0x9D));
        ciphers.put("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", new Key(0x00, 0x9E));
        ciphers.put("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", new Key(0x00, 0x9F));
        ciphers.put("TLS_DH_RSA_WITH_AES_128_GCM_SHA256", new Key(0x00, 0xA0));
        ciphers.put("TLS_DH_RSA_WITH_AES_256_GCM_SHA384", new Key(0x00, 0xA1));
        ciphers.put("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", new Key(0x00, 0xA2));
        ciphers.put("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", new Key(0x00, 0xA3));
        ciphers.put("TLS_DH_DSS_WITH_AES_128_GCM_SHA256", new Key(0x00, 0xA4));
        ciphers.put("TLS_DH_DSS_WITH_AES_256_GCM_SHA384", new Key(0x00, 0xA5));
        ciphers.put("TLS_DH_anon_WITH_AES_128_GCM_SHA256", new Key(0x00, 0xA6));
        ciphers.put("TLS_DH_anon_WITH_AES_256_GCM_SHA384", new Key(0x00, 0xA7));
        ciphers.put("TLS_PSK_WITH_AES_128_GCM_SHA256", new Key(0x00, 0xA8));
        ciphers.put("TLS_PSK_WITH_AES_256_GCM_SHA384", new Key(0x00, 0xA9));
        ciphers.put("TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", new Key(0x00, 0xAA));
        ciphers.put("TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", new Key(0x00, 0xAB));
        ciphers.put("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", new Key(0x00, 0xAC));
        ciphers.put("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", new Key(0x00, 0xAD));
        ciphers.put("TLS_PSK_WITH_AES_128_CBC_SHA256", new Key(0x00, 0xAE));
        ciphers.put("TLS_PSK_WITH_AES_256_CBC_SHA384", new Key(0x00, 0xAF));
        ciphers.put("TLS_PSK_WITH_NULL_SHA256", new Key(0x00, 0xB0));
        ciphers.put("TLS_PSK_WITH_NULL_SHA384", new Key(0x00, 0xB1));
        ciphers.put("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", new Key(0x00, 0xB2));
        ciphers.put("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", new Key(0x00, 0xB3));
        ciphers.put("TLS_DHE_PSK_WITH_NULL_SHA256", new Key(0x00, 0xB4));
        ciphers.put("TLS_DHE_PSK_WITH_NULL_SHA384", new Key(0x00, 0xB5));
        ciphers.put("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", new Key(0x00, 0xB6));
        ciphers.put("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", new Key(0x00, 0xB7));
        ciphers.put("TLS_RSA_PSK_WITH_NULL_SHA256", new Key(0x00, 0xB8));
        ciphers.put("TLS_RSA_PSK_WITH_NULL_SHA384", new Key(0x00, 0xB9));
        ciphers.put("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", new Key(0x00, 0xBA));
        ciphers.put("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", new Key(0x00, 0xBB));
        ciphers.put("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", new Key(0x00, 0xBC));
        ciphers.put("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", new Key(0x00, 0xBD));
        ciphers.put("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", new Key(0x00, 0xBE));
        ciphers.put("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", new Key(0x00, 0xBF));
        ciphers.put("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", new Key(0x00, 0xC0));
        ciphers.put("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", new Key(0x00, 0xC1));
        ciphers.put("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", new Key(0x00, 0xC2));
        ciphers.put("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", new Key(0x00, 0xC3));
        ciphers.put("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", new Key(0x00, 0xC4));
        ciphers.put("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", new Key(0x00, 0xC5));
        ciphers.put("TLS_EMPTY_RENEGOTIATION_INFO_SCSV", new Key(0x00, 0xFF));
        ciphers.put("TLS_FALLBACK_SCSV", new Key(0x56, 0x00));
        ciphers.put("TLS_ECDH_ECDSA_WITH_NULL_SHA", new Key(0xC0, 0x01));
        ciphers.put("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", new Key(0xC0, 0x02));
        ciphers.put("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", new Key(0xC0, 0x03));
        ciphers.put("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", new Key(0xC0, 0x04));
        ciphers.put("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", new Key(0xC0, 0x05));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_NULL_SHA", new Key(0xC0, 0x06));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", new Key(0xC0, 0x07));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", new Key(0xC0, 0x08));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", new Key(0xC0, 0x09));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", new Key(0xC0, 0x0A));
        ciphers.put("TLS_ECDH_RSA_WITH_NULL_SHA", new Key(0xC0, 0x0B));
        ciphers.put("TLS_ECDH_RSA_WITH_RC4_128_SHA", new Key(0xC0, 0x0C));
        ciphers.put("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", new Key(0xC0, 0x0D));
        ciphers.put("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", new Key(0xC0, 0x0E));
        ciphers.put("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", new Key(0xC0, 0x0F));
        ciphers.put("TLS_ECDHE_RSA_WITH_NULL_SHA", new Key(0xC0, 0x10));
        ciphers.put("TLS_ECDHE_RSA_WITH_RC4_128_SHA", new Key(0xC0, 0x11));
        ciphers.put("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", new Key(0xC0, 0x12));
        ciphers.put("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", new Key(0xC0, 0x13));
        ciphers.put("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", new Key(0xC0, 0x14));
        ciphers.put("TLS_ECDH_anon_WITH_NULL_SHA", new Key(0xC0, 0x15));
        ciphers.put("TLS_ECDH_anon_WITH_RC4_128_SHA", new Key(0xC0, 0x16));
        ciphers.put("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", new Key(0xC0, 0x17));
        ciphers.put("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", new Key(0xC0, 0x18));
        ciphers.put("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", new Key(0xC0, 0x19));
        ciphers.put("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", new Key(0xC0, 0x1A));
        ciphers.put("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", new Key(0xC0, 0x1B));
        ciphers.put("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", new Key(0xC0, 0x1C));
        ciphers.put("TLS_SRP_SHA_WITH_AES_128_CBC_SHA", new Key(0xC0, 0x1D));
        ciphers.put("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", new Key(0xC0, 0x1E));
        ciphers.put("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", new Key(0xC0, 0x1F));
        ciphers.put("TLS_SRP_SHA_WITH_AES_256_CBC_SHA", new Key(0xC0, 0x20));
        ciphers.put("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", new Key(0xC0, 0x21));
        ciphers.put("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", new Key(0xC0, 0x22));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", new Key(0xC0, 0x23));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", new Key(0xC0, 0x24));
        ciphers.put("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", new Key(0xC0, 0x25));
        ciphers.put("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", new Key(0xC0, 0x26));
        ciphers.put("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", new Key(0xC0, 0x27));
        ciphers.put("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", new Key(0xC0, 0x28));
        ciphers.put("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", new Key(0xC0, 0x29));
        ciphers.put("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", new Key(0xC0, 0x2A));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", new Key(0xC0, 0x2B));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", new Key(0xC0, 0x2C));
        ciphers.put("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", new Key(0xC0, 0x2D));
        ciphers.put("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", new Key(0xC0, 0x2E));
        ciphers.put("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", new Key(0xC0, 0x2F));
        ciphers.put("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", new Key(0xC0, 0x30));
        ciphers.put("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", new Key(0xC0, 0x31));
        ciphers.put("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", new Key(0xC0, 0x32));
        ciphers.put("TLS_ECDHE_PSK_WITH_RC4_128_SHA", new Key(0xC0, 0x33));
        ciphers.put("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", new Key(0xC0, 0x34));
        ciphers.put("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", new Key(0xC0, 0x35));
        ciphers.put("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", new Key(0xC0, 0x36));
        ciphers.put("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", new Key(0xC0, 0x37));
        ciphers.put("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", new Key(0xC0, 0x38));
        ciphers.put("TLS_ECDHE_PSK_WITH_NULL_SHA", new Key(0xC0, 0x39));
        ciphers.put("TLS_ECDHE_PSK_WITH_NULL_SHA256", new Key(0xC0, 0x3A));
        ciphers.put("TLS_ECDHE_PSK_WITH_NULL_SHA384", new Key(0xC0, 0x3B));
        ciphers.put("TLS_RSA_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x3C));
        ciphers.put("TLS_RSA_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x3D));
        ciphers.put("TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x3E));
        ciphers.put("TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x3F));
        ciphers.put("TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x40));
        ciphers.put("TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x41));
        ciphers.put("TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x42));
        ciphers.put("TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x43));
        ciphers.put("TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x44));
        ciphers.put("TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x45));
        ciphers.put("TLS_DH_anon_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x46));
        ciphers.put("TLS_DH_anon_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x47));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x48));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x49));
        ciphers.put("TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x4A));
        ciphers.put("TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x4B));
        ciphers.put("TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x4C));
        ciphers.put("TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x4D));
        ciphers.put("TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x4E));
        ciphers.put("TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x4F));
        ciphers.put("TLS_RSA_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x50));
        ciphers.put("TLS_RSA_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x51));
        ciphers.put("TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x52));
        ciphers.put("TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x53));
        ciphers.put("TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x54));
        ciphers.put("TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x55));
        ciphers.put("TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x56));
        ciphers.put("TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x57));
        ciphers.put("TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x58));
        ciphers.put("TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x59));
        ciphers.put("TLS_DH_anon_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x5A));
        ciphers.put("TLS_DH_anon_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x5B));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x5C));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x5D));
        ciphers.put("TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x5E));
        ciphers.put("TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x5F));
        ciphers.put("TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x60));
        ciphers.put("TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x61));
        ciphers.put("TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x62));
        ciphers.put("TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x63));
        ciphers.put("TLS_PSK_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x64));
        ciphers.put("TLS_PSK_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x65));
        ciphers.put("TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x66));
        ciphers.put("TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x67));
        ciphers.put("TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x68));
        ciphers.put("TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x69));
        ciphers.put("TLS_PSK_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x6A));
        ciphers.put("TLS_PSK_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x6B));
        ciphers.put("TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x6C));
        ciphers.put("TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x6D));
        ciphers.put("TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", new Key(0xC0, 0x6E));
        ciphers.put("TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", new Key(0xC0, 0x6F));
        ciphers.put("TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", new Key(0xC0, 0x70));
        ciphers.put("TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", new Key(0xC0, 0x71));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", new Key(0xC0, 0x72));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", new Key(0xC0, 0x73));
        ciphers.put("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", new Key(0xC0, 0x74));
        ciphers.put("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", new Key(0xC0, 0x75));
        ciphers.put("TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", new Key(0xC0, 0x76));
        ciphers.put("TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", new Key(0xC0, 0x77));
        ciphers.put("TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", new Key(0xC0, 0x78));
        ciphers.put("TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", new Key(0xC0, 0x79));
        ciphers.put("TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x7A));
        ciphers.put("TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x7B));
        ciphers.put("TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x7C));
        ciphers.put("TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x7D));
        ciphers.put("TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x7E));
        ciphers.put("TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x7F));
        ciphers.put("TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x80));
        ciphers.put("TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x81));
        ciphers.put("TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x82));
        ciphers.put("TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x83));
        ciphers.put("TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x84));
        ciphers.put("TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x85));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x86));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x87));
        ciphers.put("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x88));
        ciphers.put("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x89));
        ciphers.put("TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x8A));
        ciphers.put("TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x8B));
        ciphers.put("TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x8C));
        ciphers.put("TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x8D));
        ciphers.put("TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x8E));
        ciphers.put("TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x8F));
        ciphers.put("TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x90));
        ciphers.put("TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x91));
        ciphers.put("TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", new Key(0xC0, 0x92));
        ciphers.put("TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", new Key(0xC0, 0x93));
        ciphers.put("TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", new Key(0xC0, 0x94));
        ciphers.put("TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", new Key(0xC0, 0x95));
        ciphers.put("TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", new Key(0xC0, 0x96));
        ciphers.put("TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", new Key(0xC0, 0x97));
        ciphers.put("TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", new Key(0xC0, 0x98));
        ciphers.put("TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", new Key(0xC0, 0x99));
        ciphers.put("TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", new Key(0xC0, 0x9A));
        ciphers.put("TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", new Key(0xC0, 0x9B));
        ciphers.put("TLS_RSA_WITH_AES_128_CCM", new Key(0xC0, 0x9C));
        ciphers.put("TLS_RSA_WITH_AES_256_CCM", new Key(0xC0, 0x9D));
        ciphers.put("TLS_DHE_RSA_WITH_AES_128_CCM", new Key(0xC0, 0x9E));
        ciphers.put("TLS_DHE_RSA_WITH_AES_256_CCM", new Key(0xC0, 0x9F));
        ciphers.put("TLS_RSA_WITH_AES_128_CCM_8", new Key(0xC0, 0xA0));
        ciphers.put("TLS_RSA_WITH_AES_256_CCM_8", new Key(0xC0, 0xA1));
        ciphers.put("TLS_DHE_RSA_WITH_AES_128_CCM_8", new Key(0xC0, 0xA2));
        ciphers.put("TLS_DHE_RSA_WITH_AES_256_CCM_8", new Key(0xC0, 0xA3));
        ciphers.put("TLS_PSK_WITH_AES_128_CCM", new Key(0xC0, 0xA4));
        ciphers.put("TLS_PSK_WITH_AES_256_CCM", new Key(0xC0, 0xA5));
        ciphers.put("TLS_DHE_PSK_WITH_AES_128_CCM", new Key(0xC0, 0xA6));
        ciphers.put("TLS_DHE_PSK_WITH_AES_256_CCM", new Key(0xC0, 0xA7));
        ciphers.put("TLS_PSK_WITH_AES_128_CCM_8", new Key(0xC0, 0xA8));
        ciphers.put("TLS_PSK_WITH_AES_256_CCM_8", new Key(0xC0, 0xA9));
        ciphers.put("TLS_PSK_DHE_WITH_AES_128_CCM_8", new Key(0xC0, 0xAA));
        ciphers.put("TLS_PSK_DHE_WITH_AES_256_CCM_8", new Key(0xC0, 0xAB));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_128_CCM", new Key(0xC0, 0xAC));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_256_CCM", new Key(0xC0, 0xAD));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", new Key(0xC0, 0xAE));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", new Key(0xC0, 0xAF));
        ciphers.put("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", new Key(0xCC, 0xA8));
        ciphers.put("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", new Key(0xCC, 0xA9));
        ciphers.put("TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", new Key(0xCC, 0xAA));
        ciphers.put("TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", new Key(0xCC, 0xAB));
        ciphers.put("TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", new Key(0xCC, 0xAC));
        ciphers.put("TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", new Key(0xCC, 0xAD));
        ciphers.put("TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", new Key(0xCC, 0xAE));
        CIPHERS = Collections.unmodifiableMap(ciphers);
        Map<Key, String> reverse = new HashMap<>();
        for(Map.Entry<String, Key> e : ciphers.entrySet()) {
            reverse.put(e.getValue(), e.getKey());
        }
        REVERSE_CIPHERS = Collections.unmodifiableMap(reverse);


        Set<String> banned = new HashSet<>() ;
        banned.add("TLS_NULL_WITH_NULL_NULL");
        banned.add("TLS_RSA_WITH_NULL_MD5");
        banned.add("TLS_RSA_WITH_NULL_SHA");
        banned.add("TLS_RSA_EXPORT_WITH_RC4_40_MD5");
        banned.add("TLS_RSA_WITH_RC4_128_MD5");
        banned.add("TLS_RSA_WITH_RC4_128_SHA");
        banned.add("TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5");
        banned.add("TLS_RSA_WITH_IDEA_CBC_SHA");
        banned.add("TLS_RSA_EXPORT_WITH_DES40_CBC_SHA");
        banned.add("TLS_RSA_WITH_DES_CBC_SHA");
        banned.add("TLS_RSA_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA");
        banned.add("TLS_DH_DSS_WITH_DES_CBC_SHA");
        banned.add("TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA");
        banned.add("TLS_DH_RSA_WITH_DES_CBC_SHA");
        banned.add("TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
        banned.add("TLS_DHE_DSS_WITH_DES_CBC_SHA");
        banned.add("TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
        banned.add("TLS_DHE_RSA_WITH_DES_CBC_SHA");
        banned.add("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_DH_anon_EXPORT_WITH_RC4_40_MD5");
        banned.add("TLS_DH_anon_WITH_RC4_128_MD5");
        banned.add("TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA");
        banned.add("TLS_DH_anon_WITH_DES_CBC_SHA");
        banned.add("TLS_DH_anon_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_KRB5_WITH_DES_CBC_SHA");
        banned.add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_KRB5_WITH_RC4_128_SHA");
        banned.add("TLS_KRB5_WITH_IDEA_CBC_SHA");
        banned.add("TLS_KRB5_WITH_DES_CBC_MD5");
        banned.add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5");
        banned.add("TLS_KRB5_WITH_RC4_128_MD5");
        banned.add("TLS_KRB5_WITH_IDEA_CBC_MD5");
        banned.add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA");
        banned.add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA");
        banned.add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA");
        banned.add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5");
        banned.add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5");
        banned.add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5");
        banned.add("TLS_PSK_WITH_NULL_SHA");
        banned.add("TLS_DHE_PSK_WITH_NULL_SHA");
        banned.add("TLS_RSA_PSK_WITH_NULL_SHA");
        banned.add("TLS_RSA_WITH_AES_128_CBC_SHA");
        banned.add("TLS_DH_DSS_WITH_AES_128_CBC_SHA");
        banned.add("TLS_DH_RSA_WITH_AES_128_CBC_SHA");
        banned.add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA");
        banned.add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
        banned.add("TLS_DH_anon_WITH_AES_128_CBC_SHA");
        banned.add("TLS_RSA_WITH_AES_256_CBC_SHA");
        banned.add("TLS_DH_DSS_WITH_AES_256_CBC_SHA");
        banned.add("TLS_DH_RSA_WITH_AES_256_CBC_SHA");
        banned.add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA");
        banned.add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
        banned.add("TLS_DH_anon_WITH_AES_256_CBC_SHA");
        banned.add("TLS_RSA_WITH_NULL_SHA256");
        banned.add("TLS_RSA_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_RSA_WITH_AES_256_CBC_SHA256");
        banned.add("TLS_DH_DSS_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_DH_RSA_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA");
        banned.add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA");
        banned.add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA");
        banned.add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA");
        banned.add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA");
        banned.add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA");
        banned.add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_DH_DSS_WITH_AES_256_CBC_SHA256");
        banned.add("TLS_DH_RSA_WITH_AES_256_CBC_SHA256");
        banned.add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256");
        banned.add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256");
        banned.add("TLS_DH_anon_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_DH_anon_WITH_AES_256_CBC_SHA256");
        banned.add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA");
        banned.add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA");
        banned.add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA");
        banned.add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA");
        banned.add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA");
        banned.add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA");
        banned.add("TLS_PSK_WITH_RC4_128_SHA");
        banned.add("TLS_PSK_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_PSK_WITH_AES_128_CBC_SHA");
        banned.add("TLS_PSK_WITH_AES_256_CBC_SHA");
        banned.add("TLS_DHE_PSK_WITH_RC4_128_SHA");
        banned.add("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA");
        banned.add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA");
        banned.add("TLS_RSA_PSK_WITH_RC4_128_SHA");
        banned.add("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA");
        banned.add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA");
        banned.add("TLS_RSA_WITH_SEED_CBC_SHA");
        banned.add("TLS_DH_DSS_WITH_SEED_CBC_SHA");
        banned.add("TLS_DH_RSA_WITH_SEED_CBC_SHA");
        banned.add("TLS_DHE_DSS_WITH_SEED_CBC_SHA");
        banned.add("TLS_DHE_RSA_WITH_SEED_CBC_SHA");
        banned.add("TLS_DH_anon_WITH_SEED_CBC_SHA");
        banned.add("TLS_RSA_WITH_AES_128_GCM_SHA256");
        banned.add("TLS_RSA_WITH_AES_256_GCM_SHA384");
        banned.add("TLS_DH_RSA_WITH_AES_128_GCM_SHA256");
        banned.add("TLS_DH_RSA_WITH_AES_256_GCM_SHA384");
        banned.add("TLS_DH_DSS_WITH_AES_128_GCM_SHA256");
        banned.add("TLS_DH_DSS_WITH_AES_256_GCM_SHA384");
        banned.add("TLS_DH_anon_WITH_AES_128_GCM_SHA256");
        banned.add("TLS_DH_anon_WITH_AES_256_GCM_SHA384");
        banned.add("TLS_PSK_WITH_AES_128_GCM_SHA256");
        banned.add("TLS_PSK_WITH_AES_256_GCM_SHA384");
        banned.add("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256");
        banned.add("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384");
        banned.add("TLS_PSK_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_PSK_WITH_AES_256_CBC_SHA384");
        banned.add("TLS_PSK_WITH_NULL_SHA256");
        banned.add("TLS_PSK_WITH_NULL_SHA384");
        banned.add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384");
        banned.add("TLS_DHE_PSK_WITH_NULL_SHA256");
        banned.add("TLS_DHE_PSK_WITH_NULL_SHA384");
        banned.add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384");
        banned.add("TLS_RSA_PSK_WITH_NULL_SHA256");
        banned.add("TLS_RSA_PSK_WITH_NULL_SHA384");
        banned.add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256");
        banned.add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256");
        banned.add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256");
        banned.add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256");
        banned.add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256");
        banned.add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256");
        banned.add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV");
        banned.add("TLS_ECDH_ECDSA_WITH_NULL_SHA");
        banned.add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA");
        banned.add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA");
        banned.add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
        banned.add("TLS_ECDHE_ECDSA_WITH_NULL_SHA");
        banned.add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA");
        banned.add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
        banned.add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
        banned.add("TLS_ECDH_RSA_WITH_NULL_SHA");
        banned.add("TLS_ECDH_RSA_WITH_RC4_128_SHA");
        banned.add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA");
        banned.add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA");
        banned.add("TLS_ECDHE_RSA_WITH_NULL_SHA");
        banned.add("TLS_ECDHE_RSA_WITH_RC4_128_SHA");
        banned.add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
        banned.add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
        banned.add("TLS_ECDH_anon_WITH_NULL_SHA");
        banned.add("TLS_ECDH_anon_WITH_RC4_128_SHA");
        banned.add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA");
        banned.add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA");
        banned.add("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_SRP_SHA_WITH_AES_128_CBC_SHA");
        banned.add("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA");
        banned.add("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA");
        banned.add("TLS_SRP_SHA_WITH_AES_256_CBC_SHA");
        banned.add("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA");
        banned.add("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA");
        banned.add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
        banned.add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384");
        banned.add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
        banned.add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384");
        banned.add("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256");
        banned.add("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384");
        banned.add("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256");
        banned.add("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384");
        banned.add("TLS_ECDHE_PSK_WITH_RC4_128_SHA");
        banned.add("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA");
        banned.add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA");
        banned.add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA");
        banned.add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
        banned.add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384");
        banned.add("TLS_ECDHE_PSK_WITH_NULL_SHA");
        banned.add("TLS_ECDHE_PSK_WITH_NULL_SHA256");
        banned.add("TLS_ECDHE_PSK_WITH_NULL_SHA384");
        banned.add("TLS_RSA_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_RSA_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_DH_anon_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_DH_anon_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_RSA_WITH_ARIA_128_GCM_SHA256");
        banned.add("TLS_RSA_WITH_ARIA_256_GCM_SHA384");
        banned.add("TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256");
        banned.add("TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384");
        banned.add("TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256");
        banned.add("TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384");
        banned.add("TLS_DH_anon_WITH_ARIA_128_GCM_SHA256");
        banned.add("TLS_DH_anon_WITH_ARIA_256_GCM_SHA384");
        banned.add("TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256");
        banned.add("TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384");
        banned.add("TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256");
        banned.add("TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384");
        banned.add("TLS_PSK_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_PSK_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_PSK_WITH_ARIA_128_GCM_SHA256");
        banned.add("TLS_PSK_WITH_ARIA_256_GCM_SHA384");
        banned.add("TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256");
        banned.add("TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384");
        banned.add("TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256");
        banned.add("TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384");
        banned.add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384");
        banned.add("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384");
        banned.add("TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384");
        banned.add("TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384");
        banned.add("TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256");
        banned.add("TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384");
        banned.add("TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256");
        banned.add("TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384");
        banned.add("TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256");
        banned.add("TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384");
        banned.add("TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256");
        banned.add("TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384");
        banned.add("TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256");
        banned.add("TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384");
        banned.add("TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256");
        banned.add("TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384");
        banned.add("TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256");
        banned.add("TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384");
        banned.add("TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256");
        banned.add("TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384");
        banned.add("TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384");
        banned.add("TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384");
        banned.add("TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384");
        banned.add("TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256");
        banned.add("TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384");
        banned.add("TLS_RSA_WITH_AES_128_CCM");
        banned.add("TLS_RSA_WITH_AES_256_CCM");
        banned.add("TLS_RSA_WITH_AES_128_CCM_8");
        banned.add("TLS_RSA_WITH_AES_256_CCM_8");
        banned.add("TLS_PSK_WITH_AES_128_CCM");
        banned.add("TLS_PSK_WITH_AES_256_CCM");
        banned.add("TLS_PSK_WITH_AES_128_CCM_8");
        banned.add("TLS_PSK_WITH_AES_256_CCM_8");
        ALPN_BANNED_CIPHERS = Collections.unmodifiableSet(banned);
    }

    static boolean isAllowed(byte b1, byte b2) {
        String cipher = REVERSE_CIPHERS.get(new Key(b1, b2));
        if(cipher == null) {
            //new cipher, should be allowed
            return true;
        }
        return !ALPN_BANNED_CIPHERS.contains(cipher);
    }

    static boolean isAllowed(String cipher) {
        return !ALPN_BANNED_CIPHERS.contains(cipher);
    }
}
