1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.security;
28 
29 import java.io.Serializable;
30 import java.util.Enumeration;
31 import java.util.Properties;
32 
33 /**
34  * <p>This class represents a scope for identities. It is an Identity
35  * itself, and therefore has a name and can have a scope. It can also
36  * optionally have a public key and associated certificates.
37  *
38  * <p>An IdentityScope can contain Identity objects of all kinds, including
39  * Signers. All types of Identity objects can be retrieved, added, and
40  * removed using the same methods. Note that it is possible, and in fact
41  * expected, that different types of identity scopes will
42  * apply different policies for their various operations on the
43  * various types of Identities.
44  *
45  * <p>There is a one-to-one mapping between keys and identities, and
46  * there can only be one copy of one key per scope. For example, suppose
47  * <b>Acme Software, Inc</b> is a software publisher known to a user.
48  * Suppose it is an Identity, that is, it has a public key, and a set of
49  * associated certificates. It is named in the scope using the name
50  * "Acme Software". No other named Identity in the scope has the same
51  * public  key. Of course, none has the same name as well.
52  *
53  * @see Identity
54  * @see Signer
55  * @see Principal
56  * @see Key
57  *
58  * @author Benjamin Renaud
59  * @since 1.1
60  *
61  * @deprecated This class is deprecated and subject to removal in a future
62  *     version of Java SE. It has been replaced by
63  *     {@code java.security.KeyStore}, the {@code java.security.cert} package,
64  *     and {@code java.security.Principal}.
65  */
66 @Deprecated(since="1.2", forRemoval=true)
67 // Android-added: Identity is deprecated too, no need to warn here.
68 @SuppressWarnings("removal")
69 public abstract
70 class IdentityScope extends Identity {
71 
72     private static final long serialVersionUID = -2337346281189773310L;
73 
74     /* The system's scope */
75     private static IdentityScope scope;
76 
77     // initialize the system scope
initializeSystemScope()78     private static void initializeSystemScope() {
79 
80         String classname = AccessController.doPrivileged(
81                                 new PrivilegedAction<>() {
82             public String run() {
83                 return Security.getProperty("system.scope");
84             }
85         });
86 
87         if (classname == null) {
88             return;
89 
90         } else {
91 
92             try {
93                 // Android-changed: Actually set the system scope after initializing it
94                 // Class.forName(classname);
95                 scope = (IdentityScope) Class.forName(classname).newInstance();
96             } catch (Exception e) {
97                 System.err.println("unable to establish a system scope from " +
98                         classname);
99                 e.printStackTrace();
100             }
101         }
102     }
103 
104     /**
105      * This constructor is used for serialization only and should not
106      * be used by subclasses.
107      */
IdentityScope()108     protected IdentityScope() {
109         this("restoring...");
110     }
111 
112     /**
113      * Constructs a new identity scope with the specified name.
114      *
115      * @param name the scope name.
116      */
IdentityScope(String name)117     public IdentityScope(String name) {
118         super(name);
119     }
120 
121     /**
122      * Constructs a new identity scope with the specified name and scope.
123      *
124      * @param name the scope name.
125      * @param scope the scope for the new identity scope.
126      *
127      * @exception KeyManagementException if there is already an identity
128      * with the same name in the scope.
129      */
IdentityScope(String name, IdentityScope scope)130     public IdentityScope(String name, IdentityScope scope)
131     throws KeyManagementException {
132         super(name, scope);
133     }
134 
135     /**
136      * Returns the system's identity scope.
137      *
138      * @return the system's identity scope, or {@code null} if none has been
139      *         set.
140      *
141      * @see #setSystemScope
142      */
getSystemScope()143     public static IdentityScope getSystemScope() {
144         if (scope == null) {
145             initializeSystemScope();
146         }
147         return scope;
148     }
149 
150 
151     /**
152      * Sets the system's identity scope.
153      *
154      * <p>First, if there is a security manager, its
155      * {@code checkSecurityAccess}
156      * method is called with {@code "setSystemScope"}
157      * as its argument to see if it's ok to set the identity scope.
158      *
159      * @param scope the scope to set.
160      *
161      * @exception  SecurityException  if a security manager exists and its
162      * {@code checkSecurityAccess} method doesn't allow
163      * setting the identity scope.
164      *
165      * @see #getSystemScope
166      * @see SecurityManager#checkSecurityAccess
167      */
setSystemScope(IdentityScope scope)168     protected static void setSystemScope(IdentityScope scope) {
169         check("setSystemScope");
170         IdentityScope.scope = scope;
171     }
172 
173     /**
174      * Returns the number of identities within this identity scope.
175      *
176      * @return the number of identities within this identity scope.
177      */
size()178     public abstract int size();
179 
180     /**
181      * Returns the identity in this scope with the specified name (if any).
182      *
183      * @param name the name of the identity to be retrieved.
184      *
185      * @return the identity named {@code name}, or null if there are
186      * no identities named {@code name} in this scope.
187      */
getIdentity(String name)188     public abstract Identity getIdentity(String name);
189 
190     /**
191      * Retrieves the identity whose name is the same as that of the
192      * specified principal. (Note: Identity implements Principal.)
193      *
194      * @param principal the principal corresponding to the identity
195      * to be retrieved.
196      *
197      * @return the identity whose name is the same as that of the
198      * principal, or null if there are no identities of the same name
199      * in this scope.
200      */
getIdentity(Principal principal)201     public Identity getIdentity(Principal principal) {
202         return getIdentity(principal.getName());
203     }
204 
205     /**
206      * Retrieves the identity with the specified public key.
207      *
208      * @param key the public key for the identity to be returned.
209      *
210      * @return the identity with the given key, or null if there are
211      * no identities in this scope with that key.
212      */
getIdentity(PublicKey key)213     public abstract Identity getIdentity(PublicKey key);
214 
215     /**
216      * Adds an identity to this identity scope.
217      *
218      * @param identity the identity to be added.
219      *
220      * @exception KeyManagementException if the identity is not
221      * valid, a name conflict occurs, another identity has the same
222      * public key as the identity being added, or another exception
223      * occurs. */
addIdentity(Identity identity)224     public abstract void addIdentity(Identity identity)
225     throws KeyManagementException;
226 
227     /**
228      * Removes an identity from this identity scope.
229      *
230      * @param identity the identity to be removed.
231      *
232      * @exception KeyManagementException if the identity is missing,
233      * or another exception occurs.
234      */
removeIdentity(Identity identity)235     public abstract void removeIdentity(Identity identity)
236     throws KeyManagementException;
237 
238     /**
239      * Returns an enumeration of all identities in this identity scope.
240      *
241      * @return an enumeration of all identities in this identity scope.
242      */
identities()243     public abstract Enumeration<Identity> identities();
244 
245     /**
246      * Returns a string representation of this identity scope, including
247      * its name, its scope name, and the number of identities in this
248      * identity scope.
249      *
250      * @return a string representation of this identity scope.
251      */
toString()252     public String toString() {
253         return super.toString() + "[" + size() + "]";
254     }
255 
check(String directive)256     private static void check(String directive) {
257         SecurityManager security = System.getSecurityManager();
258         if (security != null) {
259             security.checkSecurityAccess(directive);
260         }
261     }
262 
263 }
264