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 javax.crypto.spec;
19
20import java.security.spec.AlgorithmParameterSpec;
21import java.util.Arrays;
22
23import org.apache.harmony.crypto.internal.nls.Messages;
24
25/**
26 * The algorithm parameter specification for the <a
27 * href="http://www.ietf.org/rfc/rfc2268.txt">RC2</a> algorithm.
28 */
29public class RC2ParameterSpec implements AlgorithmParameterSpec {
30
31    private final int effectiveKeyBits;
32    private final byte[] iv;
33
34    /**
35     * Creates a new <code>RC2ParameterSpec</code> instance with the specified
36     * effective key length (in bits),
37     *
38     * @param effectiveKeyBits
39     *            the effective key length (in bits).
40     */
41    public RC2ParameterSpec(int effectiveKeyBits) {
42        this.effectiveKeyBits = effectiveKeyBits;
43        iv = null;
44    }
45
46    /**
47     * Creates a new <code>RC2ParameterSpec</code> instance with the specified
48     * effective key length (in bits) and <i>initialization vector</i>.
49     * <p>
50     * The size of the <i>initialization vector</i> must be at least 8 bytes
51     * which are copied to protect them against modification.
52     *
53     * @param effectiveKeyBits
54     *            the effective key length (in bits).
55     * @param iv
56     *            the initialization vector.
57     * @throws IllegalArgumentException
58     *             if the initialization vector is null or shorter than 8 bytes.
59     */
60    public RC2ParameterSpec(int effectiveKeyBits, byte[] iv) {
61        if (iv == null) {
62            throw new IllegalArgumentException(Messages.getString("crypto.31")); //$NON-NLS-1$
63        }
64        if (iv.length < 8) {
65            throw new IllegalArgumentException(Messages.getString("crypto.41")); //$NON-NLS-1$
66        }
67        this.effectiveKeyBits = effectiveKeyBits;
68        this.iv = new byte[8];
69        System.arraycopy(iv, 0, this.iv, 0, 8);
70    }
71
72    /**
73     * Creates a new <code>RC2ParameterSpec</code> instance with the specified
74     * effective key length (in bits) and <i>initialization vector<i>.
75     * <p>
76     * The size of the <i>initialization vector</i> starting at
77     * <code>offset</code> must be at least 8 bytes which are copied to protect
78     * them against modification.
79     *
80     * @param effectiveKeyBits
81     *            the effective key length (in bits).
82     * @param iv
83     *            the initialization vector.
84     * @param offset
85     *            the offset in the initialization vector to start at.
86     * @throws IllegalArgumentException
87     *             if the initialization vector is null or starting at
88     *             <code>offset</code> is shorter than 8 bytes.
89     */
90    public RC2ParameterSpec(int effectiveKeyBits, byte[] iv, int offset) {
91        if (iv == null) {
92            throw new IllegalArgumentException(Messages.getString("crypto.31")); //$NON-NLS-1$
93        }
94        if (iv.length - offset < 8) {
95            throw new IllegalArgumentException(Messages.getString("crypto.41")); //$NON-NLS-1$
96        }
97        this.effectiveKeyBits = effectiveKeyBits;
98        this.iv = new byte[8];
99        System.arraycopy(iv, offset, this.iv, 0, 8);
100    }
101
102    /**
103     * Returns the effective key length (in bits).
104     *
105     * @return the effective key length (in bits).
106     */
107    public int getEffectiveKeyBits() {
108        return effectiveKeyBits;
109    }
110
111    /**
112     * Returns a copy of the initialization vector.
113     *
114     * @return a copy of the initialization vector, or null if none specified.
115     */
116    public byte[] getIV() {
117        if (iv == null) {
118            return null;
119        }
120        byte[] result = new byte[iv.length];
121        System.arraycopy(iv, 0, result, 0, iv.length);
122        return result;
123    }
124
125    /**
126     * Compares the specified object to this <code>RC2ParameterSpec</code>
127     * instance.
128     *
129     * @param obj
130     *            the object to compare.
131     * @return true if the effective key length and the initialization vector of
132     *         both objects are equal, otherwise false.
133     */
134    @Override
135    public boolean equals(Object obj) {
136        if (obj == this) {
137            return true;
138        }
139        if (!(obj instanceof RC2ParameterSpec)) {
140            return false;
141        }
142        RC2ParameterSpec ps = (RC2ParameterSpec) obj;
143        return (effectiveKeyBits == ps.effectiveKeyBits)
144            && (Arrays.equals(iv, ps.iv));
145    }
146
147    /**
148     * Returns the hash code of this <code>RC2ParameterSpec</code> instance.
149     *
150     * @return the hash code.
151     */
152    @Override
153    public int hashCode() {
154        int result = effectiveKeyBits;
155        if (iv == null) {
156            return result;
157        }
158        for (byte element : iv) {
159            result += element;
160        }
161        return result;
162    }
163}
164
165