1 package iaik.pkcs.pkcs11.objects;
2 
3 import iaik.pkcs.pkcs11.TokenRuntimeException;
4 import iaik.pkcs.pkcs11.wrapper.CK_ATTRIBUTE;
5 import iaik.pkcs.pkcs11.wrapper.PKCS11Constants;
6 
7 import java.util.Hashtable;
8 
9 /**
10  * This is the base-class for all types of attributes. In general, all PKCS#11
11  * objects are just a collection of attributes. PKCS#11 specifies which
12  * attributes each type of objects must have.
13  * In some cases, attributes are optinal (e.g. in RSAPrivateKey). In such a
14  * case, this attribute will return false when the application calls
15  * isPresent() on this attribute. This measn, that the object does not
16  * posses this attribute (maybe even though it should, but not all drivers
17  * seem to implement the standard correctly). Handling attributes in this
18  * fashion ensures that this library can work also with drivers that are
19  * not fully compliant.
20  * Moreover, certain attributes can be sensitive; i.e. their values cannot
21  * be read, e.g. the private exponent of a RSA private key.
22  *
23  * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
24  * @version 1.0
25  * @invariants (ckAttribute_ <> null)
26  */
27 public class Attribute implements Cloneable {
28 
29 	public static final Long CLASS = new Long(PKCS11Constants.CKA_CLASS);
30 	public static final Long TOKEN = new Long(PKCS11Constants.CKA_TOKEN);
31 	public static final Long PRIVATE = new Long(PKCS11Constants.CKA_PRIVATE);
32 	public static final Long LABEL = new Long(PKCS11Constants.CKA_LABEL);
33 	public static final Long APPLICATION = new Long(PKCS11Constants.CKA_APPLICATION);
34 	public static final Long VALUE = new Long(PKCS11Constants.CKA_VALUE);
35 	public static final Long OBJECT_ID = new Long(PKCS11Constants.CKA_OBJECT_ID);
36 	public static final Long CERTIFICATE_TYPE = new Long(
37 	    PKCS11Constants.CKA_CERTIFICATE_TYPE);
38 	public static final Long ISSUER = new Long(PKCS11Constants.CKA_ISSUER);
39 	public static final Long SERIAL_NUMBER = new Long(PKCS11Constants.CKA_SERIAL_NUMBER);
40 	public static final Long URL = new Long(PKCS11Constants.CKA_URL);
41 	public static final Long HASH_OF_SUBJECT_PUBLIC_KEY = new Long(
42 	    PKCS11Constants.CKA_HASH_OF_SUBJECT_PUBLIC_KEY);
43 	public static final Long HASH_OF_ISSUER_PUBLIC_KEY = new Long(
44 	    PKCS11Constants.CKA_HASH_OF_ISSUER_PUBLIC_KEY);
45 	public static final Long JAVA_MIDP_SECURITY_DOMAIN = new Long(
46 	    PKCS11Constants.CKA_JAVA_MIDP_SECURITY_DOMAIN);
47 	public static final Long AC_ISSUER = new Long(PKCS11Constants.CKA_AC_ISSUER);
48 	public static final Long OWNER = new Long(PKCS11Constants.CKA_OWNER);
49 	public static final Long ATTR_TYPES = new Long(PKCS11Constants.CKA_ATTR_TYPES);
50 	public static final Long TRUSTED = new Long(PKCS11Constants.CKA_TRUSTED);
51 	public static final Long KEY_TYPE = new Long(PKCS11Constants.CKA_KEY_TYPE);
52 	public static final Long SUBJECT = new Long(PKCS11Constants.CKA_SUBJECT);
53 	public static final Long ID = new Long(PKCS11Constants.CKA_ID);
54 	public static final Long CHECK_VALUE = new Long(PKCS11Constants.CKA_CHECK_VALUE);
55 	public static final Long CERTIFICATE_CATEGORY = new Long(
56 	    PKCS11Constants.CKA_CERTIFICATE_CATEGORY);
57 	public static final Long SENSITIVE = new Long(PKCS11Constants.CKA_SENSITIVE);
58 	public static final Long ENCRYPT = new Long(PKCS11Constants.CKA_ENCRYPT);
59 	public static final Long DECRYPT = new Long(PKCS11Constants.CKA_DECRYPT);
60 	public static final Long WRAP = new Long(PKCS11Constants.CKA_WRAP);
61 	public static final Long WRAP_TEMPLATE = new Long(PKCS11Constants.CKA_WRAP_TEMPLATE);
62 	public static final Long UNWRAP = new Long(PKCS11Constants.CKA_UNWRAP);
63 	public static final Long UNWRAP_TEMPLATE = new Long(PKCS11Constants.CKA_UNWRAP_TEMPLATE);
64 	public static final Long SIGN = new Long(PKCS11Constants.CKA_SIGN);
65 	public static final Long SIGN_RECOVER = new Long(PKCS11Constants.CKA_SIGN_RECOVER);
66 	public static final Long VERIFY = new Long(PKCS11Constants.CKA_VERIFY);
67 	public static final Long VERIFY_RECOVER = new Long(PKCS11Constants.CKA_VERIFY_RECOVER);
68 	public static final Long DERIVE = new Long(PKCS11Constants.CKA_DERIVE);
69 	public static final Long START_DATE = new Long(PKCS11Constants.CKA_START_DATE);
70 	public static final Long END_DATE = new Long(PKCS11Constants.CKA_END_DATE);
71 	public static final Long MECHANISM_TYPE = new Long(PKCS11Constants.CKA_MECHANISM_TYPE);
72 	public static final Long MODULUS = new Long(PKCS11Constants.CKA_MODULUS);
73 	public static final Long MODULUS_BITS = new Long(PKCS11Constants.CKA_MODULUS_BITS);
74 	public static final Long PUBLIC_EXPONENT = new Long(PKCS11Constants.CKA_PUBLIC_EXPONENT);
75 	public static final Long PRIVATE_EXPONENT = new Long(
76 	    PKCS11Constants.CKA_PRIVATE_EXPONENT);
77 	public static final Long PRIME_1 = new Long(PKCS11Constants.CKA_PRIME_1);
78 	public static final Long PRIME_2 = new Long(PKCS11Constants.CKA_PRIME_2);
79 	public static final Long EXPONENT_1 = new Long(PKCS11Constants.CKA_EXPONENT_1);
80 	public static final Long EXPONENT_2 = new Long(PKCS11Constants.CKA_EXPONENT_2);
81 	public static final Long COEFFICIENT = new Long(PKCS11Constants.CKA_COEFFICIENT);
82 	public static final Long PRIME = new Long(PKCS11Constants.CKA_PRIME);
83 	public static final Long SUBPRIME = new Long(PKCS11Constants.CKA_SUBPRIME);
84 	public static final Long BASE = new Long(PKCS11Constants.CKA_BASE);
85 	public static final Long PRIME_BITS = new Long(PKCS11Constants.CKA_PRIME_BITS);
86 	public static final Long SUB_PRIME_BITS = new Long(PKCS11Constants.CKA_SUB_PRIME_BITS);
87 	public static final Long VALUE_BITS = new Long(PKCS11Constants.CKA_VALUE_BITS);
88 	public static final Long VALUE_LEN = new Long(PKCS11Constants.CKA_VALUE_LEN);
89 	public static final Long EXTRACTABLE = new Long(PKCS11Constants.CKA_EXTRACTABLE);
90 	public static final Long LOCAL = new Long(PKCS11Constants.CKA_LOCAL);
91 	public static final Long NEVER_EXTRACTABLE = new Long(
92 	    PKCS11Constants.CKA_NEVER_EXTRACTABLE);
93 	public static final Long WRAP_WITH_TRUSTED = new Long(
94 	    PKCS11Constants.CKA_WRAP_WITH_TRUSTED);
95 	public static final Long ALWAYS_SENSITIVE = new Long(
96 	    PKCS11Constants.CKA_ALWAYS_SENSITIVE);
97 	public static final Long ALWAYS_AUTHENTICATE = new Long(
98 	    PKCS11Constants.CKA_ALWAYS_AUTHENTICATE);
99 	public static final Long KEY_GEN_MECHANISM = new Long(
100 	    PKCS11Constants.CKA_KEY_GEN_MECHANISM);
101 	public static final Long ALLOWED_MECHANISMS = new Long(
102 	    PKCS11Constants.CKA_ALLOWED_MECHANISMS);
103 	public static final Long MODIFIABLE = new Long(PKCS11Constants.CKA_MODIFIABLE);
104 	public static final Long ECDSA_PARAMS = new Long(PKCS11Constants.CKA_ECDSA_PARAMS);
105 	public static final Long EC_PARAMS = new Long(PKCS11Constants.CKA_EC_PARAMS);
106 	public static final Long EC_POINT = new Long(PKCS11Constants.CKA_EC_POINT);
107 	public static final Long SECONDARY_AUTH = new Long(PKCS11Constants.CKA_SECONDARY_AUTH);
108 	public static final Long AUTH_PIN_FLAGS = new Long(PKCS11Constants.CKA_AUTH_PIN_FLAGS);
109 	public static final Long HW_FEATURE_TYPE = new Long(PKCS11Constants.CKA_HW_FEATURE_TYPE);
110 	public static final Long RESET_ON_INIT = new Long(PKCS11Constants.CKA_RESET_ON_INIT);
111 	public static final Long HAS_RESET = new Long(PKCS11Constants.CKA_HAS_RESET);
112 	public static final Long VENDOR_DEFINED = new Long(PKCS11Constants.CKA_VENDOR_DEFINED);
113 	public static final Long PIXEL_X = new Long(PKCS11Constants.CKA_PIXEL_X);
114 	public static final Long PIXEL_Y = new Long(PKCS11Constants.CKA_PIXEL_Y);
115 	public static final Long RESOLUTION = new Long(PKCS11Constants.CKA_RESOLUTION);
116 	public static final Long CHAR_ROWS = new Long(PKCS11Constants.CKA_CHAR_ROWS);
117 	public static final Long CHAR_COLUMNS = new Long(PKCS11Constants.CKA_CHAR_COLUMNS);
118 	public static final Long COLOR = new Long(PKCS11Constants.CKA_COLOR);
119 	public static final Long BITS_PER_PIXEL = new Long(PKCS11Constants.CKA_BITS_PER_PIXEL);
120 	public static final Long CHAR_SETS = new Long(PKCS11Constants.CKA_CHAR_SETS);
121 	public static final Long ENCODING_METHODS = new Long(
122 	    PKCS11Constants.CKA_ENCODING_METHODS);
123 	public static final Long MIME_TYPES = new Long(PKCS11Constants.CKA_MIME_TYPES);
124 
125 	protected static Hashtable attributeNames_;
126 	protected static Hashtable attributeClasses_;
127 
128 	/**
129 	 * True, if the object really posesses this attribute.
130 	 */
131 	protected boolean present_;
132 
133 	/**
134 	 * True, if this attribute is sensitive.
135 	 */
136 	protected boolean sensitive_;
137 
138 	/**
139 	 * The CK_ATTRIBUTE that is used to hold the PKCS#11 type of this attribute
140 	 * and the value.
141 	 */
142 	protected CK_ATTRIBUTE ckAttribute_;
143 
144 	/**
145 	 * Empty constructor.
146 	 * Attention! If you use this constructor, you must set ckAttribute_ to ensure
147 	 * that the class invariant is not violated.
148 	 *
149 	 * @preconditions
150 	 * @postconditions
151 	 */
Attribute()152 	protected Attribute() { /* left empty intentionally */
153 	}
154 
155 	/**
156 	 * Constructor taking the PKCS#11 type of the attribute.
157 	 *
158 	 * @param type The PKCS'11 type of this attribute; e.g.
159 	 *             PKCS11Constants.CKA_PRIVATE.
160 	 * @preconditions (type <> null)
161 	 * @postconditions
162 	 */
Attribute(Long type)163 	protected Attribute(Long type) {
164 		if (type == null) {
165 			throw new NullPointerException("Argument \"type\" must not be null.");
166 		}
167 
168 		present_ = false;
169 		sensitive_ = false;
170 		ckAttribute_ = new CK_ATTRIBUTE();
171 		ckAttribute_.type = type.longValue();
172 	}
173 
174 	/**
175 	 * Get the name of the given attribute type.
176 	 *
177 	 * @param type The attribute type.
178 	 * @return The name of the attribute type, or null if there is no such type.
179 	 * @preconditions
180 	 * @postconditions
181 	 */
getAttributeName(Long type)182 	protected synchronized static String getAttributeName(Long type) {
183 		if (type == null) {
184 			throw new NullPointerException("Argument \"type\" must not be null.");
185 		}
186 
187 		if (attributeNames_ == null) {
188 			attributeNames_ = new Hashtable(85);
189 			attributeNames_.put(Attribute.CLASS, "Class");
190 			attributeNames_.put(Attribute.TOKEN, "Token");
191 			attributeNames_.put(Attribute.PRIVATE, "Private");
192 			attributeNames_.put(Attribute.LABEL, "Label");
193 			attributeNames_.put(Attribute.APPLICATION, "Application");
194 			attributeNames_.put(Attribute.VALUE, "Value");
195 			attributeNames_.put(Attribute.OBJECT_ID, "Object ID");
196 			attributeNames_.put(Attribute.CERTIFICATE_TYPE, "Certificate Type");
197 			attributeNames_.put(Attribute.ISSUER, "Issuer");
198 			attributeNames_.put(Attribute.SERIAL_NUMBER, "Serial Number");
199 			attributeNames_.put(Attribute.URL, "URL");
200 			attributeNames_.put(Attribute.HASH_OF_SUBJECT_PUBLIC_KEY,
201 			    "Hash Of Subject Public Key");
202 			attributeNames_.put(Attribute.HASH_OF_ISSUER_PUBLIC_KEY,
203 			    "Hash Of Issuer Public Key");
204 			attributeNames_.put(Attribute.JAVA_MIDP_SECURITY_DOMAIN,
205 			    "Java MIDP Security Domain");
206 			attributeNames_.put(Attribute.AC_ISSUER, "AC Issuer");
207 			attributeNames_.put(Attribute.OWNER, "Owner");
208 			attributeNames_.put(Attribute.ATTR_TYPES, "Attribute Types");
209 			attributeNames_.put(Attribute.TRUSTED, "Trusted");
210 			attributeNames_.put(Attribute.KEY_TYPE, "Key Type");
211 			attributeNames_.put(Attribute.SUBJECT, "Subject");
212 			attributeNames_.put(Attribute.ID, "ID");
213 			attributeNames_.put(Attribute.CHECK_VALUE, "Check Value");
214 			attributeNames_.put(Attribute.CERTIFICATE_CATEGORY, "Certificate Category");
215 			attributeNames_.put(Attribute.SENSITIVE, "Sensitive");
216 			attributeNames_.put(Attribute.ENCRYPT, "Encrypt");
217 			attributeNames_.put(Attribute.DECRYPT, "Decrypt");
218 			attributeNames_.put(Attribute.WRAP, "Wrap");
219 			attributeNames_.put(Attribute.UNWRAP, "Unwrap");
220 			attributeNames_.put(Attribute.WRAP_TEMPLATE, "Wrap Template");
221 			attributeNames_.put(Attribute.UNWRAP_TEMPLATE, "Unwrap Template");
222 			attributeNames_.put(Attribute.SIGN, "Sign");
223 			attributeNames_.put(Attribute.SIGN_RECOVER, "Sign Recover");
224 			attributeNames_.put(Attribute.VERIFY, "Verify");
225 			attributeNames_.put(Attribute.VERIFY_RECOVER, "Verify Recover");
226 			attributeNames_.put(Attribute.DERIVE, "Derive");
227 			attributeNames_.put(Attribute.START_DATE, "Start Date");
228 			attributeNames_.put(Attribute.END_DATE, "End Date");
229 			attributeNames_.put(Attribute.MODULUS, "Modulus");
230 			attributeNames_.put(Attribute.MODULUS_BITS, "Modulus Bits");
231 			attributeNames_.put(Attribute.PUBLIC_EXPONENT, "Public Exponent");
232 			attributeNames_.put(Attribute.PRIVATE_EXPONENT, "Private Exponent");
233 			attributeNames_.put(Attribute.PRIME_1, "Prime 1");
234 			attributeNames_.put(Attribute.PRIME_2, "Prime 2");
235 			attributeNames_.put(Attribute.EXPONENT_1, "Exponent 1");
236 			attributeNames_.put(Attribute.EXPONENT_2, "Exponent 2");
237 			attributeNames_.put(Attribute.COEFFICIENT, "Coefficient");
238 			attributeNames_.put(Attribute.PRIME, "Prime");
239 			attributeNames_.put(Attribute.SUBPRIME, "Subprime");
240 			attributeNames_.put(Attribute.BASE, "Base");
241 			attributeNames_.put(Attribute.PRIME_BITS, "Prime Pits");
242 			attributeNames_.put(Attribute.SUB_PRIME_BITS, "Subprime Bits");
243 			attributeNames_.put(Attribute.VALUE_BITS, "Value Bits");
244 			attributeNames_.put(Attribute.VALUE_LEN, "Value Length");
245 			attributeNames_.put(Attribute.EXTRACTABLE, "Extractable");
246 			attributeNames_.put(Attribute.LOCAL, "Local");
247 			attributeNames_.put(Attribute.NEVER_EXTRACTABLE, "Never Extractable");
248 			attributeNames_.put(Attribute.WRAP_WITH_TRUSTED, "Wrap With Trusted");
249 			attributeNames_.put(Attribute.ALWAYS_SENSITIVE, "Always Sensitive");
250 			attributeNames_.put(Attribute.ALWAYS_AUTHENTICATE, "Always Authenticate");
251 			attributeNames_.put(Attribute.KEY_GEN_MECHANISM, "Key Generation Mechanism");
252 			attributeNames_.put(Attribute.ALLOWED_MECHANISMS, "Allowed Mechanisms");
253 			attributeNames_.put(Attribute.MODIFIABLE, "Modifiable");
254 			attributeNames_.put(Attribute.ECDSA_PARAMS, "ECDSA Parameters");
255 			attributeNames_.put(Attribute.EC_PARAMS, "EC Parameters");
256 			attributeNames_.put(Attribute.EC_POINT, "EC Point");
257 			attributeNames_.put(Attribute.SECONDARY_AUTH, "Secondary Authentication");
258 			attributeNames_.put(Attribute.AUTH_PIN_FLAGS, "Authentication PIN Flags");
259 			attributeNames_.put(Attribute.HW_FEATURE_TYPE, "Hardware Feature Type");
260 			attributeNames_.put(Attribute.RESET_ON_INIT, "Reset on Initialization");
261 			attributeNames_.put(Attribute.HAS_RESET, "Has been reset");
262 			attributeNames_.put(Attribute.VENDOR_DEFINED, "Vendor Defined");
263 		}
264 
265 		String name;
266 
267 		if ((type.longValue() & Attribute.VENDOR_DEFINED.longValue()) != 0L) {
268 			StringBuffer nameBuffer = new StringBuffer(36);
269 			nameBuffer.append("VENDOR_DEFINED [0x");
270 			nameBuffer.append(Long.toHexString(type.longValue()));
271 			nameBuffer.append(']');
272 			name = nameBuffer.toString();
273 		} else {
274 			name = (String) attributeNames_.get(type);
275 			if (name == null) {
276 				StringBuffer nameBuffer = new StringBuffer(25);
277 				nameBuffer.append("[0x");
278 				nameBuffer.append(Long.toHexString(type.longValue()));
279 				nameBuffer.append(']');
280 				name = nameBuffer.toString();
281 			}
282 		}
283 
284 		return name;
285 	}
286 
287 	/**
288 	 * Get the class of the given attribute type.
289 	 * Current existing Attribute classes are:
290 	 *           AttributeArray
291 	 *           BooleanAttribute
292 	 *           ByteArrayAttribute
293 	 *           CertificateTypeAttribute
294 	 *           CharArrayAttribute
295 	 *           DateAttribute
296 	 *           HardwareFeatureTypeAttribute
297 	 *           KeyTypeAttribute
298 	 *           LongAttribute
299 	 *           MechanismAttribute
300 	 *           MechanismArrayAttribute
301 	 *           ObjectClassAttribute
302 	 * @param type The attribute type.
303 	 * @return The class of the attribute type, or null if there is no such type.
304 	 * @preconditions
305 	 * @postconditions
306 	 */
getAttributeClass(Long type)307 	protected synchronized static Class getAttributeClass(Long type) {
308 		if (type == null) {
309 			throw new NullPointerException("Argument \"type\" must not be null.");
310 		}
311 
312 		if (attributeClasses_ == null) {
313 			attributeClasses_ = new Hashtable(85);
314 			attributeClasses_.put(Attribute.CLASS, ObjectClassAttribute.class); //CK_OBJECT_CLASS
315 			attributeClasses_.put(Attribute.TOKEN, BooleanAttribute.class); //CK_BBOOL
316 			attributeClasses_.put(Attribute.PRIVATE, BooleanAttribute.class);//CK_BBOOL
317 			attributeClasses_.put(Attribute.LABEL, CharArrayAttribute.class); //RFC2279 string
318 			attributeClasses_.put(Attribute.APPLICATION, CharArrayAttribute.class); //RFC2279 string
319 			attributeClasses_.put(Attribute.VALUE, ByteArrayAttribute.class); //Byte Array
320 			attributeClasses_.put(Attribute.OBJECT_ID, ByteArrayAttribute.class); //Byte Array
321 			attributeClasses_.put(Attribute.CERTIFICATE_TYPE, CertificateTypeAttribute.class); //CK_CERTIFICATE_TYPE
322 			attributeClasses_.put(Attribute.ISSUER, ByteArrayAttribute.class); //Byte array
323 			attributeClasses_.put(Attribute.SERIAL_NUMBER, ByteArrayAttribute.class); //Byte array
324 			attributeClasses_.put(Attribute.URL, CharArrayAttribute.class); //RFC2279 string
325 			attributeClasses_.put(Attribute.HASH_OF_SUBJECT_PUBLIC_KEY,
326 			    ByteArrayAttribute.class); //Byte array
327 			attributeClasses_
328 			    .put(Attribute.HASH_OF_ISSUER_PUBLIC_KEY, ByteArrayAttribute.class); //Byte array
329 			attributeClasses_.put(Attribute.JAVA_MIDP_SECURITY_DOMAIN, LongAttribute.class); //CK_ULONG
330 			attributeClasses_.put(Attribute.AC_ISSUER, ByteArrayAttribute.class); //Byte array
331 			attributeClasses_.put(Attribute.OWNER, ByteArrayAttribute.class); //Byte array
332 			attributeClasses_.put(Attribute.ATTR_TYPES, ByteArrayAttribute.class); //Byte array
333 			attributeClasses_.put(Attribute.TRUSTED, BooleanAttribute.class); //CK_BBOOL
334 			attributeClasses_.put(Attribute.KEY_TYPE, KeyTypeAttribute.class); //CK_KEY_TYPE
335 			attributeClasses_.put(Attribute.SUBJECT, ByteArrayAttribute.class); //Byte array
336 			attributeClasses_.put(Attribute.ID, ByteArrayAttribute.class); //Byte array
337 			attributeClasses_.put(Attribute.CHECK_VALUE, ByteArrayAttribute.class); //Byte array
338 			attributeClasses_.put(Attribute.CERTIFICATE_CATEGORY, LongAttribute.class); //CK_ULONG
339 			attributeClasses_.put(Attribute.SENSITIVE, BooleanAttribute.class); //CK_BBOOL
340 			attributeClasses_.put(Attribute.ENCRYPT, BooleanAttribute.class); //CK_BBOOL
341 			attributeClasses_.put(Attribute.DECRYPT, BooleanAttribute.class); //CK_BBOOL
342 			attributeClasses_.put(Attribute.WRAP, BooleanAttribute.class); //CK_BBOOL
343 			attributeClasses_.put(Attribute.UNWRAP, BooleanAttribute.class); //CK_BBOOL
344 			attributeClasses_.put(Attribute.WRAP_TEMPLATE, AttributeArray.class); //CK_ATTRIBUTE_PTR
345 			attributeClasses_.put(Attribute.UNWRAP_TEMPLATE, AttributeArray.class); //CK_ATTRIBUTE_PTR
346 			attributeClasses_.put(Attribute.SIGN, BooleanAttribute.class); //CK_BBOOL
347 			attributeClasses_.put(Attribute.SIGN_RECOVER, BooleanAttribute.class); //CK_BBOOL
348 			attributeClasses_.put(Attribute.VERIFY, BooleanAttribute.class); //CK_BBOOL
349 			attributeClasses_.put(Attribute.VERIFY_RECOVER, BooleanAttribute.class); //CK_BBOOL
350 			attributeClasses_.put(Attribute.DERIVE, BooleanAttribute.class); //CK_BBOOL
351 			attributeClasses_.put(Attribute.START_DATE, DateAttribute.class); //CK_DATE
352 			attributeClasses_.put(Attribute.END_DATE, DateAttribute.class); //CK_DATE
353 			attributeClasses_.put(Attribute.MODULUS, ByteArrayAttribute.class); //Big integer
354 			attributeClasses_.put(Attribute.MODULUS_BITS, LongAttribute.class); //CK_ULONG
355 			attributeClasses_.put(Attribute.PUBLIC_EXPONENT, ByteArrayAttribute.class); //Big integer
356 			attributeClasses_.put(Attribute.PRIVATE_EXPONENT, ByteArrayAttribute.class); //Big integer
357 			attributeClasses_.put(Attribute.PRIME_1, ByteArrayAttribute.class); //Big integer
358 			attributeClasses_.put(Attribute.PRIME_2, ByteArrayAttribute.class); //Big integer
359 			attributeClasses_.put(Attribute.EXPONENT_1, ByteArrayAttribute.class); //Big integer
360 			attributeClasses_.put(Attribute.EXPONENT_2, ByteArrayAttribute.class); //Big integer
361 			attributeClasses_.put(Attribute.COEFFICIENT, ByteArrayAttribute.class); //Big integer
362 			attributeClasses_.put(Attribute.PRIME, ByteArrayAttribute.class); //Big integer
363 			attributeClasses_.put(Attribute.SUBPRIME, ByteArrayAttribute.class); //Big integer
364 			attributeClasses_.put(Attribute.BASE, ByteArrayAttribute.class); //Big integer
365 			attributeClasses_.put(Attribute.PRIME_BITS, LongAttribute.class); //CK_ULONG
366 			attributeClasses_.put(Attribute.SUB_PRIME_BITS, LongAttribute.class); //CK_ULONG
367 			attributeClasses_.put(Attribute.VALUE_BITS, LongAttribute.class); //CK_ULONG
368 			attributeClasses_.put(Attribute.VALUE_LEN, LongAttribute.class); //CK_ULONG
369 			attributeClasses_.put(Attribute.EXTRACTABLE, BooleanAttribute.class); //CK_BBOOL
370 			attributeClasses_.put(Attribute.LOCAL, BooleanAttribute.class); //CK_BBOOL
371 			attributeClasses_.put(Attribute.NEVER_EXTRACTABLE, BooleanAttribute.class); //CK_BBOOL
372 			attributeClasses_.put(Attribute.WRAP_WITH_TRUSTED, BooleanAttribute.class); //CK_BBOOL
373 			attributeClasses_.put(Attribute.ALWAYS_SENSITIVE, BooleanAttribute.class); //CK_BBOOL
374 			attributeClasses_.put(Attribute.ALWAYS_AUTHENTICATE, BooleanAttribute.class); //CK_BBOOL
375 			attributeClasses_.put(Attribute.KEY_GEN_MECHANISM, MechanismAttribute.class); //CK_MECHANISM_TYPE
376 			attributeClasses_.put(Attribute.ALLOWED_MECHANISMS, MechanismArrayAttribute.class); //CK_MECHANISM_TYPE_PTR
377 			attributeClasses_.put(Attribute.MODIFIABLE, BooleanAttribute.class); //CK_BBOOL
378 			attributeClasses_.put(Attribute.ECDSA_PARAMS, ByteArrayAttribute.class); //Byte array
379 			attributeClasses_.put(Attribute.EC_PARAMS, ByteArrayAttribute.class); //Byte array
380 			attributeClasses_.put(Attribute.EC_POINT, ByteArrayAttribute.class); //Byte array
381 			attributeClasses_.put(Attribute.SECONDARY_AUTH, BooleanAttribute.class); //CK_BBOOL - deprecated
382 			attributeClasses_.put(Attribute.AUTH_PIN_FLAGS, LongAttribute.class); //CK_ULONG - deprecated
383 			attributeClasses_
384 			    .put(Attribute.HW_FEATURE_TYPE, HardwareFeatureTypeAttribute.class); //CK_HW_FEATURE
385 			attributeClasses_.put(Attribute.RESET_ON_INIT, BooleanAttribute.class); //CK_BBOOL
386 			attributeClasses_.put(Attribute.HAS_RESET, BooleanAttribute.class); //CK_BBOOL
387 		}
388 
389 		Class implementation = (Class) attributeClasses_.get(type);
390 		return implementation;
391 
392 	}
393 
394 	/**
395 	 * Create a (deep) clone of this object.
396 	 *
397 	 * @return A clone of this object.
398 	 * @preconditions
399 	 * @postconditions (result <> null)
400 	 *                 and (result instanceof Attribute)
401 	 *                 and (result.equals(this))
402 	 */
clone()403 	public java.lang.Object clone() {
404 		Attribute clone;
405 
406 		try {
407 			clone = (Attribute) super.clone();
408 			clone.ckAttribute_ = (CK_ATTRIBUTE) this.ckAttribute_.clone();
409 		} catch (CloneNotSupportedException ex) {
410 			// this must not happen, because this class is cloneable
411 			throw new TokenRuntimeException("An unexpected clone exception occurred.", ex);
412 		}
413 
414 		return clone;
415 	}
416 
417 	/**
418 	 * Set, if this attribute is really present in the associated object.
419 	 * Does only make sense if used in combination with template objects.
420 	 *
421 	 * @param present True, if attribute is present.
422 	 * @preconditions
423 	 * @postconditions
424 	 */
setPresent(boolean present)425 	public void setPresent(boolean present) {
426 		present_ = present;
427 	}
428 
429 	/**
430 	 * Set, if this attribute is sensitive in the associated object.
431 	 * Does only make sense if used in combination with template objects.
432 	 *
433 	 * @param sensitive True, if attribute is sensitive.
434 	 * @preconditions
435 	 * @postconditions
436 	 */
setSensitive(boolean sensitive)437 	public void setSensitive(boolean sensitive) {
438 		sensitive_ = sensitive;
439 	}
440 
441 	/**
442 	 * Set the CK_ATTRIBUTE of this Attribute.
443 	 * Only for internal use.
444 	 *
445 	 * @param ckAttribute The new CK_ATTRIBUTE of this Attribute.
446 	 * @preconditions (ckAttribute <> null)
447 	 * @postconditions
448 	 */
setCkAttribute(CK_ATTRIBUTE ckAttribute)449 	protected void setCkAttribute(CK_ATTRIBUTE ckAttribute) {
450 		if (ckAttribute == null) {
451 			throw new NullPointerException("Argument \"ckAttribute\" must not be null.");
452 		}
453 		ckAttribute_ = ckAttribute;
454 	}
455 
456 	/**
457 	 * Check, if this attribute is really present in the associated object.
458 	 *
459 	 * @return True, if this attribute is really present in the associated object.
460 	 * @preconditions
461 	 * @postconditions
462 	 */
isPresent()463 	public boolean isPresent() {
464 		return present_;
465 	}
466 
467 	/**
468 	 * Check, if this attribute is sensitive in the associated object.
469 	 *
470 	 * @return True, if this attribute is sensitive in the associated object.
471 	 * @preconditions
472 	 * @postconditions
473 	 */
isSensitive()474 	public boolean isSensitive() {
475 		return sensitive_;
476 	}
477 
478 	/**
479 	 * Get the CK_ATTRIBUTE object of this Attribute that contains the attribute
480 	 * type and value .
481 	 *
482 	 * @return The CK_ATTRIBUTE of this Attribute.
483 	 * @preconditions
484 	 * @postconditions (result <> null)
485 	 */
getCkAttribute()486 	protected CK_ATTRIBUTE getCkAttribute() {
487 		return ckAttribute_;
488 	}
489 
490 	/**
491 	 * Get a string representation of the value of this attribute.
492 	 *
493 	 * @return A string representation of the value of this attribute.
494 	 * @preconditions
495 	 * @postconditions (result <> null)
496 	 */
getValueString()497 	protected String getValueString() {
498 		String valueString;
499 
500 		if ((ckAttribute_ != null) && (ckAttribute_.pValue != null)) {
501 			valueString = ckAttribute_.pValue.toString();
502 		} else {
503 			valueString = "<NULL_PTR>";
504 		}
505 
506 		return valueString;
507 	}
508 
509 	/**
510 	 * Get a string representation of this attribute. If the attribute is not
511 	 * present or if it is sensitive, the output of this method shows jsut
512 	 * a message telling this. This string does not contain the attribute's type
513 	 * name.
514 	 *
515 	 * @return A string representation of the value of this attribute.
516 	 * @preconditions
517 	 * @postconditions (result <> null)
518 	 */
toString()519 	public String toString() {
520 		return toString(false);
521 	}
522 
523 	/**
524 	 * Get a string representation of this attribute. If the attribute is not
525 	 * present or if it is sensitive, the output of this method shows jsut
526 	 * a message telling this.
527 	 *
528 	 * @param withName If true, the string contains the attribute type name and
529 	 *                 the value. If false, it just contains the value.
530 	 * @return A string representation of this attribute.
531 	 * @preconditions
532 	 * @postconditions (result <> null)
533 	 */
toString(boolean withName)534 	public String toString(boolean withName) {
535 		StringBuffer buffer = new StringBuffer(32);
536 
537 		if (withName) {
538 			String typeName = getAttributeName(new Long(ckAttribute_.type));
539 			buffer.append(typeName);
540 			buffer.append(": ");
541 		}
542 		if (present_) {
543 			if (sensitive_) {
544 				buffer.append("<Value is sensitive>");
545 			} else {
546 				buffer.append(getValueString());
547 			}
548 		} else {
549 			buffer.append("<Attribute not present>");
550 		}
551 
552 		return buffer.toString();
553 	}
554 
555 	/**
556 	 * Set the PKCS#11 type of this attribute.
557 	 *
558 	 * @param type The PKCS#11 type of this attribute.
559 	 * @preconditions (type <> null)
560 	 * @postconditions
561 	 */
setType(Long type)562 	protected void setType(Long type) {
563 		if (type == null) {
564 			throw new NullPointerException("Argument \"type\" must not be null.");
565 		}
566 
567 		ckAttribute_.type = type.longValue();
568 	}
569 
570 	/**
571 	 * Get the PKCS#11 type of this attribute.
572 	 *
573 	 * @return The PKCS#11 type of this attribute.
574 	 * @preconditions
575 	 * @postconditions (result <> null)
576 	 */
getType()577 	protected Long getType() {
578 		return new Long(ckAttribute_.type);
579 	}
580 
581 	/**
582 	 * True, if both attributes are not present or if both attributes are present
583 	 * and all other member variables are equal. False, otherwise.
584 	 *
585 	 * @param otherObject The other object to compare to.
586 	 * @return True, if both attributes are not present or if both attributes are
587 	 *         present and all other member variables are equal. False, otherwise.
588 	 * @preconditions
589 	 * @postconditions
590 	 */
equals(java.lang.Object otherObject)591 	public boolean equals(java.lang.Object otherObject) {
592 		boolean equal = false;
593 
594 		if (otherObject instanceof Attribute) {
595 			Attribute other = (Attribute) otherObject;
596 			equal = (this == other)
597 			    || (((this.present_ == false) && (other.present_ == false)) || (((this.present_ == true) && (other.present_ == true)) && ((this.sensitive_ == other.sensitive_)
598 			        && (this.ckAttribute_.type == other.ckAttribute_.type) && ((this.ckAttribute_.pValue == other.ckAttribute_.pValue) || ((this.ckAttribute_.pValue != null) && this.ckAttribute_.pValue
599 			        .equals(other.ckAttribute_.pValue))))));
600 		}
601 
602 		return equal;
603 	}
604 
605 	/**
606 	 * The overriding of this method should ensure that the objects of this class
607 	 * work correctly in a hashtable.
608 	 *
609 	 * @return The hash code of this object.
610 	 * @preconditions
611 	 * @postconditions
612 	 */
hashCode()613 	public int hashCode() {
614 		return ((int) ckAttribute_.type)
615 		    ^ ((ckAttribute_.pValue != null) ? ckAttribute_.pValue.hashCode() : 0);
616 	}
617 
618 }
619