1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @author Alexander Y. Kleymenov
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project* @version $Revision$
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project*/
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage javax.crypto.spec;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.Serializable;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.spec.KeySpec;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.crypto.SecretKey;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A key specification for a <code>SecretKey</code> and also a secret key
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation that is provider-independent. It can be used for raw secret
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * keys that can be specified as <code>byte[]</code>.
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class SecretKeySpec implements SecretKey, KeySpec, Serializable {
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The 5.0 spec. doesn't declare this serialVersionUID field
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // In order to be compatible it is explicitly declared here
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // for details see HARMONY-233
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = 6577238317307289933L;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final byte[] key;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final String algorithm;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new <code>SecretKeySpec</code> for the specified key data and
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * algorithm name.
48ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key data.
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the algorithm name.
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the key data or the algorithm name is null or if the key
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             data is empty.
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SecretKeySpec(byte[] key, String algorithm) {
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key == null) {
5980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("key == null");
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key.length == 0) {
6280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("key.length == 0");
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (algorithm == null) {
6580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("algorithm == null");
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.algorithm = algorithm;
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.key = new byte[key.length];
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(key, 0, this.key, 0, key.length);
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new <code>SecretKeySpec</code> for the key data from the
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified buffer <code>key</code> starting at <code>offset</code> with
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * length <code>len</code> and the specified <code>algorithm</code> name.
77ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key data.
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the offset.
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the size of the key data.
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the algorithm name.
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the key data or the algorithm name is null, the key data
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             is empty or <code>offset</code> and <code>len</code> do not
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             specify a valid chunk in the buffer <code>key</code>.
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ArrayIndexOutOfBoundsException
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if <code>offset</code> or <code>len</code> is negative.
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SecretKeySpec(byte[] key, int offset, int len, String algorithm) {
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key == null) {
9580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("key == null");
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key.length == 0) {
9880a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("key.length == 0");
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (len < 0 || offset < 0) {
10180a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new ArrayIndexOutOfBoundsException("len < 0 || offset < 0");
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
10380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes        if (key.length - offset < len) {
10480a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("key too short");
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (algorithm == null) {
10780a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("algorithm == null");
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.algorithm = algorithm;
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.key = new byte[len];
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(key, offset, this.key, 0, len);
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the algorithm name.
116ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the algorithm name.
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getAlgorithm() {
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return algorithm;
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the name of the format used to encode the key.
125ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the format name "RAW".
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getFormat() {
1296aa068b481cc4cca7765ce90fdf32f3eb2b5a77cElliott Hughes        return "RAW";
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the encoded form of this secret key.
134ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the encoded form of this secret key.
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getEncoded() {
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] result = new byte[key.length];
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(key, 0, result, 0, key.length);
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the hash code of this <code>SecretKeySpec</code> object.
145ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the hash code.
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int hashCode() {
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int result = algorithm.length();
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (byte element : key) {
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result += element;
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Compares the specified object with this <code>SecretKeySpec</code>
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * instance.
160ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param obj
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the object to compare.
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return true if the algorithm name and key of both object are equal,
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise false.
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean equals(Object obj) {
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (obj == this) {
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(obj instanceof SecretKeySpec)) {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecretKeySpec ks = (SecretKeySpec) obj;
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (algorithm.equalsIgnoreCase(ks.algorithm))
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            && (Arrays.equals(key, ks.key));
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
179