1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.security;
19
20import java.io.Serializable;
21import java.util.Arrays;
22import java.util.Vector;
23import libcore.util.Objects;
24
25/**
26 * {@code Identity} represents an identity like a person or a company.
27 *
28 * @deprecated Use {@link Principal}, {@link KeyStore} and the {@code java.security.cert} package
29 * instead.
30 */
31@Deprecated
32public abstract class Identity implements Principal, Serializable {
33    private static final long serialVersionUID = 3609922007826600659L;
34
35    private String name;
36
37    private PublicKey publicKey;
38
39    private String info = "no additional info";
40
41    private IdentityScope scope;
42
43    private Vector<Certificate> certificates;
44
45    /**
46     * Constructs a new instance of {@code Identity}.
47     */
48    protected Identity() {
49    }
50
51    /**
52     * Creates a new instance of {@code Identity} with the specified name.
53     *
54     * @param name
55     *            the name of this {@code Identity}.
56     */
57    public Identity(String name) {
58        this.name = name;
59    }
60
61    /**
62     * Creates a new instance of {@code Identity} with the specified name and
63     * the scope of this {@code Identity}.
64     *
65     * @param name
66     *            the name of this {@code Identity}.
67     * @param scope
68     *            the {@code IdentityScope} of this {@code Identity}.
69     * @throws KeyManagementException
70     *             if an {@code Identity} with the same name is already present
71     *             in the specified scope.
72     */
73    public Identity(String name, IdentityScope scope)
74            throws KeyManagementException {
75        this(name);
76        if (scope != null) {
77            scope.addIdentity(this);
78            this.scope = scope;
79        }
80    }
81
82    /**
83     * Adds a {@code Certificate} to this {@code Identity}.
84     *
85     * @param certificate
86     *            the {@code Certificate} to be added to this {@code Identity}.
87     * @throws KeyManagementException
88     *             if the certificate is not valid.
89     */
90    public void addCertificate(Certificate certificate) throws KeyManagementException {
91        PublicKey certPK = certificate.getPublicKey();
92        if (publicKey != null) {
93            if (!checkKeysEqual(publicKey, certPK)) {
94                throw new KeyManagementException("Cert's public key does not match Identity's public key");
95            }
96        } else {
97            publicKey = certPK;
98        }
99        if (certificates == null) {
100            certificates = new Vector<Certificate>();
101        }
102        certificates.add(certificate);
103    }
104
105
106
107
108    private static boolean checkKeysEqual(PublicKey pk1, PublicKey pk2) {
109        // first, they should have the same format
110        // second, their encoded form must be the same
111
112        // assert(pk1 != null);
113        // assert(pk2 != null);
114
115        String format1 = pk1.getFormat();
116        String format2;
117        if ((pk2 == null)
118                || (((format2 = pk2.getFormat()) != null) ^ (format1 != null))
119                || ((format1 != null) && !format1.equals(format2))) {
120            return false;
121        }
122
123        return Arrays.equals(pk1.getEncoded(), pk2.getEncoded());
124    }
125
126
127
128
129    /**
130     * Removes the specified {@code Certificate} from this {@code Identity}.
131     *
132     * @param certificate
133     *            the {@code Certificate} to be removed.
134     * @throws KeyManagementException
135     *             if the certificate is not found.
136     */
137    public void removeCertificate(Certificate certificate) throws KeyManagementException {
138        if (certificates != null) {
139            if (!certificates.contains(certificate)) {
140                throw new KeyManagementException("Certificate not found");
141            }
142            certificates.removeElement(certificate);
143        }
144    }
145
146
147
148
149    /**
150     * Returns the certificates for this {@code Identity}. External
151     * modifications of the returned array has no impact on this {@code
152     * Identity}.
153     *
154     * @return the {@code Certificates} for this {@code Identity}
155     */
156    public Certificate[] certificates() {
157        if (certificates == null) {
158            return new Certificate[0];
159        }
160        Certificate[] ret = new Certificate[certificates.size()];
161        certificates.copyInto(ret);
162        return ret;
163    }
164
165
166
167
168    /**
169     * Compares the specified {@code Identity} with this {@code Identity} for
170     * equality and returns {@code true} if the specified object is equal,
171     * {@code false} otherwise.
172     * <p>
173     * To be equal, two {@code Identity} objects need to have the same name and
174     * the same public keys.
175     *
176     * @param identity
177     *            the identity to check for equality.
178     * @return {@code true} if the {@code Identity} objects are equal, {@code
179     *         false} otherwise.
180     */
181    protected boolean identityEquals(Identity identity) {
182        if (!name.equals(identity.name)) {
183            return false;
184        }
185
186        if (publicKey == null) {
187            return (identity.publicKey == null);
188        }
189
190        return checkKeysEqual(publicKey, identity.publicKey);
191    }
192
193
194
195
196    /**
197     * Returns a string containing a concise, human-readable description of the
198     * this {@code Identity}.
199     *
200     * @param detailed
201     *            whether or not this method should return detailed information.
202     * @return a printable representation for this {@code Permission}.
203     */
204    public String toString(boolean detailed) {
205        String s = toString();
206        if (detailed) {
207            s += " " + info;
208        }
209        return s;
210    }
211
212
213
214
215    /**
216     * Returns the {@code IdentityScope} of this {@code Identity}.
217     *
218     * @return the {@code IdentityScope} of this {@code Identity}.
219     */
220    public final IdentityScope getScope() {
221        return scope;
222    }
223
224
225
226
227    /**
228     * Sets the specified {@code PublicKey} to this {@code Identity}.
229     *
230     * @param key
231     *            the {@code PublicKey} to be set.
232     * @throws KeyManagementException
233     *             if another {@code Identity} in the same scope as this {@code
234     *             Identity} already has the same {@code PublicKey}.
235     */
236    public void setPublicKey(PublicKey key) throws KeyManagementException {
237        // this check does not always work
238        if ((scope != null) && (key != null)) {
239            Identity i = scope.getIdentity(key);
240            //System.out.println("###DEBUG## Identity: "+i);
241            if ((i != null) && (i != this)) {
242                throw new KeyManagementException("key already used in scope");
243            }
244        }
245        this.publicKey = key;
246        certificates = null;
247    }
248
249
250
251
252    /**
253     * Returns the {@code PublicKey} associated with this {@code Identity}.
254     *
255     * @return the {@code PublicKey} associated with this {@code Identity}.
256     */
257    public PublicKey getPublicKey() {
258        return publicKey;
259    }
260
261
262
263
264    /**
265     * Sets an information string for this {@code Identity}.
266     * @param info
267     *            the information to be set.
268     */
269    public void setInfo(String info) {
270        this.info = info;
271    }
272
273    /**
274     * Returns the information string of this {@code Identity}.
275     *
276     * @return the information string of this {@code Identity}.
277     */
278    public String getInfo() {
279        return info;
280    }
281
282    /**
283     * Compares the specified object with this {@code Identity} for equality and
284     * returns {@code true} if the specified object is equal, {@code false}
285     * otherwise. {@code Identity} objects are considered equal, if they have
286     * the same name and are in the same scope.
287     *
288     * @param obj
289     *            object to be compared for equality with this {@code
290     *            Identity}.
291     * @return {@code true} if the specified object is equal to this {@code
292     *         Identity}, otherwise {@code false}.
293     */
294    @Override
295    public final boolean equals(Object obj) {
296        if (this == obj) {
297            return true;
298        }
299        if (!(obj instanceof Identity)) {
300            return false;
301        }
302        Identity i = (Identity) obj;
303        if (Objects.equal(name, i.name) && (Objects.equal(scope, i.scope))) {
304            return true;
305        }
306        return identityEquals(i);
307    }
308
309    /**
310     * Returns the name of this {@code Identity}.
311     *
312     * @return the name of this {@code Identity}.
313     */
314    public final String getName() {
315        return name;
316    }
317
318    /**
319     * Returns the hash code value for this {@code Identity}. Returns the same
320     * hash code for {@code Identity}s that are equal to each other as required
321     * by the general contract of {@link Object#hashCode}.
322     *
323     * @return the hash code value for this {@code Identity}.
324     * @see Object#equals(Object)
325     * @see Identity#equals(Object)
326     */
327    @Override
328    public int hashCode() {
329        int hash = 0;
330        if (name != null) {
331            hash += name.hashCode();
332        }
333        if (scope != null) {
334            hash += scope.hashCode();
335        }
336        return hash;
337    }
338
339    /**
340     * Returns a string containing a concise, human-readable description of the
341     * this {@code Identity} including its name and its scope.
342     *
343     * @return a printable representation for this {@code Identity}.
344     */
345    @Override
346    public String toString() {
347        String s = (this.name == null ? "" : this.name);
348        if (scope != null) {
349            s += " [" + scope.getName() + "]";
350        }
351        return s;
352    }
353}
354