116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.jce.provider;
216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.Permission;
44caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giroimport java.util.Collections;
54caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giroimport java.util.HashMap;
64caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giroimport java.util.HashSet;
74caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giroimport java.util.Map;
84caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giroimport java.util.Set;
916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
1016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.spec.DHParameterSpec;
1116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
1216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
1316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
1416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
1516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.jcajce.provider.config.ProviderConfigurationPermission;
1616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.jce.spec.ECParameterSpec;
1716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
1816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroclass BouncyCastleProviderConfiguration
1916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    implements ProviderConfiguration
2016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{
2116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private static Permission BC_EC_LOCAL_PERMISSION = new ProviderConfigurationPermission(
2216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA);
2316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private static Permission BC_EC_PERMISSION = new ProviderConfigurationPermission(
2416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.EC_IMPLICITLY_CA);
2516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private static Permission BC_DH_LOCAL_PERMISSION = new ProviderConfigurationPermission(
2616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS);
2716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private static Permission BC_DH_PERMISSION = new ProviderConfigurationPermission(
2816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.DH_DEFAULT_PARAMS);
294caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    private static Permission BC_EC_CURVE_PERMISSION = new ProviderConfigurationPermission(
304caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.ACCEPTABLE_EC_CURVES);
314caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    private static Permission BC_ADDITIONAL_EC_CURVE_PERMISSION = new ProviderConfigurationPermission(
324caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.ADDITIONAL_EC_PARAMETERS);
3316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
3416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private ThreadLocal ecThreadSpec = new ThreadLocal();
3516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private ThreadLocal dhThreadSpec = new ThreadLocal();
3616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
3716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private volatile ECParameterSpec ecImplicitCaParams;
3816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private volatile Object dhDefaultParams;
394caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    private volatile Set acceptableNamedCurves = new HashSet();
404caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    private volatile Map additionalECParameters = new HashMap();
4116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
4216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    void setParameter(String parameterName, Object parameter)
4316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
4416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        SecurityManager securityManager = System.getSecurityManager();
4516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
4616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_EC_IMPLICITLY_CA))
4716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
4816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            ECParameterSpec curveSpec;
4916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
5016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (securityManager != null)
5116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
5216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                securityManager.checkPermission(BC_EC_LOCAL_PERMISSION);
5316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
5416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
5516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (parameter instanceof ECParameterSpec || parameter == null)
5616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
5716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                curveSpec = (ECParameterSpec)parameter;
5816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
5916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            else  // assume java.security.spec
6016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
6116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                curveSpec = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter, false);
6216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
6316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
6416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (curveSpec == null)
6516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
6616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                ecThreadSpec.remove();
6716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
6816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            else
6916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
7016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                ecThreadSpec.set(curveSpec);
7116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
7216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
7316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else if (parameterName.equals(ConfigurableProvider.EC_IMPLICITLY_CA))
7416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
7516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (securityManager != null)
7616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
7716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                securityManager.checkPermission(BC_EC_PERMISSION);
7816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
7916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
8016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (parameter instanceof ECParameterSpec || parameter == null)
8116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
8216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                ecImplicitCaParams = (ECParameterSpec)parameter;
8316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
8416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            else  // assume java.security.spec
8516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
8616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                ecImplicitCaParams = EC5Util.convertSpec((java.security.spec.ECParameterSpec)parameter, false);
8716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
8816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
8916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else if (parameterName.equals(ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS))
9016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
9116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            Object dhSpec;
9216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
9316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (securityManager != null)
9416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
9516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                securityManager.checkPermission(BC_DH_LOCAL_PERMISSION);
9616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
9716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
9816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null)
9916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
10016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                dhSpec = parameter;
10116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
10216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            else
10316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
10416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                throw new IllegalArgumentException("not a valid DHParameterSpec");
10516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
10616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
10716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (dhSpec == null)
10816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
10916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                dhThreadSpec.remove();
11016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
11116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            else
11216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
11316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                dhThreadSpec.set(dhSpec);
11416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
11516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
11616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else if (parameterName.equals(ConfigurableProvider.DH_DEFAULT_PARAMS))
11716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
11816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (securityManager != null)
11916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
12016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                securityManager.checkPermission(BC_DH_PERMISSION);
12116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
12216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
12316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (parameter instanceof DHParameterSpec || parameter instanceof DHParameterSpec[] || parameter == null)
12416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
12516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                dhDefaultParams = parameter;
12616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
12716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            else
12816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
12916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                throw new IllegalArgumentException("not a valid DHParameterSpec or DHParameterSpec[]");
13016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
13116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
1324caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        else if (parameterName.equals(ConfigurableProvider.ACCEPTABLE_EC_CURVES))
1334caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        {
1344caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro            if (securityManager != null)
1354caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro            {
1364caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro                securityManager.checkPermission(BC_EC_CURVE_PERMISSION);
1374caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro            }
1384caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro
1394caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro            this.acceptableNamedCurves = (Set)parameter;
1404caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        }
1414caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        else if (parameterName.equals(ConfigurableProvider.ADDITIONAL_EC_PARAMETERS))
1424caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        {
1434caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro            if (securityManager != null)
1444caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro            {
1454caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro                securityManager.checkPermission(BC_ADDITIONAL_EC_CURVE_PERMISSION);
1464caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro            }
1474caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro
1484caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro            this.additionalECParameters = (Map)parameter;
1494caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        }
15016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
15116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
15216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public ECParameterSpec getEcImplicitlyCa()
15316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
15416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ECParameterSpec spec = (ECParameterSpec)ecThreadSpec.get();
15516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
15616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (spec != null)
15716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
15816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return spec;
15916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
16016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
16116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return ecImplicitCaParams;
16216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
16316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
16416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public DHParameterSpec getDHDefaultParameters(int keySize)
16516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
16616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        Object params = dhThreadSpec.get();
16716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (params == null)
16816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
16916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            params = dhDefaultParams;
17016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
17116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
17216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (params instanceof DHParameterSpec)
17316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
17416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            DHParameterSpec spec = (DHParameterSpec)params;
17516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
17616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (spec.getP().bitLength() == keySize)
17716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
17816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                return spec;
17916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
18016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
18116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else if (params instanceof DHParameterSpec[])
18216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
18316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            DHParameterSpec[] specs = (DHParameterSpec[])params;
18416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
18516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            for (int i = 0; i != specs.length; i++)
18616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
18716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                if (specs[i].getP().bitLength() == keySize)
18816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                {
18916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    return specs[i];
19016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                }
19116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
19216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
19316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
19416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return null;
19516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
1964caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro
1974caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    public Set getAcceptableNamedCurves()
1984caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    {
1994caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        return Collections.unmodifiableSet(acceptableNamedCurves);
2004caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    }
2014caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro
2024caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    public Map getAdditionalECParameters()
2034caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    {
2044caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro        return Collections.unmodifiableMap(additionalECParameters);
2054caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro    }
20616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro}
207