1package org.bouncycastle.jce;
2
3import org.bouncycastle.util.Strings;
4
5import java.security.BasicPermission;
6import java.security.Permission;
7import java.util.StringTokenizer;
8
9/**
10 * A permission class to define what can be done with the ConfigurableProvider interface.
11 * <p>
12 * Available permissions are "threadLocalEcImplicitlyCa" and "ecImplicitlyCa" which allow the setting
13 * of the thread local and global ecImplicitlyCa parameters respectively.
14 * </p>
15 * <p>
16 * Examples:
17 * <ul>
18 * <li>ProviderConfigurationPermission("BC"); // enable all permissions</li>
19 * <li>ProviderConfigurationPermission("BC", "threadLocalEcImplicitlyCa"); // enable thread local only</li>
20 * <li>ProviderConfigurationPermission("BC", "ecImplicitlyCa"); // enable global setting only</li>
21 * <li>ProviderConfigurationPermission("BC", "threadLocalEcImplicitlyCa, ecImplicitlyCa"); // enable both explicitly</li>
22 * </ul>
23 * <p>
24 * Note: permission checks are only enforced if a security manager is present.
25 * </p>
26 */
27public class ProviderConfigurationPermission
28    extends BasicPermission
29{
30    private static final int  THREAD_LOCAL_EC_IMPLICITLY_CA = 0x01;
31
32    private static final int  EC_IMPLICITLY_CA = 0x02;
33    private static final int  ALL = THREAD_LOCAL_EC_IMPLICITLY_CA | EC_IMPLICITLY_CA;
34
35    private static final String THREAD_LOCAL_EC_IMPLICITLY_CA_STR = "threadlocalecimplicitlyca";
36    private static final String EC_IMPLICITLY_CA_STR = "ecimplicitlyca";
37    private static final String ALL_STR = "all";
38
39    private final String actions;
40    private final int permissionMask;
41
42    public ProviderConfigurationPermission(String name)
43    {
44        super(name);
45        this.actions = "all";
46        this.permissionMask = ALL;
47    }
48
49    public ProviderConfigurationPermission(String name, String actions)
50    {
51        super(name, actions);
52        this.actions = actions;
53        this.permissionMask = calculateMask(actions);
54    }
55
56    private int calculateMask(
57        String actions)
58    {
59        StringTokenizer tok = new StringTokenizer(Strings.toLowerCase(actions), " ,");
60        int             mask = 0;
61
62        while (tok.hasMoreTokens())
63        {
64            String s = tok.nextToken();
65
66            if (s.equals(THREAD_LOCAL_EC_IMPLICITLY_CA_STR))
67            {
68                mask |= THREAD_LOCAL_EC_IMPLICITLY_CA;
69            }
70            else if (s.equals(EC_IMPLICITLY_CA_STR))
71            {
72                mask |= EC_IMPLICITLY_CA;
73            }
74            else if (s.equals(ALL_STR))
75            {
76                mask |= ALL;
77            }
78        }
79
80        if (mask == 0)
81        {
82            throw new IllegalArgumentException("unknown permissions passed to mask");
83        }
84
85        return mask;
86    }
87
88    public String getActions()
89    {
90        return actions;
91    }
92
93    public boolean implies(
94        Permission permission)
95    {
96        if (!(permission instanceof ProviderConfigurationPermission))
97        {
98            return false;
99        }
100
101        if (!this.getName().equals(permission.getName()))
102        {
103            return false;
104        }
105
106        ProviderConfigurationPermission other = (ProviderConfigurationPermission)permission;
107
108        return (this.permissionMask & other.permissionMask) == other.permissionMask;
109    }
110
111    public boolean equals(
112        Object obj)
113    {
114        if (obj == this)
115        {
116            return true;
117        }
118
119        if (obj instanceof ProviderConfigurationPermission)
120        {
121            ProviderConfigurationPermission other = (ProviderConfigurationPermission)obj;
122
123            return this.permissionMask == other.permissionMask && this.getName().equals(other.getName());
124        }
125
126        return false;
127    }
128
129    public int hashCode()
130    {
131        return this.getName().hashCode() + this.permissionMask;
132    }
133}
134