1 package iaik.pkcs.pkcs11.parameters;
2 
3 import iaik.pkcs.pkcs11.TokenRuntimeException;
4 import iaik.pkcs.pkcs11.wrapper.CK_PBE_PARAMS;
5 import iaik.pkcs.pkcs11.wrapper.Constants;
6 import iaik.pkcs.pkcs11.wrapper.Functions;
7 
8 /**
9  * This class encapsulates parameters for the Mechanism.PBA_* and
10  * Mechanism.PBA_SHA1_WITH_SHA1_HMAC mechanisms.
11  *
12  * @author Karl Scheibelhofer
13  * @version 1.0
14  * @invariants (initializationVector_ == null)
15  *             or ((initializationVector_ <> null)
16  *                 and (initializationVector_.length == 8))
17  *             and (password_ <> null)
18  *             and (salt_ <> null)
19  */
20 public class PBEParameters implements Parameters {
21 
22 	/**
23 	 * The 8-byte initialization vector (IV), if an IV is required.
24 	 */
25 	protected char[] initializationVector_;
26 
27 	/**
28 	 * The password to be used in the PBE key generation.
29 	 */
30 	protected char[] password_;
31 
32 	/**
33 	 * The salt to be used in the PBE key generation.
34 	 */
35 	protected char[] salt_;
36 
37 	/**
38 	 * The number of iterations required for the generation.
39 	 */
40 	protected long iterations_;
41 
42 	/**
43 	 * Create a new PBEDeriveParameters object with the given attributes.
44 	 *
45 	 * @param initializationVector The 8-byte initialization vector (IV), if an
46 	 *                             IV is required.
47 	 * @param password The password to be used in the PBE key generation.
48 	 * @param salt The salt to be used in the PBE key generation.
49 	 * @param iterations The number of iterations required for the generation.
50 	 * @preconditions (initializationVector == null)
51 	 *                or ((initializationVector <> null)
52 	 *                    and (initializationVector.length == 8))
53 	 *                and (password <> null)
54 	 *                and (salt <> null)
55 	 * @postconditions
56 	 */
PBEParameters(char[] initializationVector, char[] password, char[] salt, long iterations)57 	public PBEParameters(char[] initializationVector,
58 	                     char[] password,
59 	                     char[] salt,
60 	                     long iterations)
61 	{
62 		if ((initializationVector != null) && (initializationVector.length != 8)) {
63 			throw new IllegalArgumentException(
64 			    "Argument \"initializationVector\" must be null or must have length "
65 			        + "8, if it is not null.");
66 		}
67 		if (password == null) {
68 			throw new NullPointerException("Argument \"password\" must not be null.");
69 		}
70 		if (salt == null) {
71 			throw new NullPointerException("Argument \"salt\" must not be null.");
72 		}
73 		initializationVector_ = initializationVector;
74 		password_ = password;
75 		salt_ = salt;
76 		iterations_ = iterations;
77 	}
78 
79 	/**
80 	 * Create a (deep) clone of this object.
81 	 *
82 	 * @return A clone of this object.
83 	 * @preconditions
84 	 * @postconditions (result <> null)
85 	 *                 and (result instanceof PBEParameters)
86 	 *                 and (result.equals(this))
87 	 */
clone()88 	public java.lang.Object clone() {
89 		PBEParameters clone;
90 
91 		try {
92 			clone = (PBEParameters) super.clone();
93 
94 			clone.initializationVector_ = (char[]) this.initializationVector_.clone();
95 			clone.password_ = (char[]) this.password_.clone();
96 			clone.salt_ = (char[]) this.salt_.clone();
97 		} catch (CloneNotSupportedException ex) {
98 			// this must not happen, because this class is cloneable
99 			throw new TokenRuntimeException("An unexpected clone exception occurred.", ex);
100 		}
101 
102 		return clone;
103 	}
104 
105 	/**
106 	 * Get this parameters object as an object of the CK_PBE_PARAMS
107 	 * class.
108 	 *
109 	 * @return This object as a CK_PBE_PARAMS object.
110 	 * @preconditions
111 	 * @postconditions (result <> null)
112 	 */
getPKCS11ParamsObject()113 	public Object getPKCS11ParamsObject() {
114 		CK_PBE_PARAMS params = new CK_PBE_PARAMS();
115 
116 		params.pInitVector = initializationVector_;
117 		params.pPassword = password_;
118 		params.pSalt = salt_;
119 		params.ulIteration = iterations_;
120 
121 		return params;
122 	}
123 
124 	/**
125 	 * Get the 8-byte initialization vector (IV), if an IV is required.
126 	 *
127 	 * @return The 8-byte initialization vector (IV), if an IV is required.
128 	 * @preconditions
129 	 * @postconditions (result == null)
130 	 *                 or ((result <> null)
131 	 *                     and (result.length == 8))
132 	 */
getInitializationVector()133 	public char[] getInitializationVector() {
134 		return initializationVector_;
135 	}
136 
137 	/**
138 	 * Get the password to be used in the PBE key generation.
139 	 *
140 	 * @return The password to be used in the PBE key generation.
141 	 * @preconditions
142 	 * @postconditions (result <> null)
143 	 */
getPassword()144 	public char[] getPassword() {
145 		return password_;
146 	}
147 
148 	/**
149 	 * Get the salt to be used in the PBE key generation.
150 	 *
151 	 * @return The salt to be used in the PBE key generation.
152 	 * @preconditions
153 	 * @postconditions (result <> null)
154 	 */
getSalt()155 	public char[] getSalt() {
156 		return salt_;
157 	}
158 
159 	/**
160 	 * Get the number of iterations required for the generation.
161 	 *
162 	 * @return The number of iterations required for the generation.
163 	 * @preconditions
164 	 * @postconditions
165 	 */
getIterations()166 	public long getIterations() {
167 		return iterations_;
168 	}
169 
170 	/**
171 	 * Set the 8-byte initialization vector (IV), if an IV is required.
172 	 *
173 	 * @param initializationVector The 8-byte initialization vector (IV), if an
174 	 *                             IV is required.
175 	 * @preconditions (initializationVector == null)
176 	 *                or ((initializationVector <> null)
177 	 *                    and (initializationVector.length == 8))
178 	 * @postconditions
179 	 */
setInitializationVector(char[] initializationVector)180 	public void setInitializationVector(char[] initializationVector) {
181 		if ((initializationVector != null) && (initializationVector.length != 8)) {
182 			throw new IllegalArgumentException(
183 			    "Argument \"initializationVector\" must be null or must have length "
184 			        + "8, if it is not null.");
185 		}
186 		initializationVector_ = initializationVector;
187 	}
188 
189 	/**
190 	 * Set the password to be used in the PBE key generation.
191 	 *
192 	 * @param password The password to be used in the PBE key generation.
193 	 * @preconditions (password <> null)
194 	 * @postconditions
195 	 */
setPassword(char[] password)196 	public void setPassword(char[] password) {
197 		if (password == null) {
198 			throw new NullPointerException("Argument \"password\" must not be null.");
199 		}
200 		password_ = password;
201 	}
202 
203 	/**
204 	 * Set the salt to be used in the PBE key generation.
205 	 *
206 	 * @param salt The salt to be used in the PBE key generation.
207 	 * @preconditions (salt <> null)
208 	 * @postconditions
209 	 */
setSalt(char[] salt)210 	public void setSalt(char[] salt) {
211 		if (salt == null) {
212 			throw new NullPointerException("Argument \"salt\" must not be null.");
213 		}
214 		salt_ = salt;
215 	}
216 
217 	/**
218 	 * Set the number of iterations required for the generation.
219 	 *
220 	 * @param iterations The number of iterations required for the generation.
221 	 * @preconditions
222 	 * @postconditions
223 	 */
setIterations(long iterations)224 	public void setIterations(long iterations) {
225 		iterations_ = iterations;
226 	}
227 
228 	/**
229 	 * Returns the string representation of this object. Do not parse data from
230 	 * this string, it is for debugging only.
231 	 *
232 	 * @return A string representation of this object.
233 	 */
toString()234 	public String toString() {
235 		StringBuffer buffer = new StringBuffer();
236 
237 		buffer.append(Constants.INDENT);
238 		buffer.append("Initialization Vector: ");
239 		buffer.append((initializationVector_ != null) ? new String(initializationVector_)
240 		    : null);
241 		buffer.append(Constants.NEWLINE);
242 
243 		buffer.append(Constants.INDENT);
244 		buffer.append("Password: ");
245 		buffer.append((password_ != null) ? new String(password_) : null);
246 		buffer.append(Constants.NEWLINE);
247 
248 		buffer.append(Constants.INDENT);
249 		buffer.append("Salt: ");
250 		buffer.append((salt_ != null) ? new String(salt_) : null);
251 		buffer.append(Constants.NEWLINE);
252 
253 		buffer.append(Constants.INDENT);
254 		buffer.append("Iterations (dec): ");
255 		buffer.append(iterations_);
256 		// buffer.append(Constants.NEWLINE);
257 
258 		return buffer.toString();
259 	}
260 
261 	/**
262 	 * Compares all member variables of this object with the other object.
263 	 * Returns only true, if all are equal in both objects.
264 	 *
265 	 * @param otherObject The other object to compare to.
266 	 * @return True, if other is an instance of this class and all member
267 	 *         variables of both objects are equal. False, otherwise.
268 	 * @preconditions
269 	 * @postconditions
270 	 */
equals(java.lang.Object otherObject)271 	public boolean equals(java.lang.Object otherObject) {
272 		boolean equal = false;
273 
274 		if (otherObject instanceof PBEParameters) {
275 			PBEParameters other = (PBEParameters) otherObject;
276 			equal = (this == other)
277 			    || ((Functions.equals(this.initializationVector_, other.initializationVector_)
278 			        && Functions.equals(this.password_, other.password_)
279 			        && Functions.equals(this.salt_, other.salt_) && this.iterations_ == other.iterations_));
280 		}
281 
282 		return equal;
283 	}
284 
285 	/**
286 	 * The overriding of this method should ensure that the objects of this class
287 	 * work correctly in a hashtable.
288 	 *
289 	 * @return The hash code of this object.
290 	 * @preconditions
291 	 * @postconditions
292 	 */
hashCode()293 	public int hashCode() {
294 		return Functions.hashCode(initializationVector_) ^ Functions.hashCode(password_)
295 		    ^ Functions.hashCode(salt_) ^ ((int) iterations_);
296 	}
297 
298 }
299