1723e4046Schristos 
2723e4046Schristos /*
3723e4046Schristos  * Licensed Materials - Property of IBM
4723e4046Schristos  *
5723e4046Schristos  * trousers - An open source TCG Software Stack
6723e4046Schristos  *
7723e4046Schristos  * (C) Copyright International Business Machines Corp. 2005, 2007
8723e4046Schristos  *
9723e4046Schristos  */
10723e4046Schristos 
11723e4046Schristos 
12723e4046Schristos #include <stdlib.h>
13723e4046Schristos #include <stdio.h>
14723e4046Schristos #include <errno.h>
15723e4046Schristos #include <string.h>
16723e4046Schristos 
17723e4046Schristos #include "trousers/tss.h"
18723e4046Schristos #include "trousers/trousers.h"
19723e4046Schristos #include "trousers_types.h"
20723e4046Schristos #include "spi_utils.h"
21723e4046Schristos #include "capabilities.h"
22723e4046Schristos #include "tsplog.h"
23723e4046Schristos #include "obj.h"
24723e4046Schristos #include "tsp_delegate.h"
25723e4046Schristos #include "authsess.h"
26723e4046Schristos 
27723e4046Schristos 
28723e4046Schristos TSS_RESULT
obj_policy_add(TSS_HCONTEXT tsp_context,UINT32 type,TSS_HOBJECT * phObject)29723e4046Schristos obj_policy_add(TSS_HCONTEXT tsp_context, UINT32 type, TSS_HOBJECT *phObject)
30723e4046Schristos {
31723e4046Schristos 	struct tr_policy_obj *policy;
32723e4046Schristos 	TSS_RESULT result;
33723e4046Schristos 
34723e4046Schristos 	if ((policy = calloc(1, sizeof(struct tr_policy_obj))) == NULL) {
35723e4046Schristos 		LogError("malloc of %zd bytes failed", sizeof(struct tr_policy_obj));
36723e4046Schristos 		return TSPERR(TSS_E_OUTOFMEMORY);
37723e4046Schristos 	}
38723e4046Schristos 
39723e4046Schristos 	policy->type = type;
40723e4046Schristos #ifndef TSS_SPEC_COMPLIANCE
41723e4046Schristos 	policy->SecretMode = TSS_SECRET_MODE_NONE;
42723e4046Schristos #else
43723e4046Schristos 	policy->SecretMode = TSS_SECRET_MODE_POPUP;
44723e4046Schristos #endif
45723e4046Schristos 	/* The policy object will inherit this attribute from the context */
46723e4046Schristos 	if ((result = obj_context_get_hash_mode(tsp_context, &policy->hashMode))) {
47723e4046Schristos 		free(policy);
48723e4046Schristos 		return result;
49723e4046Schristos 	}
50723e4046Schristos 	policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS;
51723e4046Schristos #ifdef TSS_BUILD_DELEGATION
52723e4046Schristos 	policy->delegationType = TSS_DELEGATIONTYPE_NONE;
53723e4046Schristos #endif
54723e4046Schristos 
55723e4046Schristos 	if ((result = obj_list_add(&policy_list, tsp_context, 0, policy, phObject))) {
56723e4046Schristos 		free(policy);
57723e4046Schristos 		return result;
58723e4046Schristos 	}
59723e4046Schristos 
60723e4046Schristos 	return TSS_SUCCESS;
61723e4046Schristos }
62723e4046Schristos 
63723e4046Schristos void
__tspi_policy_free(void * data)64723e4046Schristos __tspi_policy_free(void *data)
65723e4046Schristos {
66723e4046Schristos 	struct tr_policy_obj *policy = (struct tr_policy_obj *)data;
67723e4046Schristos 
68723e4046Schristos 	free(policy->popupString);
69723e4046Schristos #ifdef TSS_BUILD_DELEGATION
70723e4046Schristos 	free(policy->delegationBlob);
71723e4046Schristos #endif
72723e4046Schristos 	free(policy);
73723e4046Schristos }
74723e4046Schristos 
75723e4046Schristos TSS_RESULT
obj_policy_remove(TSS_HOBJECT hObject,TSS_HCONTEXT tspContext)76723e4046Schristos obj_policy_remove(TSS_HOBJECT hObject, TSS_HCONTEXT tspContext)
77723e4046Schristos {
78723e4046Schristos 	TSS_RESULT result;
79723e4046Schristos 
80723e4046Schristos 	if ((result = obj_list_remove(&policy_list, &__tspi_policy_free, hObject, tspContext)))
81723e4046Schristos 		return result;
82723e4046Schristos 
83723e4046Schristos 	obj_lists_remove_policy_refs(hObject, tspContext);
84723e4046Schristos 
85723e4046Schristos 	return TSS_SUCCESS;
86723e4046Schristos }
87723e4046Schristos 
88723e4046Schristos TSS_BOOL
obj_is_policy(TSS_HOBJECT hObject)89723e4046Schristos obj_is_policy(TSS_HOBJECT hObject)
90723e4046Schristos {
91723e4046Schristos 	TSS_BOOL answer = FALSE;
92723e4046Schristos 
93723e4046Schristos 	if ((obj_list_get_obj(&policy_list, hObject))) {
94723e4046Schristos 		answer = TRUE;
95723e4046Schristos 		obj_list_put(&policy_list);
96723e4046Schristos 	}
97723e4046Schristos 
98723e4046Schristos 	return answer;
99723e4046Schristos }
100723e4046Schristos 
101723e4046Schristos TSS_RESULT
obj_policy_get_type(TSS_HPOLICY hPolicy,UINT32 * type)102723e4046Schristos obj_policy_get_type(TSS_HPOLICY hPolicy, UINT32 *type)
103723e4046Schristos {
104723e4046Schristos 	struct tsp_object *obj;
105723e4046Schristos 	struct tr_policy_obj *policy;
106723e4046Schristos 
107723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
108723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
109723e4046Schristos 
110723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
111723e4046Schristos 	*type = policy->type;
112723e4046Schristos 
113723e4046Schristos 	obj_list_put(&policy_list);
114723e4046Schristos 
115723e4046Schristos 	return TSS_SUCCESS;
116723e4046Schristos }
117723e4046Schristos 
118723e4046Schristos TSS_RESULT
obj_policy_set_type(TSS_HPOLICY hPolicy,UINT32 type)119723e4046Schristos obj_policy_set_type(TSS_HPOLICY hPolicy, UINT32 type)
120723e4046Schristos {
121723e4046Schristos 	struct tsp_object *obj;
122723e4046Schristos 	struct tr_policy_obj *policy;
123723e4046Schristos 
124723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
125723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
126723e4046Schristos 
127723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
128723e4046Schristos 	policy->type = type;
129723e4046Schristos 
130723e4046Schristos 	obj_list_put(&policy_list);
131723e4046Schristos 
132723e4046Schristos 	return TSS_SUCCESS;
133723e4046Schristos }
134723e4046Schristos 
135723e4046Schristos TSS_RESULT
obj_policy_get_tsp_context(TSS_HPOLICY hPolicy,TSS_HCONTEXT * tspContext)136723e4046Schristos obj_policy_get_tsp_context(TSS_HPOLICY hPolicy, TSS_HCONTEXT *tspContext)
137723e4046Schristos {
138723e4046Schristos 	struct tsp_object *obj;
139723e4046Schristos 
140723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
141723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
142723e4046Schristos 
143723e4046Schristos 	*tspContext = obj->tspContext;
144723e4046Schristos 
145723e4046Schristos 	obj_list_put(&policy_list);
146723e4046Schristos 
147723e4046Schristos 	return TSS_SUCCESS;
148723e4046Schristos }
149723e4046Schristos 
150723e4046Schristos TSS_RESULT
obj_policy_do_hmac(TSS_HPOLICY hPolicy,TSS_HOBJECT hAuthorizedObject,TSS_BOOL returnOrVerify,UINT32 ulPendingFunction,TSS_BOOL continueUse,UINT32 ulSizeNonces,BYTE * rgbNonceEven,BYTE * rgbNonceOdd,BYTE * rgbNonceEvenOSAP,BYTE * rgbNonceOddOSAP,UINT32 ulSizeDigestHmac,BYTE * rgbParamDigest,BYTE * rgbHmacData)151723e4046Schristos obj_policy_do_hmac(TSS_HPOLICY hPolicy, TSS_HOBJECT hAuthorizedObject,
152723e4046Schristos 		   TSS_BOOL returnOrVerify, UINT32 ulPendingFunction,
153723e4046Schristos 		   TSS_BOOL continueUse, UINT32 ulSizeNonces,
154723e4046Schristos 		   BYTE *rgbNonceEven, BYTE *rgbNonceOdd,
155723e4046Schristos 		   BYTE *rgbNonceEvenOSAP, BYTE *rgbNonceOddOSAP,
156723e4046Schristos 		   UINT32 ulSizeDigestHmac, BYTE *rgbParamDigest,
157723e4046Schristos 		   BYTE *rgbHmacData)
158723e4046Schristos {
159723e4046Schristos 	struct tsp_object *obj;
160723e4046Schristos 	struct tr_policy_obj *policy;
161723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
162723e4046Schristos 
163723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
164723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
165723e4046Schristos 
166723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
167723e4046Schristos 
168723e4046Schristos 	result = policy->Tspicb_CallbackHMACAuth(
169723e4046Schristos 			policy->hmacAppData, hAuthorizedObject,
170723e4046Schristos 			returnOrVerify,
171723e4046Schristos 			ulPendingFunction,
172723e4046Schristos 			continueUse,
173723e4046Schristos 			ulSizeNonces,
174723e4046Schristos 			rgbNonceEven,
175723e4046Schristos 			rgbNonceOdd,
176723e4046Schristos 			rgbNonceEvenOSAP, rgbNonceOddOSAP, ulSizeDigestHmac,
177723e4046Schristos 			rgbParamDigest,
178723e4046Schristos 			rgbHmacData);
179723e4046Schristos 
180723e4046Schristos 	obj_list_put(&policy_list);
181723e4046Schristos 
182723e4046Schristos 	return result;
183723e4046Schristos }
184723e4046Schristos 
185723e4046Schristos TSS_RESULT
obj_policy_get_secret(TSS_HPOLICY hPolicy,TSS_BOOL ctx,TCPA_SECRET * secret)186723e4046Schristos obj_policy_get_secret(TSS_HPOLICY hPolicy, TSS_BOOL ctx, TCPA_SECRET *secret)
187723e4046Schristos {
188723e4046Schristos 	struct tsp_object *obj;
189723e4046Schristos 	struct tr_policy_obj *policy;
190723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
191723e4046Schristos 	TCPA_SECRET null_secret;
192723e4046Schristos 
193723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
194723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
195723e4046Schristos 
196723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
197723e4046Schristos 
198*0861b331Schristos 	__tspi_memset(&null_secret, 0, sizeof(TCPA_SECRET));
199723e4046Schristos 
200723e4046Schristos 	switch (policy->SecretMode) {
201723e4046Schristos 		case TSS_SECRET_MODE_POPUP:
202723e4046Schristos 			/* if the secret is still NULL, grab it using the GUI */
203723e4046Schristos 			if (policy->SecretSet == FALSE) {
204723e4046Schristos 				if ((result = popup_GetSecret(ctx,
205723e4046Schristos 							      policy->hashMode,
206723e4046Schristos 							      policy->popupString,
207723e4046Schristos 							      policy->Secret)))
208723e4046Schristos 					break;
209723e4046Schristos 			}
210723e4046Schristos 			policy->SecretSet = TRUE;
211723e4046Schristos 			/* fall through */
212723e4046Schristos 		case TSS_SECRET_MODE_PLAIN:
213723e4046Schristos 		case TSS_SECRET_MODE_SHA1:
214723e4046Schristos 			if (policy->SecretSet == FALSE) {
215723e4046Schristos 				result = TSPERR(TSS_E_POLICY_NO_SECRET);
216723e4046Schristos 				break;
217723e4046Schristos 			}
218723e4046Schristos 
219723e4046Schristos 			memcpy(secret, policy->Secret, sizeof(TCPA_SECRET));
220723e4046Schristos 			break;
221723e4046Schristos 		case TSS_SECRET_MODE_NONE:
222723e4046Schristos 			memcpy(secret, &null_secret, sizeof(TCPA_SECRET));
223723e4046Schristos 			break;
224723e4046Schristos 		default:
225723e4046Schristos 			result = TSPERR(TSS_E_POLICY_NO_SECRET);
226723e4046Schristos 			break;
227723e4046Schristos 	}
228723e4046Schristos #ifdef TSS_DEBUG
229723e4046Schristos 	if (!result) {
230723e4046Schristos 		LogDebug("Got a secret:");
231723e4046Schristos 		LogDebugData(20, (BYTE *)secret);
232723e4046Schristos 	}
233723e4046Schristos #endif
234723e4046Schristos 	obj_list_put(&policy_list);
235723e4046Schristos 
236723e4046Schristos 	return result;
237723e4046Schristos }
238723e4046Schristos 
239723e4046Schristos TSS_RESULT
obj_policy_flush_secret(TSS_HPOLICY hPolicy)240723e4046Schristos obj_policy_flush_secret(TSS_HPOLICY hPolicy)
241723e4046Schristos {
242723e4046Schristos 	struct tsp_object *obj;
243723e4046Schristos 	struct tr_policy_obj *policy;
244723e4046Schristos 
245723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
246723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
247723e4046Schristos 
248723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
249723e4046Schristos 
250*0861b331Schristos 	__tspi_memset(&policy->Secret, 0, policy->SecretSize);
251723e4046Schristos 	policy->SecretSet = FALSE;
252723e4046Schristos 
253723e4046Schristos 	obj_list_put(&policy_list);
254723e4046Schristos 
255723e4046Schristos 	return TSS_SUCCESS;
256723e4046Schristos }
257723e4046Schristos 
258723e4046Schristos TSS_RESULT
obj_policy_set_secret_object(TSS_HPOLICY hPolicy,TSS_FLAG mode,UINT32 size,TCPA_DIGEST * digest,TSS_BOOL set)259723e4046Schristos obj_policy_set_secret_object(TSS_HPOLICY hPolicy, TSS_FLAG mode, UINT32 size,
260723e4046Schristos 			     TCPA_DIGEST *digest, TSS_BOOL set)
261723e4046Schristos {
262723e4046Schristos 	struct tsp_object *obj;
263723e4046Schristos 	struct tr_policy_obj *policy;
264723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
265723e4046Schristos 
266723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
267723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
268723e4046Schristos 
269723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
270723e4046Schristos 
271723e4046Schristos 	/* if this is going to be a callback policy, the
272723e4046Schristos 	 * callbacks need to already be set. (See TSS 1.1b
273723e4046Schristos 	 * spec pg. 62). */
274723e4046Schristos 	if (mode == TSS_SECRET_MODE_CALLBACK) {
275723e4046Schristos 		if (policy->Tspicb_CallbackHMACAuth == NULL) {
276723e4046Schristos 			result = TSPERR(TSS_E_FAIL);
277723e4046Schristos 			goto done;
278723e4046Schristos 		}
279723e4046Schristos 	}
280723e4046Schristos 
281723e4046Schristos 	if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER) {
282723e4046Schristos 		policy->SecretCounter = policy->SecretTimeStamp;
283723e4046Schristos 	} else if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) {
284723e4046Schristos 		time_t t = time(NULL);
285723e4046Schristos 		if (t == ((time_t)-1)) {
286723e4046Schristos 			LogError("time failed: %s", strerror(errno));
287723e4046Schristos 			result = TSPERR(TSS_E_INTERNAL_ERROR);
288723e4046Schristos 			goto done;
289723e4046Schristos 		}
290723e4046Schristos 
291723e4046Schristos 		policy->SecretTimeStamp = t;
292723e4046Schristos 	}
293723e4046Schristos 
294723e4046Schristos 	memcpy(policy->Secret, digest, size);
295723e4046Schristos 	policy->SecretMode = mode;
296723e4046Schristos 	policy->SecretSize = size;
297723e4046Schristos 	policy->SecretSet = set;
298723e4046Schristos done:
299723e4046Schristos 	obj_list_put(&policy_list);
300723e4046Schristos 
301723e4046Schristos 	return result;
302723e4046Schristos }
303723e4046Schristos 
304723e4046Schristos TSS_RESULT
obj_policy_is_secret_set(TSS_HPOLICY hPolicy,TSS_BOOL * secretSet)305723e4046Schristos obj_policy_is_secret_set(TSS_HPOLICY hPolicy, TSS_BOOL *secretSet)
306723e4046Schristos {
307723e4046Schristos 	struct tsp_object *obj;
308723e4046Schristos 	struct tr_policy_obj *policy;
309723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
310723e4046Schristos 
311723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
312723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
313723e4046Schristos 
314723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
315723e4046Schristos 
316723e4046Schristos 	*secretSet = policy->SecretSet;
317723e4046Schristos 	obj_list_put(&policy_list);
318723e4046Schristos 
319723e4046Schristos 	return result;
320723e4046Schristos }
321723e4046Schristos 
322723e4046Schristos 
323723e4046Schristos TSS_RESULT
obj_policy_set_secret(TSS_HPOLICY hPolicy,TSS_FLAG mode,UINT32 size,BYTE * data)324723e4046Schristos obj_policy_set_secret(TSS_HPOLICY hPolicy, TSS_FLAG mode, UINT32 size, BYTE *data)
325723e4046Schristos {
326723e4046Schristos 	TCPA_DIGEST digest;
327723e4046Schristos 	UINT32 secret_size = 0;
328723e4046Schristos 	TSS_BOOL secret_set = TRUE;
329723e4046Schristos 	TSS_RESULT result;
330723e4046Schristos 
331*0861b331Schristos 	__tspi_memset(&digest.digest, 0, sizeof(TCPA_DIGEST));
332723e4046Schristos 
333723e4046Schristos 	switch (mode) {
334723e4046Schristos 		case TSS_SECRET_MODE_PLAIN:
335723e4046Schristos 			if ((result = Trspi_Hash(TSS_HASH_SHA1, size, data,
336723e4046Schristos 						 (BYTE *)&digest.digest)))
337723e4046Schristos 				return result;
338723e4046Schristos 			secret_size = TCPA_SHA1_160_HASH_LEN;
339723e4046Schristos 			break;
340723e4046Schristos 		case TSS_SECRET_MODE_SHA1:
341723e4046Schristos 			if (size != TCPA_SHA1_160_HASH_LEN)
342723e4046Schristos 				return TSPERR(TSS_E_BAD_PARAMETER);
343723e4046Schristos 
344723e4046Schristos 			memcpy(&digest.digest, data, size);
345723e4046Schristos 			secret_size = TCPA_SHA1_160_HASH_LEN;
346723e4046Schristos 			break;
347723e4046Schristos 		case TSS_SECRET_MODE_POPUP:
348723e4046Schristos 		case TSS_SECRET_MODE_NONE:
349723e4046Schristos 			secret_set = FALSE;
350723e4046Schristos 		case TSS_SECRET_MODE_CALLBACK:
351723e4046Schristos 			break;
352723e4046Schristos 		default:
353723e4046Schristos 			return TSPERR(TSS_E_BAD_PARAMETER);
354723e4046Schristos 	}
355723e4046Schristos 
356723e4046Schristos 	return obj_policy_set_secret_object(hPolicy, mode, secret_size,
357723e4046Schristos 					    &digest, secret_set);
358723e4046Schristos }
359723e4046Schristos 
360723e4046Schristos TSS_RESULT
obj_policy_get_cb11(TSS_HPOLICY hPolicy,TSS_FLAG type,UINT32 * cb)361723e4046Schristos obj_policy_get_cb11(TSS_HPOLICY hPolicy, TSS_FLAG type, UINT32 *cb)
362723e4046Schristos {
363723e4046Schristos #ifndef __LP64__
364723e4046Schristos 	struct tsp_object *obj;
365723e4046Schristos 	struct tr_policy_obj *policy;
366723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
367723e4046Schristos 
368723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
369723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
370723e4046Schristos 
371723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
372723e4046Schristos 
373723e4046Schristos 	switch (type) {
374723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
375723e4046Schristos 			*cb = (UINT32)policy->Tspicb_CallbackHMACAuth;
376723e4046Schristos 			break;
377723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
378723e4046Schristos 			*cb = (UINT32)policy->Tspicb_CallbackXorEnc;
379723e4046Schristos 			break;
380723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
381723e4046Schristos 			*cb = (UINT32)policy->Tspicb_CallbackTakeOwnership;
382723e4046Schristos 			break;
383723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
384723e4046Schristos 			*cb = (UINT32)policy->Tspicb_CallbackChangeAuthAsym;
385723e4046Schristos 			break;
386723e4046Schristos 		default:
387723e4046Schristos 			result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
388723e4046Schristos 			break;
389723e4046Schristos 	}
390723e4046Schristos 
391723e4046Schristos 	obj_list_put(&policy_list);
392723e4046Schristos 
393723e4046Schristos 	return result;
394723e4046Schristos #else
395723e4046Schristos 	return TSPERR(TSS_E_FAIL);
396723e4046Schristos #endif
397723e4046Schristos }
398723e4046Schristos 
399723e4046Schristos TSS_RESULT
obj_policy_set_cb11(TSS_HPOLICY hPolicy,TSS_FLAG type,TSS_FLAG app_data,UINT32 cb)400723e4046Schristos obj_policy_set_cb11(TSS_HPOLICY hPolicy, TSS_FLAG type, TSS_FLAG app_data, UINT32 cb)
401723e4046Schristos {
402723e4046Schristos #ifndef __LP64__
403723e4046Schristos 	struct tsp_object *obj;
404723e4046Schristos 	struct tr_policy_obj *policy;
405723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
406723e4046Schristos 
407723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
408723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
409723e4046Schristos 
410723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
411723e4046Schristos 
412723e4046Schristos 	switch (type) {
413723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
414723e4046Schristos 			policy->Tspicb_CallbackHMACAuth = (PVOID)cb;
415723e4046Schristos 			policy->hmacAppData = (PVOID)app_data;
416723e4046Schristos 			break;
417723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
418723e4046Schristos 			policy->Tspicb_CallbackXorEnc = (PVOID)cb;
419723e4046Schristos 			policy->xorAppData = (PVOID)app_data;
420723e4046Schristos 			break;
421723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
422723e4046Schristos 			policy->Tspicb_CallbackTakeOwnership = (PVOID)cb;
423723e4046Schristos 			policy->takeownerAppData = (PVOID)app_data;
424723e4046Schristos 			break;
425723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
426723e4046Schristos 			policy->Tspicb_CallbackChangeAuthAsym = (PVOID)cb;
427723e4046Schristos 			policy->changeauthAppData = (PVOID)app_data;
428723e4046Schristos 			break;
429723e4046Schristos 		default:
430723e4046Schristos 			result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
431723e4046Schristos 			break;
432723e4046Schristos 	}
433723e4046Schristos 
434723e4046Schristos 	obj_list_put(&policy_list);
435723e4046Schristos 
436723e4046Schristos 	return result;
437723e4046Schristos #else
438723e4046Schristos 	return TSPERR(TSS_E_FAIL);
439723e4046Schristos #endif
440723e4046Schristos }
441723e4046Schristos 
442723e4046Schristos TSS_RESULT
obj_policy_set_cb12(TSS_HPOLICY hPolicy,TSS_FLAG flag,BYTE * in)443723e4046Schristos obj_policy_set_cb12(TSS_HPOLICY hPolicy, TSS_FLAG flag, BYTE *in)
444723e4046Schristos {
445723e4046Schristos 	struct tsp_object *obj;
446723e4046Schristos 	struct tr_policy_obj *policy;
447723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
448723e4046Schristos 	TSS_CALLBACK *cb = (TSS_CALLBACK *)in;
449723e4046Schristos 
450723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
451723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
452723e4046Schristos 
453723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
454723e4046Schristos 
455723e4046Schristos 	switch (flag) {
456723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
457723e4046Schristos 			if (!cb) {
458723e4046Schristos 				policy->Tspicb_CallbackHMACAuth = NULL;
459723e4046Schristos 				break;
460723e4046Schristos 			}
461723e4046Schristos 
462723e4046Schristos 			policy->Tspicb_CallbackHMACAuth =
463723e4046Schristos 				(TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_BOOL,
464723e4046Schristos 				UINT32, TSS_BOOL, UINT32, BYTE *, BYTE *,
465723e4046Schristos 				BYTE *, BYTE *, UINT32, BYTE *, BYTE *))
466723e4046Schristos 				cb->callback;
467723e4046Schristos 			policy->hmacAppData = cb->appData;
468723e4046Schristos 			policy->hmacAlg = cb->alg;
469723e4046Schristos 			break;
470723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
471723e4046Schristos 			if (!cb) {
472723e4046Schristos 				policy->Tspicb_CallbackXorEnc = NULL;
473723e4046Schristos 				break;
474723e4046Schristos 			}
475723e4046Schristos 
476723e4046Schristos 			policy->Tspicb_CallbackXorEnc =
477723e4046Schristos 				(TSS_RESULT (*)(PVOID, TSS_HOBJECT,
478723e4046Schristos 				TSS_HOBJECT, TSS_FLAG, UINT32, BYTE *, BYTE *,
479723e4046Schristos 				BYTE *, BYTE *, UINT32, BYTE *, BYTE *))
480723e4046Schristos 				cb->callback;
481723e4046Schristos 			policy->xorAppData = cb->appData;
482723e4046Schristos 			policy->xorAlg = cb->alg;
483723e4046Schristos 			break;
484723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
485723e4046Schristos 			if (!cb) {
486723e4046Schristos 				policy->Tspicb_CallbackTakeOwnership = NULL;
487723e4046Schristos 				break;
488723e4046Schristos 			}
489723e4046Schristos 
490723e4046Schristos 			policy->Tspicb_CallbackTakeOwnership =
491723e4046Schristos 				(TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HKEY,
492723e4046Schristos 				UINT32, BYTE *))cb->callback;
493723e4046Schristos 			policy->takeownerAppData = cb->appData;
494723e4046Schristos 			policy->takeownerAlg = cb->alg;
495723e4046Schristos 			break;
496723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
497723e4046Schristos 			if (!cb) {
498723e4046Schristos 				policy->Tspicb_CallbackChangeAuthAsym = NULL;
499723e4046Schristos 				break;
500723e4046Schristos 			}
501723e4046Schristos 
502723e4046Schristos 			policy->Tspicb_CallbackChangeAuthAsym =
503723e4046Schristos 				(TSS_RESULT (*)(PVOID, TSS_HOBJECT, TSS_HKEY,
504723e4046Schristos 				UINT32, UINT32, BYTE *, BYTE *))cb->callback;
505723e4046Schristos 			policy->changeauthAppData = cb->appData;
506723e4046Schristos 			policy->changeauthAlg = cb->alg;
507723e4046Schristos 			break;
508723e4046Schristos #ifdef TSS_BUILD_SEALX
509723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK:
510723e4046Schristos 			if (!cb) {
511723e4046Schristos 				policy->Tspicb_CallbackSealxMask = NULL;
512723e4046Schristos 				policy->sealxAppData = NULL;
513723e4046Schristos 				policy->sealxAlg = 0;
514723e4046Schristos 				break;
515723e4046Schristos 			}
516723e4046Schristos 
517723e4046Schristos 			policy->Tspicb_CallbackSealxMask =
518723e4046Schristos 				(TSS_RESULT (*)(PVOID, TSS_HKEY, TSS_HENCDATA,
519723e4046Schristos 				TSS_ALGORITHM_ID, UINT32, BYTE *, BYTE *, BYTE *, BYTE *,
520723e4046Schristos 				UINT32, BYTE *, BYTE *))cb->callback;
521723e4046Schristos 			policy->sealxAppData = cb->appData;
522723e4046Schristos 			policy->sealxAlg = cb->alg;
523723e4046Schristos 			break;
524723e4046Schristos #endif
525723e4046Schristos 		default:
526723e4046Schristos 			result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
527723e4046Schristos 			break;
528723e4046Schristos 	}
529723e4046Schristos 
530723e4046Schristos 	obj_list_put(&policy_list);
531723e4046Schristos 
532723e4046Schristos 	return result;
533723e4046Schristos }
534723e4046Schristos 
535723e4046Schristos TSS_RESULT
obj_policy_get_cb12(TSS_HPOLICY hPolicy,TSS_FLAG flag,UINT32 * size,BYTE ** out)536723e4046Schristos obj_policy_get_cb12(TSS_HPOLICY hPolicy, TSS_FLAG flag, UINT32 *size, BYTE **out)
537723e4046Schristos {
538723e4046Schristos 	struct tsp_object *obj;
539723e4046Schristos 	struct tr_policy_obj *policy;
540723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
541723e4046Schristos 	TSS_CALLBACK *cb;
542723e4046Schristos 
543723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
544723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
545723e4046Schristos 
546723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
547723e4046Schristos 
548723e4046Schristos 	if ((cb = calloc_tspi(obj->tspContext, sizeof(TSS_CALLBACK))) == NULL) {
549723e4046Schristos 		LogError("malloc of %zd bytes failed.", sizeof(TSS_CALLBACK));
550723e4046Schristos 		result = TSPERR(TSS_E_OUTOFMEMORY);
551723e4046Schristos 		goto done;
552723e4046Schristos 	}
553723e4046Schristos 
554723e4046Schristos 	switch (flag) {
555723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_HMAC:
556723e4046Schristos 			cb->callback = policy->Tspicb_CallbackHMACAuth;
557723e4046Schristos 			cb->appData = policy->hmacAppData;
558723e4046Schristos 			cb->alg = policy->hmacAlg;
559723e4046Schristos 			*size = sizeof(TSS_CALLBACK);
560723e4046Schristos 			*out = (BYTE *)cb;
561723e4046Schristos 			break;
562723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_XOR_ENC:
563723e4046Schristos 			cb->callback = policy->Tspicb_CallbackXorEnc;
564723e4046Schristos 			cb->appData = policy->xorAppData;
565723e4046Schristos 			cb->alg = policy->xorAlg;
566723e4046Schristos 			*size = sizeof(TSS_CALLBACK);
567723e4046Schristos 			*out = (BYTE *)cb;
568723e4046Schristos 			break;
569723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_TAKEOWNERSHIP:
570723e4046Schristos 			cb->callback = policy->Tspicb_CallbackTakeOwnership;
571723e4046Schristos 			cb->appData = policy->takeownerAppData;
572723e4046Schristos 			cb->alg = policy->takeownerAlg;
573723e4046Schristos 			*size = sizeof(TSS_CALLBACK);
574723e4046Schristos 			*out = (BYTE *)cb;
575723e4046Schristos 			break;
576723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_CHANGEAUTHASYM:
577723e4046Schristos 			cb->callback = policy->Tspicb_CallbackChangeAuthAsym;
578723e4046Schristos 			cb->appData = policy->changeauthAppData;
579723e4046Schristos 			cb->alg = policy->changeauthAlg;
580723e4046Schristos 			*size = sizeof(TSS_CALLBACK);
581723e4046Schristos 			*out = (BYTE *)cb;
582723e4046Schristos 			break;
583723e4046Schristos #ifdef TSS_BUILD_SEALX
584723e4046Schristos 		case TSS_TSPATTRIB_POLICY_CALLBACK_SEALX_MASK:
585723e4046Schristos 			cb->callback = policy->Tspicb_CallbackSealxMask;
586723e4046Schristos 			cb->appData = policy->sealxAppData;
587723e4046Schristos 			cb->alg = policy->sealxAlg;
588723e4046Schristos 			*size = sizeof(TSS_CALLBACK);
589723e4046Schristos 			*out = (BYTE *)cb;
590723e4046Schristos 			break;
591723e4046Schristos #endif
592723e4046Schristos 		default:
593723e4046Schristos 			free_tspi(obj->tspContext, cb);
594723e4046Schristos 			result = TSPERR(TSS_E_INVALID_ATTRIB_FLAG);
595723e4046Schristos 			break;
596723e4046Schristos 	}
597723e4046Schristos done:
598723e4046Schristos 	obj_list_put(&policy_list);
599723e4046Schristos 
600723e4046Schristos 	return result;
601723e4046Schristos }
602723e4046Schristos 
603723e4046Schristos TSS_RESULT
obj_policy_get_lifetime(TSS_HPOLICY hPolicy,UINT32 * lifetime)604723e4046Schristos obj_policy_get_lifetime(TSS_HPOLICY hPolicy, UINT32 *lifetime)
605723e4046Schristos {
606723e4046Schristos 	struct tsp_object *obj;
607723e4046Schristos 	struct tr_policy_obj *policy;
608723e4046Schristos 
609723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
610723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
611723e4046Schristos 
612723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
613723e4046Schristos 	*lifetime = policy->SecretLifetime;
614723e4046Schristos 
615723e4046Schristos 	obj_list_put(&policy_list);
616723e4046Schristos 
617723e4046Schristos 	return TSS_SUCCESS;
618723e4046Schristos }
619723e4046Schristos 
620723e4046Schristos TSS_RESULT
obj_policy_set_lifetime(TSS_HPOLICY hPolicy,UINT32 type,UINT32 value)621723e4046Schristos obj_policy_set_lifetime(TSS_HPOLICY hPolicy, UINT32 type, UINT32 value)
622723e4046Schristos {
623723e4046Schristos 	struct tsp_object *obj;
624723e4046Schristos 	struct tr_policy_obj *policy;
625723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
626723e4046Schristos 	time_t t;
627723e4046Schristos 
628723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
629723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
630723e4046Schristos 
631723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
632723e4046Schristos 
633723e4046Schristos 	switch (type) {
634723e4046Schristos 		case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS:
635723e4046Schristos 			policy->SecretCounter = 0;
636723e4046Schristos 			policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS;
637723e4046Schristos 			policy->SecretTimeStamp = 0;
638723e4046Schristos 			break;
639723e4046Schristos 		case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER:
640723e4046Schristos 			/* Both SecretCounter and SecretTimeStamp will receive value. Every time the
641723e4046Schristos 			 * policy is used, SecretCounter will be decremented. Each time SetSecret is
642723e4046Schristos 			 * called, SecretCounter will get the value stored in SecretTimeStamp */
643723e4046Schristos 			policy->SecretCounter = value;
644723e4046Schristos 			policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER;
645723e4046Schristos 			policy->SecretTimeStamp = value;
646723e4046Schristos 			break;
647723e4046Schristos 		case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER:
648723e4046Schristos 			t = time(NULL);
649723e4046Schristos 			if (t == ((time_t)-1)) {
650723e4046Schristos 				LogError("time failed: %s", strerror(errno));
651723e4046Schristos 				result = TSPERR(TSS_E_INTERNAL_ERROR);
652723e4046Schristos 				break;
653723e4046Schristos 			}
654723e4046Schristos 
655723e4046Schristos 			/* For mode time, we'll use the SecretCounter variable to hold the number
656723e4046Schristos 			 * of seconds we're valid and the SecretTimeStamp var to record the current
657723e4046Schristos 			 * timestamp. This should protect against overflows. */
658723e4046Schristos 			policy->SecretCounter = value;
659723e4046Schristos 			policy->SecretLifetime = TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER;
660723e4046Schristos 			policy->SecretTimeStamp = t;
661723e4046Schristos 			break;
662723e4046Schristos 		default:
663723e4046Schristos 			result = TSPERR(TSS_E_BAD_PARAMETER);
664723e4046Schristos 			break;
665723e4046Schristos 	}
666723e4046Schristos 
667723e4046Schristos 	obj_list_put(&policy_list);
668723e4046Schristos 
669723e4046Schristos 	return result;
670723e4046Schristos }
671723e4046Schristos 
672723e4046Schristos TSS_RESULT
obj_policy_get_mode(TSS_HPOLICY hPolicy,UINT32 * mode)673723e4046Schristos obj_policy_get_mode(TSS_HPOLICY hPolicy, UINT32 *mode)
674723e4046Schristos {
675723e4046Schristos 	struct tsp_object *obj;
676723e4046Schristos 	struct tr_policy_obj *policy;
677723e4046Schristos 
678723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
679723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
680723e4046Schristos 
681723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
682723e4046Schristos 	*mode = policy->SecretMode;
683723e4046Schristos 
684723e4046Schristos 	obj_list_put(&policy_list);
685723e4046Schristos 
686723e4046Schristos 	return TSS_SUCCESS;
687723e4046Schristos }
688723e4046Schristos 
689723e4046Schristos TSS_RESULT
obj_policy_get_counter(TSS_HPOLICY hPolicy,UINT32 * counter)690723e4046Schristos obj_policy_get_counter(TSS_HPOLICY hPolicy, UINT32 *counter)
691723e4046Schristos {
692723e4046Schristos 	struct tsp_object *obj;
693723e4046Schristos 	struct tr_policy_obj *policy;
694723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
695723e4046Schristos 
696723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
697723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
698723e4046Schristos 
699723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
700723e4046Schristos 
701723e4046Schristos 	if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER)
702723e4046Schristos 		*counter = policy->SecretCounter;
703723e4046Schristos 	else
704723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
705723e4046Schristos 
706723e4046Schristos 	obj_list_put(&policy_list);
707723e4046Schristos 
708723e4046Schristos 	return result;
709723e4046Schristos }
710723e4046Schristos 
711723e4046Schristos TSS_RESULT
obj_policy_dec_counter(TSS_HPOLICY hPolicy)712723e4046Schristos obj_policy_dec_counter(TSS_HPOLICY hPolicy)
713723e4046Schristos {
714723e4046Schristos 	struct tsp_object *obj;
715723e4046Schristos 	struct tr_policy_obj *policy;
716723e4046Schristos 
717723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
718723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
719723e4046Schristos 
720723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
721723e4046Schristos 
722723e4046Schristos 	/* Only decrement if SecretCounter > 0, otherwise it could loop and become valid again */
723723e4046Schristos 	if (policy->SecretLifetime == TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER &&
724723e4046Schristos 	    policy->SecretCounter > 0) {
725723e4046Schristos 		policy->SecretCounter--;
726723e4046Schristos 	}
727723e4046Schristos 
728723e4046Schristos 	obj_list_put(&policy_list);
729723e4046Schristos 
730723e4046Schristos 	return TSS_SUCCESS;
731723e4046Schristos }
732723e4046Schristos 
733723e4046Schristos /* return a unicode string to the Tspi_GetAttribData function */
734723e4046Schristos TSS_RESULT
obj_policy_get_string(TSS_HPOLICY hPolicy,UINT32 * size,BYTE ** data)735723e4046Schristos obj_policy_get_string(TSS_HPOLICY hPolicy, UINT32 *size, BYTE **data)
736723e4046Schristos {
737723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
738723e4046Schristos 	BYTE *utf_string;
739723e4046Schristos 	UINT32 utf_size;
740723e4046Schristos 	struct tsp_object *obj;
741723e4046Schristos 	struct tr_policy_obj *policy;
742723e4046Schristos 
743723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
744723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
745723e4046Schristos 
746723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
747723e4046Schristos 
748723e4046Schristos 	*size = policy->popupStringLength;
749723e4046Schristos 	if (policy->popupStringLength == 0) {
750723e4046Schristos 		*data = NULL;
751723e4046Schristos 	} else {
752723e4046Schristos 		utf_size = policy->popupStringLength;
753723e4046Schristos 		utf_string = Trspi_Native_To_UNICODE(policy->popupString,
754723e4046Schristos 						     &utf_size);
755723e4046Schristos 		if (utf_string == NULL) {
756723e4046Schristos 			result = TSPERR(TSS_E_INTERNAL_ERROR);
757723e4046Schristos 			goto done;
758723e4046Schristos 		}
759723e4046Schristos 
760723e4046Schristos 		*data = calloc_tspi(obj->tspContext, utf_size);
761723e4046Schristos 		if (*data == NULL) {
762723e4046Schristos 			free(utf_string);
763723e4046Schristos 			LogError("malloc of %d bytes failed.", utf_size);
764723e4046Schristos 			result = TSPERR(TSS_E_OUTOFMEMORY);
765723e4046Schristos 			goto done;
766723e4046Schristos 		}
767723e4046Schristos 
768723e4046Schristos 		*size = utf_size;
769723e4046Schristos 		memcpy(*data, utf_string, utf_size);
770723e4046Schristos 		free(utf_string);
771723e4046Schristos 	}
772723e4046Schristos 
773723e4046Schristos done:
774723e4046Schristos 	obj_list_put(&policy_list);
775723e4046Schristos 
776723e4046Schristos 	return result;
777723e4046Schristos }
778723e4046Schristos 
779723e4046Schristos TSS_RESULT
obj_policy_set_string(TSS_HPOLICY hPolicy,UINT32 size,BYTE * data)780723e4046Schristos obj_policy_set_string(TSS_HPOLICY hPolicy, UINT32 size, BYTE *data)
781723e4046Schristos {
782723e4046Schristos 	struct tsp_object *obj;
783723e4046Schristos 	struct tr_policy_obj *policy;
784723e4046Schristos 
785723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
786723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
787723e4046Schristos 
788723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
789723e4046Schristos 
790723e4046Schristos 	free(policy->popupString);
791723e4046Schristos 	policy->popupString = data;
792723e4046Schristos 	policy->popupStringLength = size;
793723e4046Schristos 
794723e4046Schristos 	obj_list_put(&policy_list);
795723e4046Schristos 
796723e4046Schristos 	return TSS_SUCCESS;
797723e4046Schristos }
798723e4046Schristos 
799723e4046Schristos TSS_RESULT
obj_policy_get_secs_until_expired(TSS_HPOLICY hPolicy,UINT32 * secs)800723e4046Schristos obj_policy_get_secs_until_expired(TSS_HPOLICY hPolicy, UINT32 *secs)
801723e4046Schristos {
802723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
803723e4046Schristos 	struct tsp_object *obj;
804723e4046Schristos 	struct tr_policy_obj *policy;
805723e4046Schristos 	int seconds_elapsed;
806723e4046Schristos 	time_t t;
807723e4046Schristos 
808723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
809723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
810723e4046Schristos 
811723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
812723e4046Schristos 
813723e4046Schristos 	if (policy->SecretLifetime != TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER) {
814723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
815723e4046Schristos 		goto done;
816723e4046Schristos 	}
817723e4046Schristos 
818723e4046Schristos 	if ((t = time(NULL)) == ((time_t)-1)) {
819723e4046Schristos 		LogError("time failed: %s", strerror(errno));
820723e4046Schristos 		result = TSPERR(TSS_E_INTERNAL_ERROR);
821723e4046Schristos 		goto done;
822723e4046Schristos 	}
823723e4046Schristos 	/* curtime - SecretTimeStamp is the number of seconds elapsed since we started the timer.
824723e4046Schristos 	 * SecretCounter is the number of seconds the secret is valid.  If
825723e4046Schristos 	 * seconds_elspased > SecretCounter, we've expired. */
826723e4046Schristos 	seconds_elapsed = t - policy->SecretTimeStamp;
827723e4046Schristos 	if ((UINT32)seconds_elapsed >= policy->SecretCounter) {
828723e4046Schristos 		*secs = 0;
829723e4046Schristos 	} else {
830723e4046Schristos 		*secs = policy->SecretCounter - seconds_elapsed;
831723e4046Schristos 	}
832723e4046Schristos 
833723e4046Schristos done:
834723e4046Schristos 	obj_list_put(&policy_list);
835723e4046Schristos 
836723e4046Schristos 	return result;
837723e4046Schristos }
838723e4046Schristos 
839723e4046Schristos TSS_RESULT
policy_has_expired(struct tr_policy_obj * policy,TSS_BOOL * answer)840723e4046Schristos policy_has_expired(struct tr_policy_obj *policy, TSS_BOOL *answer)
841723e4046Schristos {
842723e4046Schristos 	switch (policy->SecretLifetime) {
843723e4046Schristos 	case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_ALWAYS:
844723e4046Schristos 		*answer = FALSE;
845723e4046Schristos 		break;
846723e4046Schristos 	case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_COUNTER:
847723e4046Schristos 		*answer = (policy->SecretCounter == 0 ? TRUE : FALSE);
848723e4046Schristos 		break;
849723e4046Schristos 	case TSS_TSPATTRIB_POLICYSECRET_LIFETIME_TIMER:
850723e4046Schristos 	{
851723e4046Schristos 		int seconds_elapsed;
852723e4046Schristos 		time_t t = time(NULL);
853723e4046Schristos 
854723e4046Schristos 		if (t == ((time_t)-1)) {
855723e4046Schristos 			LogError("time failed: %s", strerror(errno));
856723e4046Schristos 			return TSPERR(TSS_E_INTERNAL_ERROR);
857723e4046Schristos 		}
858723e4046Schristos 		/* curtime - SecretTimer is the number of seconds elapsed since we
859723e4046Schristos 		 * started the timer. SecretCounter is the number of seconds the
860723e4046Schristos 		 * secret is valid.  If seconds_elspased > SecretCounter, we've
861723e4046Schristos 		 * expired.
862723e4046Schristos 		 */
863723e4046Schristos 		seconds_elapsed = t - policy->SecretTimeStamp;
864723e4046Schristos 		*answer = ((UINT32)seconds_elapsed >= policy->SecretCounter ? TRUE : FALSE);
865723e4046Schristos 		break;
866723e4046Schristos 	}
867723e4046Schristos 	default:
868723e4046Schristos 		LogError("policy has an undefined secret lifetime!");
869723e4046Schristos 		return TSPERR(TSS_E_INVALID_OBJ_ACCESS);
870723e4046Schristos 	}
871723e4046Schristos 
872723e4046Schristos 	return TSS_SUCCESS;
873723e4046Schristos }
874723e4046Schristos 
875723e4046Schristos TSS_RESULT
obj_policy_has_expired(TSS_HPOLICY hPolicy,TSS_BOOL * answer)876723e4046Schristos obj_policy_has_expired(TSS_HPOLICY hPolicy, TSS_BOOL *answer)
877723e4046Schristos {
878723e4046Schristos 	struct tsp_object *obj;
879723e4046Schristos 	struct tr_policy_obj *policy;
880723e4046Schristos 	TSS_RESULT result;
881723e4046Schristos 
882723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
883723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
884723e4046Schristos 
885723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
886723e4046Schristos 
887723e4046Schristos 	result = policy_has_expired(policy, answer);
888723e4046Schristos 
889723e4046Schristos 	obj_list_put(&policy_list);
890723e4046Schristos 
891723e4046Schristos 	return result;
892723e4046Schristos }
893723e4046Schristos 
894723e4046Schristos TSS_RESULT
obj_policy_get_xsap_params(TSS_HPOLICY hPolicy,TPM_COMMAND_CODE command,TPM_ENTITY_TYPE * et,UINT32 * entity_value_size,BYTE ** entity_value,BYTE * secret,TSS_CALLBACK * cb_xor,TSS_CALLBACK * cb_hmac,TSS_CALLBACK * cb_sealx,UINT32 * mode,TSS_BOOL new_secret)895723e4046Schristos obj_policy_get_xsap_params(TSS_HPOLICY hPolicy,
896723e4046Schristos 			   TPM_COMMAND_CODE command,
897723e4046Schristos 			   TPM_ENTITY_TYPE *et,
898723e4046Schristos 			   UINT32 *entity_value_size,
899723e4046Schristos 			   BYTE **entity_value,
900723e4046Schristos 			   BYTE *secret,
901723e4046Schristos 			   TSS_CALLBACK *cb_xor,
902723e4046Schristos 			   TSS_CALLBACK *cb_hmac,
903723e4046Schristos 			   TSS_CALLBACK *cb_sealx,
904723e4046Schristos 			   UINT32 *mode,
905723e4046Schristos 			   TSS_BOOL new_secret)
906723e4046Schristos {
907723e4046Schristos 	struct tsp_object *obj;
908723e4046Schristos 	struct tr_policy_obj *policy;
909723e4046Schristos 	TSS_RESULT result;
910723e4046Schristos 	TSS_BOOL answer = FALSE;
911723e4046Schristos 
912723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
913723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
914723e4046Schristos 
915723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
916723e4046Schristos 
917723e4046Schristos 	if ((result = policy_has_expired(policy, &answer)))
918723e4046Schristos 		goto done;
919723e4046Schristos 
920723e4046Schristos 	if (answer) {
921723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
922723e4046Schristos 		goto done;
923723e4046Schristos 	}
924723e4046Schristos #ifdef TSS_BUILD_DELEGATION
925723e4046Schristos 	/* if the delegation index or blob is set, check to see if the command is delegated, if so,
926723e4046Schristos 	 * return the blob or index as the secret data */
927723e4046Schristos 	if (command && (policy->delegationType != TSS_DELEGATIONTYPE_NONE)) {
928723e4046Schristos 		if (policy->delegationBlob) {
929723e4046Schristos 			if ((*entity_value = malloc(policy->delegationBlobLength)) == NULL) {
930723e4046Schristos 				LogError("malloc of %u bytes failed.",
931723e4046Schristos 					 policy->delegationBlobLength);
932723e4046Schristos 				result = TSPERR(TSS_E_OUTOFMEMORY);
933723e4046Schristos 				goto done;
934723e4046Schristos 			}
935723e4046Schristos 
936723e4046Schristos 			memcpy(*entity_value, policy->delegationBlob, policy->delegationBlobLength);
937723e4046Schristos 			*entity_value_size = policy->delegationBlobLength;
938723e4046Schristos 			if (policy->delegationType == TSS_DELEGATIONTYPE_OWNER)
939723e4046Schristos 				*et = TPM_ET_DEL_OWNER_BLOB;
940723e4046Schristos 			else
941723e4046Schristos 				*et = TPM_ET_DEL_KEY_BLOB;
942723e4046Schristos 		} else {
943723e4046Schristos 			if ((*entity_value = malloc(sizeof(UINT32))) == NULL) {
944723e4046Schristos 				LogError("malloc of %zd bytes failed.", sizeof(UINT32));
945723e4046Schristos 				result = TSPERR(TSS_E_OUTOFMEMORY);
946723e4046Schristos 				goto done;
947723e4046Schristos 			}
948723e4046Schristos 
949723e4046Schristos 			*(UINT32 *)entity_value = policy->delegationIndex;
950723e4046Schristos 			*entity_value_size = sizeof(UINT32);
951723e4046Schristos 			*et = TPM_ET_DEL_ROW;
952723e4046Schristos 		}
953723e4046Schristos 	}
954723e4046Schristos #endif
955723e4046Schristos 	/* Either this is a policy set to mode callback, in which case both xor and hmac addresses
956723e4046Schristos 	 * must be set, or this is an encrypted data object's policy, where its mode is independent
957723e4046Schristos 	 * of whether a sealx callback is set */
958723e4046Schristos 	if (policy->SecretMode == TSS_SECRET_MODE_CALLBACK && cb_xor && cb_hmac) {
959723e4046Schristos 		if ((policy->Tspicb_CallbackXorEnc && !policy->Tspicb_CallbackHMACAuth) ||
960723e4046Schristos 		    (!policy->Tspicb_CallbackXorEnc && policy->Tspicb_CallbackHMACAuth)) {
961723e4046Schristos 			result = TSPERR(TSS_E_INTERNAL_ERROR);
962723e4046Schristos 			goto done;
963723e4046Schristos 		}
964723e4046Schristos 
965723e4046Schristos 		cb_xor->callback = policy->Tspicb_CallbackXorEnc;
966723e4046Schristos 		cb_xor->appData = policy->xorAppData;
967723e4046Schristos 		cb_xor->alg = policy->xorAlg;
968723e4046Schristos 
969723e4046Schristos 		cb_hmac->callback = policy->Tspicb_CallbackHMACAuth;
970723e4046Schristos 		cb_hmac->appData = policy->hmacAppData;
971723e4046Schristos 		cb_hmac->alg = policy->hmacAlg;
972723e4046Schristos #ifdef TSS_BUILD_SEALX
973723e4046Schristos 	} else if (cb_sealx && policy->Tspicb_CallbackSealxMask) {
974723e4046Schristos 		cb_sealx->callback = policy->Tspicb_CallbackSealxMask;
975723e4046Schristos 		cb_sealx->appData = policy->sealxAppData;
976723e4046Schristos 		cb_sealx->alg = policy->sealxAlg;
977723e4046Schristos #endif
978723e4046Schristos 	}
979723e4046Schristos 
980723e4046Schristos 	if ((policy->SecretMode == TSS_SECRET_MODE_POPUP) &&
981723e4046Schristos 	    (policy->SecretSet == FALSE)) {
982723e4046Schristos 		if ((result = popup_GetSecret(new_secret,
983723e4046Schristos 					      policy->hashMode,
984723e4046Schristos 					      policy->popupString,
985723e4046Schristos 					      policy->Secret)))
986723e4046Schristos 			goto done;
987723e4046Schristos 			policy->SecretSet = TRUE;
988723e4046Schristos 	}
989723e4046Schristos 	memcpy(secret, policy->Secret, TPM_SHA1_160_HASH_LEN);
990723e4046Schristos 	*mode = policy->SecretMode;
991723e4046Schristos done:
992723e4046Schristos 	obj_list_put(&policy_list);
993723e4046Schristos 
994723e4046Schristos 	return result;
995723e4046Schristos }
996723e4046Schristos 
997723e4046Schristos TSS_RESULT
obj_policy_do_xor(TSS_HPOLICY hPolicy,TSS_HOBJECT hOSAPObject,TSS_HOBJECT hObject,TSS_FLAG PurposeSecret,UINT32 ulSizeNonces,BYTE * rgbNonceEven,BYTE * rgbNonceOdd,BYTE * rgbNonceEvenOSAP,BYTE * rgbNonceOddOSAP,UINT32 ulSizeEncAuth,BYTE * rgbEncAuthUsage,BYTE * rgbEncAuthMigration)998723e4046Schristos obj_policy_do_xor(TSS_HPOLICY hPolicy,
999723e4046Schristos 		  TSS_HOBJECT hOSAPObject, TSS_HOBJECT hObject,
1000723e4046Schristos 		  TSS_FLAG PurposeSecret, UINT32 ulSizeNonces,
1001723e4046Schristos 		  BYTE *rgbNonceEven, BYTE *rgbNonceOdd,
1002723e4046Schristos 		  BYTE *rgbNonceEvenOSAP, BYTE *rgbNonceOddOSAP,
1003723e4046Schristos 		  UINT32 ulSizeEncAuth, BYTE *rgbEncAuthUsage,
1004723e4046Schristos 		  BYTE *rgbEncAuthMigration)
1005723e4046Schristos {
1006723e4046Schristos 	TSS_RESULT result;
1007723e4046Schristos 	struct tsp_object *obj;
1008723e4046Schristos 	struct tr_policy_obj *policy;
1009723e4046Schristos 
1010723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1011723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1012723e4046Schristos 
1013723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1014723e4046Schristos 
1015723e4046Schristos 	result = policy->Tspicb_CallbackXorEnc(policy->xorAppData,
1016723e4046Schristos 			hOSAPObject, hObject,
1017723e4046Schristos 			PurposeSecret, ulSizeNonces,
1018723e4046Schristos 			rgbNonceEven, rgbNonceOdd,
1019723e4046Schristos 			rgbNonceEvenOSAP, rgbNonceOddOSAP,
1020723e4046Schristos 			ulSizeEncAuth,
1021723e4046Schristos 			rgbEncAuthUsage, rgbEncAuthMigration);
1022723e4046Schristos 
1023723e4046Schristos 	obj_list_put(&policy_list);
1024723e4046Schristos 
1025723e4046Schristos 	return result;
1026723e4046Schristos }
1027723e4046Schristos 
1028723e4046Schristos TSS_RESULT
obj_policy_do_takeowner(TSS_HPOLICY hPolicy,TSS_HOBJECT hObject,TSS_HKEY hObjectPubKey,UINT32 ulSizeEncAuth,BYTE * rgbEncAuth)1029723e4046Schristos obj_policy_do_takeowner(TSS_HPOLICY hPolicy,
1030723e4046Schristos 			TSS_HOBJECT hObject, TSS_HKEY hObjectPubKey,
1031723e4046Schristos 			UINT32 ulSizeEncAuth, BYTE *rgbEncAuth)
1032723e4046Schristos {
1033723e4046Schristos 	TSS_RESULT result;
1034723e4046Schristos 	struct tsp_object *obj;
1035723e4046Schristos 	struct tr_policy_obj *policy;
1036723e4046Schristos 
1037723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1038723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1039723e4046Schristos 
1040723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1041723e4046Schristos 
1042723e4046Schristos 	result = policy->Tspicb_CallbackTakeOwnership(
1043723e4046Schristos 			policy->takeownerAppData,
1044723e4046Schristos 			hObject, hObjectPubKey, ulSizeEncAuth,
1045723e4046Schristos 			rgbEncAuth);
1046723e4046Schristos 
1047723e4046Schristos 	obj_list_put(&policy_list);
1048723e4046Schristos 
1049723e4046Schristos 	return result;
1050723e4046Schristos }
1051723e4046Schristos 
1052723e4046Schristos TSS_RESULT
obj_policy_get_hash_mode(TSS_HPOLICY hPolicy,UINT32 * mode)1053723e4046Schristos obj_policy_get_hash_mode(TSS_HPOLICY hPolicy, UINT32 *mode)
1054723e4046Schristos {
1055723e4046Schristos 	struct tsp_object *obj;
1056723e4046Schristos 	struct tr_policy_obj *policy;
1057723e4046Schristos 
1058723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1059723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1060723e4046Schristos 
1061723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1062723e4046Schristos 	*mode = policy->hashMode;
1063723e4046Schristos 
1064723e4046Schristos 	obj_list_put(&policy_list);
1065723e4046Schristos 
1066723e4046Schristos 	return TSS_SUCCESS;
1067723e4046Schristos }
1068723e4046Schristos 
1069723e4046Schristos TSS_RESULT
obj_policy_set_hash_mode(TSS_HPOLICY hPolicy,UINT32 mode)1070723e4046Schristos obj_policy_set_hash_mode(TSS_HPOLICY hPolicy, UINT32 mode)
1071723e4046Schristos {
1072723e4046Schristos 	struct tsp_object *obj;
1073723e4046Schristos 	struct tr_policy_obj *policy;
1074723e4046Schristos 
1075723e4046Schristos 	switch (mode) {
1076723e4046Schristos 		case TSS_TSPATTRIB_HASH_MODE_NULL:
1077723e4046Schristos 		case TSS_TSPATTRIB_HASH_MODE_NOT_NULL:
1078723e4046Schristos 			break;
1079723e4046Schristos 		default:
1080723e4046Schristos 			return TSPERR(TSS_E_INVALID_ATTRIB_DATA);
1081723e4046Schristos 	}
1082723e4046Schristos 
1083723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1084723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1085723e4046Schristos 
1086723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1087723e4046Schristos 	policy->hashMode = mode;
1088723e4046Schristos 
1089723e4046Schristos 	obj_list_put(&policy_list);
1090723e4046Schristos 
1091723e4046Schristos 	return TSS_SUCCESS;
1092723e4046Schristos }
1093723e4046Schristos 
1094723e4046Schristos #ifdef TSS_BUILD_DELEGATION
1095723e4046Schristos TSS_RESULT
obj_policy_set_delegation_type(TSS_HPOLICY hPolicy,UINT32 type)1096723e4046Schristos obj_policy_set_delegation_type(TSS_HPOLICY hPolicy, UINT32 type)
1097723e4046Schristos {
1098723e4046Schristos 	struct tsp_object *obj;
1099723e4046Schristos 	struct tr_policy_obj *policy;
1100723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1101723e4046Schristos 
1102723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1103723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1104723e4046Schristos 
1105723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1106723e4046Schristos 
1107723e4046Schristos 	switch (type) {
1108723e4046Schristos 	case TSS_DELEGATIONTYPE_NONE:
1109723e4046Schristos 		obj_policy_clear_delegation(policy);
1110723e4046Schristos 		break;
1111723e4046Schristos 	case TSS_DELEGATIONTYPE_OWNER:
1112723e4046Schristos 	case TSS_DELEGATIONTYPE_KEY:
1113723e4046Schristos 		if (policy->delegationIndexSet || policy->delegationBlob) {
1114723e4046Schristos 			result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1115723e4046Schristos 			goto done;
1116723e4046Schristos 		}
1117723e4046Schristos 		break;
1118723e4046Schristos 	}
1119723e4046Schristos 
1120723e4046Schristos 	policy->delegationType = type;
1121723e4046Schristos 
1122723e4046Schristos done:
1123723e4046Schristos 	obj_list_put(&policy_list);
1124723e4046Schristos 
1125723e4046Schristos 	return result;
1126723e4046Schristos }
1127723e4046Schristos 
1128723e4046Schristos 
1129723e4046Schristos TSS_RESULT
obj_policy_get_delegation_type(TSS_HPOLICY hPolicy,UINT32 * type)1130723e4046Schristos obj_policy_get_delegation_type(TSS_HPOLICY hPolicy, UINT32 *type)
1131723e4046Schristos {
1132723e4046Schristos 	struct tsp_object *obj;
1133723e4046Schristos 	struct tr_policy_obj *policy;
1134723e4046Schristos 
1135723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1136723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1137723e4046Schristos 
1138723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1139723e4046Schristos 
1140723e4046Schristos 	*type = policy->delegationType;
1141723e4046Schristos 
1142723e4046Schristos 	obj_list_put(&policy_list);
1143723e4046Schristos 
1144723e4046Schristos 	return TSS_SUCCESS;
1145723e4046Schristos }
1146723e4046Schristos 
1147723e4046Schristos TSS_RESULT
obj_policy_set_delegation_index(TSS_HPOLICY hPolicy,UINT32 index)1148723e4046Schristos obj_policy_set_delegation_index(TSS_HPOLICY hPolicy, UINT32 index)
1149723e4046Schristos {
1150723e4046Schristos 	struct tsp_object *obj;
1151723e4046Schristos 	struct tr_policy_obj *policy;
1152723e4046Schristos 	TPM_DELEGATE_PUBLIC public;
1153723e4046Schristos 	TSS_RESULT result;
1154723e4046Schristos 
1155723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1156723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1157723e4046Schristos 
1158723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1159723e4046Schristos 
1160723e4046Schristos 	if ((result = get_delegate_index(obj->tspContext, index, &public)))
1161723e4046Schristos 		goto done;
1162723e4046Schristos 
1163723e4046Schristos 	free(public.pcrInfo.pcrSelection.pcrSelect);
1164723e4046Schristos 
1165723e4046Schristos 	obj_policy_clear_delegation(policy);
1166723e4046Schristos 	switch (public.permissions.delegateType) {
1167723e4046Schristos 	case TPM_DEL_OWNER_BITS:
1168723e4046Schristos 		policy->delegationType = TSS_DELEGATIONTYPE_OWNER;
1169723e4046Schristos 		break;
1170723e4046Schristos 	case TPM_DEL_KEY_BITS:
1171723e4046Schristos 		policy->delegationType = TSS_DELEGATIONTYPE_KEY;
1172723e4046Schristos 		break;
1173723e4046Schristos 	default:
1174723e4046Schristos 		result = TSPERR(TSS_E_BAD_PARAMETER);
1175723e4046Schristos 		goto done;
1176723e4046Schristos 	}
1177723e4046Schristos 	policy->delegationIndex = index;
1178723e4046Schristos 	policy->delegationIndexSet = TRUE;
1179723e4046Schristos 
1180723e4046Schristos done:
1181723e4046Schristos 	obj_list_put(&policy_list);
1182723e4046Schristos 
1183723e4046Schristos 	return result;
1184723e4046Schristos }
1185723e4046Schristos 
1186723e4046Schristos TSS_RESULT
obj_policy_get_delegation_index(TSS_HPOLICY hPolicy,UINT32 * index)1187723e4046Schristos obj_policy_get_delegation_index(TSS_HPOLICY hPolicy, UINT32 *index)
1188723e4046Schristos {
1189723e4046Schristos 	struct tsp_object *obj;
1190723e4046Schristos 	struct tr_policy_obj *policy;
1191723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1192723e4046Schristos 
1193723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1194723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1195723e4046Schristos 
1196723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1197723e4046Schristos 
1198723e4046Schristos 	if (!policy->delegationIndexSet) {
1199723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1200723e4046Schristos 		goto done;
1201723e4046Schristos 	}
1202723e4046Schristos 
1203723e4046Schristos 	*index = policy->delegationIndex;
1204723e4046Schristos 
1205723e4046Schristos done:
1206723e4046Schristos 	obj_list_put(&policy_list);
1207723e4046Schristos 
1208723e4046Schristos 	return result;
1209723e4046Schristos }
1210723e4046Schristos 
obj_policy_set_delegation_per1(TSS_HPOLICY hPolicy,UINT32 per1)1211723e4046Schristos TSS_RESULT obj_policy_set_delegation_per1(TSS_HPOLICY hPolicy, UINT32 per1)
1212723e4046Schristos {
1213723e4046Schristos 	struct tsp_object *obj;
1214723e4046Schristos 	struct tr_policy_obj *policy;
1215723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1216723e4046Schristos 
1217723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1218723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1219723e4046Schristos 
1220723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1221723e4046Schristos 
1222723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1223723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1224723e4046Schristos 		goto done;
1225723e4046Schristos 	}
1226723e4046Schristos 
1227723e4046Schristos 	policy->delegationPer1 = per1;
1228723e4046Schristos 
1229723e4046Schristos done:
1230723e4046Schristos 	obj_list_put(&policy_list);
1231723e4046Schristos 
1232723e4046Schristos 	return result;
1233723e4046Schristos }
1234723e4046Schristos 
obj_policy_get_delegation_per1(TSS_HPOLICY hPolicy,UINT32 * per1)1235723e4046Schristos TSS_RESULT obj_policy_get_delegation_per1(TSS_HPOLICY hPolicy, UINT32 *per1)
1236723e4046Schristos {
1237723e4046Schristos 	struct tsp_object *obj;
1238723e4046Schristos 	struct tr_policy_obj *policy;
1239723e4046Schristos 	TPM_DELEGATE_PUBLIC public;
1240723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1241723e4046Schristos 
1242723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1243723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1244723e4046Schristos 
1245723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1246723e4046Schristos 
1247723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1248723e4046Schristos 		if ((result = obj_policy_get_delegate_public(obj, &public)))
1249723e4046Schristos 			goto done;
1250723e4046Schristos 		*per1 = public.permissions.per1;
1251723e4046Schristos 		free(public.pcrInfo.pcrSelection.pcrSelect);
1252723e4046Schristos 	} else
1253723e4046Schristos 		*per1 = policy->delegationPer1;
1254723e4046Schristos 
1255723e4046Schristos done:
1256723e4046Schristos 	obj_list_put(&policy_list);
1257723e4046Schristos 
1258723e4046Schristos 	return result;
1259723e4046Schristos }
1260723e4046Schristos 
obj_policy_set_delegation_per2(TSS_HPOLICY hPolicy,UINT32 per2)1261723e4046Schristos TSS_RESULT obj_policy_set_delegation_per2(TSS_HPOLICY hPolicy, UINT32 per2)
1262723e4046Schristos {
1263723e4046Schristos 	struct tsp_object *obj;
1264723e4046Schristos 	struct tr_policy_obj *policy;
1265723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1266723e4046Schristos 
1267723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1268723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1269723e4046Schristos 
1270723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1271723e4046Schristos 
1272723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1273723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1274723e4046Schristos 		goto done;
1275723e4046Schristos 	}
1276723e4046Schristos 
1277723e4046Schristos 	policy->delegationPer2 = per2;
1278723e4046Schristos 
1279723e4046Schristos done:
1280723e4046Schristos 	obj_list_put(&policy_list);
1281723e4046Schristos 
1282723e4046Schristos 	return result;
1283723e4046Schristos }
1284723e4046Schristos 
obj_policy_get_delegation_per2(TSS_HPOLICY hPolicy,UINT32 * per2)1285723e4046Schristos TSS_RESULT obj_policy_get_delegation_per2(TSS_HPOLICY hPolicy, UINT32 *per2)
1286723e4046Schristos {
1287723e4046Schristos 	struct tsp_object *obj;
1288723e4046Schristos 	struct tr_policy_obj *policy;
1289723e4046Schristos 	TPM_DELEGATE_PUBLIC public;
1290723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1291723e4046Schristos 
1292723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1293723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1294723e4046Schristos 
1295723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1296723e4046Schristos 
1297723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1298723e4046Schristos 		if ((result = obj_policy_get_delegate_public(obj, &public)))
1299723e4046Schristos 			goto done;
1300723e4046Schristos 		*per2 = public.permissions.per2;
1301723e4046Schristos 		free(public.pcrInfo.pcrSelection.pcrSelect);
1302723e4046Schristos 	} else
1303723e4046Schristos 		*per2 = policy->delegationPer2;
1304723e4046Schristos 
1305723e4046Schristos done:
1306723e4046Schristos 	obj_list_put(&policy_list);
1307723e4046Schristos 
1308723e4046Schristos 	return result;
1309723e4046Schristos }
1310723e4046Schristos 
1311723e4046Schristos TSS_RESULT
obj_policy_set_delegation_blob(TSS_HPOLICY hPolicy,UINT32 type,UINT32 blobLength,BYTE * blob)1312723e4046Schristos obj_policy_set_delegation_blob(TSS_HPOLICY hPolicy, UINT32 type, UINT32 blobLength, BYTE *blob)
1313723e4046Schristos {
1314723e4046Schristos 	struct tsp_object *obj;
1315723e4046Schristos 	struct tr_policy_obj *policy;
1316723e4046Schristos 	UINT16 tag;
1317723e4046Schristos 	UINT64 offset;
1318723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1319723e4046Schristos 
1320723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1321723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1322723e4046Schristos 
1323723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1324723e4046Schristos 
1325723e4046Schristos 	obj_policy_clear_delegation(policy);
1326723e4046Schristos 
1327723e4046Schristos 	if (blobLength == 0) {
1328723e4046Schristos 		result = TSPERR(TSS_E_BAD_PARAMETER);
1329723e4046Schristos 		goto done;
1330723e4046Schristos 	}
1331723e4046Schristos 
1332723e4046Schristos 	offset = 0;
1333723e4046Schristos 	Trspi_UnloadBlob_UINT16(&offset, &tag, blob);
1334723e4046Schristos 	switch (tag) {
1335723e4046Schristos 	case TPM_TAG_DELEGATE_OWNER_BLOB:
1336723e4046Schristos 		if (type && (type != TSS_DELEGATIONTYPE_OWNER)) {
1337723e4046Schristos 			result = TSPERR(TSS_E_BAD_PARAMETER);
1338723e4046Schristos 			goto done;
1339723e4046Schristos 		}
1340723e4046Schristos 		policy->delegationType = TSS_DELEGATIONTYPE_OWNER;
1341723e4046Schristos 		break;
1342723e4046Schristos 	case TPM_TAG_DELG_KEY_BLOB:
1343723e4046Schristos 		if (type && (type != TSS_DELEGATIONTYPE_KEY)) {
1344723e4046Schristos 			result = TSPERR(TSS_E_BAD_PARAMETER);
1345723e4046Schristos 			goto done;
1346723e4046Schristos 		}
1347723e4046Schristos 		policy->delegationType = TSS_DELEGATIONTYPE_KEY;
1348723e4046Schristos 		break;
1349723e4046Schristos 	default:
1350723e4046Schristos 		result = TSPERR(TSS_E_BAD_PARAMETER);
1351723e4046Schristos 		goto done;
1352723e4046Schristos 	}
1353723e4046Schristos 
1354723e4046Schristos 	if ((policy->delegationBlob = malloc(blobLength)) == NULL) {
1355723e4046Schristos 		LogError("malloc of %u bytes failed.", blobLength);
1356723e4046Schristos 		result = TSPERR(TSS_E_OUTOFMEMORY);
1357723e4046Schristos 		goto done;
1358723e4046Schristos 	}
1359723e4046Schristos 
1360723e4046Schristos 	policy->delegationBlobLength = blobLength;
1361723e4046Schristos 	memcpy(policy->delegationBlob, blob, blobLength);
1362723e4046Schristos 
1363723e4046Schristos done:
1364723e4046Schristos 	obj_list_put(&policy_list);
1365723e4046Schristos 
1366723e4046Schristos 	return result;
1367723e4046Schristos }
1368723e4046Schristos 
1369723e4046Schristos TSS_RESULT
obj_policy_get_delegation_blob(TSS_HPOLICY hPolicy,UINT32 type,UINT32 * blobLength,BYTE ** blob)1370723e4046Schristos obj_policy_get_delegation_blob(TSS_HPOLICY hPolicy, UINT32 type, UINT32 *blobLength, BYTE **blob)
1371723e4046Schristos {
1372723e4046Schristos 	struct tsp_object *obj;
1373723e4046Schristos 	struct tr_policy_obj *policy;
1374723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1375723e4046Schristos 
1376723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1377723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1378723e4046Schristos 
1379723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1380723e4046Schristos 
1381723e4046Schristos 	if (policy->delegationBlobLength == 0) {
1382723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1383723e4046Schristos 		goto done;
1384723e4046Schristos 	}
1385723e4046Schristos 
1386723e4046Schristos 	if (type && (type != policy->delegationType)) {
1387723e4046Schristos 		result = TSPERR(TSS_E_BAD_PARAMETER);
1388723e4046Schristos 		goto done;
1389723e4046Schristos 	}
1390723e4046Schristos 
1391723e4046Schristos 	if ((*blob = calloc_tspi(obj->tspContext, policy->delegationBlobLength)) == NULL) {
1392723e4046Schristos 		LogError("malloc of %u bytes failed.", policy->delegationBlobLength);
1393723e4046Schristos 		result = TSPERR(TSS_E_OUTOFMEMORY);
1394723e4046Schristos 		goto done;
1395723e4046Schristos 	}
1396723e4046Schristos 
1397723e4046Schristos 	memcpy(*blob, policy->delegationBlob, policy->delegationBlobLength);
1398723e4046Schristos 	*blobLength = policy->delegationBlobLength;
1399723e4046Schristos 
1400723e4046Schristos done:
1401723e4046Schristos 	obj_list_put(&policy_list);
1402723e4046Schristos 
1403723e4046Schristos 	return result;
1404723e4046Schristos }
1405723e4046Schristos 
1406723e4046Schristos TSS_RESULT
obj_policy_get_delegation_label(TSS_HPOLICY hPolicy,BYTE * label)1407723e4046Schristos obj_policy_get_delegation_label(TSS_HPOLICY hPolicy, BYTE *label)
1408723e4046Schristos {
1409723e4046Schristos 	struct tsp_object *obj;
1410723e4046Schristos 	struct tr_policy_obj *policy;
1411723e4046Schristos 	TPM_DELEGATE_PUBLIC public;
1412723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1413723e4046Schristos 
1414723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1415723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1416723e4046Schristos 
1417723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1418723e4046Schristos 
1419723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1420723e4046Schristos 		if ((result = obj_policy_get_delegate_public(obj, &public)))
1421723e4046Schristos 			goto done;
1422723e4046Schristos 		*label = public.label.label;
1423723e4046Schristos 		free(public.pcrInfo.pcrSelection.pcrSelect);
1424723e4046Schristos 	} else
1425723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1426723e4046Schristos 
1427723e4046Schristos done:
1428723e4046Schristos 	obj_list_put(&policy_list);
1429723e4046Schristos 
1430723e4046Schristos 	return result;
1431723e4046Schristos }
1432723e4046Schristos 
1433723e4046Schristos TSS_RESULT
obj_policy_get_delegation_familyid(TSS_HPOLICY hPolicy,UINT32 * familyID)1434723e4046Schristos obj_policy_get_delegation_familyid(TSS_HPOLICY hPolicy, UINT32 *familyID)
1435723e4046Schristos {
1436723e4046Schristos 	struct tsp_object *obj;
1437723e4046Schristos 	struct tr_policy_obj *policy;
1438723e4046Schristos 	TPM_DELEGATE_PUBLIC public;
1439723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1440723e4046Schristos 
1441723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1442723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1443723e4046Schristos 
1444723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1445723e4046Schristos 
1446723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1447723e4046Schristos 		if ((result = obj_policy_get_delegate_public(obj, &public)))
1448723e4046Schristos 			goto done;
1449723e4046Schristos 		*familyID = public.familyID;
1450723e4046Schristos 		free(public.pcrInfo.pcrSelection.pcrSelect);
1451723e4046Schristos 	} else
1452723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1453723e4046Schristos 
1454723e4046Schristos done:
1455723e4046Schristos 	obj_list_put(&policy_list);
1456723e4046Schristos 
1457723e4046Schristos 	return result;
1458723e4046Schristos }
1459723e4046Schristos 
1460723e4046Schristos TSS_RESULT
obj_policy_get_delegation_vercount(TSS_HPOLICY hPolicy,UINT32 * verCount)1461723e4046Schristos obj_policy_get_delegation_vercount(TSS_HPOLICY hPolicy, UINT32 *verCount)
1462723e4046Schristos {
1463723e4046Schristos 	struct tsp_object *obj;
1464723e4046Schristos 	struct tr_policy_obj *policy;
1465723e4046Schristos 	TPM_DELEGATE_PUBLIC public;
1466723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1467723e4046Schristos 
1468723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1469723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1470723e4046Schristos 
1471723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1472723e4046Schristos 
1473723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1474723e4046Schristos 		if ((result = obj_policy_get_delegate_public(obj, &public)))
1475723e4046Schristos 			goto done;
1476723e4046Schristos 		*verCount = public.verificationCount;
1477723e4046Schristos 		free(public.pcrInfo.pcrSelection.pcrSelect);
1478723e4046Schristos 	} else
1479723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1480723e4046Schristos 
1481723e4046Schristos done:
1482723e4046Schristos 	obj_list_put(&policy_list);
1483723e4046Schristos 
1484723e4046Schristos 	return result;
1485723e4046Schristos }
1486723e4046Schristos 
1487723e4046Schristos TSS_RESULT
obj_policy_get_delegation_pcr_locality(TSS_HPOLICY hPolicy,UINT32 * locality)1488723e4046Schristos obj_policy_get_delegation_pcr_locality(TSS_HPOLICY hPolicy, UINT32 *locality)
1489723e4046Schristos {
1490723e4046Schristos 	struct tsp_object *obj;
1491723e4046Schristos 	struct tr_policy_obj *policy;
1492723e4046Schristos 	TPM_DELEGATE_PUBLIC public;
1493723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1494723e4046Schristos 
1495723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1496723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1497723e4046Schristos 
1498723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1499723e4046Schristos 
1500723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1501723e4046Schristos 		if ((result = obj_policy_get_delegate_public(obj, &public)))
1502723e4046Schristos 			goto done;
1503723e4046Schristos 		*locality = public.pcrInfo.localityAtRelease;
1504723e4046Schristos 		free(public.pcrInfo.pcrSelection.pcrSelect);
1505723e4046Schristos 	} else
1506723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1507723e4046Schristos 
1508723e4046Schristos done:
1509723e4046Schristos 	obj_list_put(&policy_list);
1510723e4046Schristos 
1511723e4046Schristos 	return result;
1512723e4046Schristos }
1513723e4046Schristos 
1514723e4046Schristos TSS_RESULT
obj_policy_get_delegation_pcr_digest(TSS_HPOLICY hPolicy,UINT32 * digestLength,BYTE ** digest)1515723e4046Schristos obj_policy_get_delegation_pcr_digest(TSS_HPOLICY hPolicy, UINT32 *digestLength, BYTE **digest)
1516723e4046Schristos {
1517723e4046Schristos 	struct tsp_object *obj;
1518723e4046Schristos 	struct tr_policy_obj *policy;
1519723e4046Schristos 	TPM_DELEGATE_PUBLIC public;
1520723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1521723e4046Schristos 
1522723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1523723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1524723e4046Schristos 
1525723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1526723e4046Schristos 
1527723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1528723e4046Schristos 		if ((result = obj_policy_get_delegate_public(obj, &public)))
1529723e4046Schristos 			goto done;
1530723e4046Schristos 		*digest = calloc_tspi(obj->tspContext, TPM_SHA1_160_HASH_LEN);
1531723e4046Schristos 		if (*digest == NULL) {
1532723e4046Schristos 			LogError("malloc of %u bytes failed.", TPM_SHA1_160_HASH_LEN);
1533723e4046Schristos 			result = TSPERR(TSS_E_OUTOFMEMORY);
1534723e4046Schristos 			goto done;
1535723e4046Schristos 		}
1536723e4046Schristos 		memcpy(*digest, &public.pcrInfo.digestAtRelease.digest, TPM_SHA1_160_HASH_LEN);
1537723e4046Schristos 		*digestLength = TPM_SHA1_160_HASH_LEN;
1538723e4046Schristos 		free(public.pcrInfo.pcrSelection.pcrSelect);
1539723e4046Schristos 	} else
1540723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1541723e4046Schristos 
1542723e4046Schristos done:
1543723e4046Schristos 	obj_list_put(&policy_list);
1544723e4046Schristos 
1545723e4046Schristos 	return result;
1546723e4046Schristos }
1547723e4046Schristos 
1548723e4046Schristos TSS_RESULT
obj_policy_get_delegation_pcr_selection(TSS_HPOLICY hPolicy,UINT32 * selectionLength,BYTE ** selection)1549723e4046Schristos obj_policy_get_delegation_pcr_selection(TSS_HPOLICY hPolicy, UINT32 *selectionLength,
1550723e4046Schristos 					BYTE **selection)
1551723e4046Schristos {
1552723e4046Schristos 	struct tsp_object *obj;
1553723e4046Schristos 	struct tr_policy_obj *policy;
1554723e4046Schristos 	TPM_DELEGATE_PUBLIC public;
1555723e4046Schristos 	UINT64 offset;
1556723e4046Schristos 	TSS_RESULT result = TSS_SUCCESS;
1557723e4046Schristos 
1558723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1559723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1560723e4046Schristos 
1561723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1562723e4046Schristos 
1563723e4046Schristos 	if (policy->delegationIndexSet || policy->delegationBlob) {
1564723e4046Schristos 		if ((result = obj_policy_get_delegate_public(obj, &public)))
1565723e4046Schristos 			goto done;
1566723e4046Schristos 		offset = 0;
1567723e4046Schristos 		Trspi_LoadBlob_PCR_SELECTION(&offset, NULL, &public.pcrInfo.pcrSelection);
1568723e4046Schristos 		*selection = calloc_tspi(obj->tspContext, offset);
1569723e4046Schristos 		if (*selection == NULL) {
1570723e4046Schristos 			LogError("malloc of %u bytes failed.", (UINT32)offset);
1571723e4046Schristos 			result = TSPERR(TSS_E_OUTOFMEMORY);
1572723e4046Schristos 			goto done;
1573723e4046Schristos 		}
1574723e4046Schristos 		offset = 0;
1575723e4046Schristos 		Trspi_LoadBlob_PCR_SELECTION(&offset, *selection, &public.pcrInfo.pcrSelection);
1576723e4046Schristos 		*selectionLength = offset;
1577723e4046Schristos 		free(public.pcrInfo.pcrSelection.pcrSelect);
1578723e4046Schristos 	} else
1579723e4046Schristos 		result = TSPERR(TSS_E_INVALID_OBJ_ACCESS);
1580723e4046Schristos 
1581723e4046Schristos done:
1582723e4046Schristos 	obj_list_put(&policy_list);
1583723e4046Schristos 
1584723e4046Schristos 	return result;
1585723e4046Schristos }
1586723e4046Schristos 
1587723e4046Schristos TSS_RESULT
obj_policy_is_delegation_index_set(TSS_HPOLICY hPolicy,TSS_BOOL * indexSet)1588723e4046Schristos obj_policy_is_delegation_index_set(TSS_HPOLICY hPolicy, TSS_BOOL *indexSet)
1589723e4046Schristos {
1590723e4046Schristos 	struct tsp_object *obj;
1591723e4046Schristos 	struct tr_policy_obj *policy;
1592723e4046Schristos 
1593723e4046Schristos 	if ((obj = obj_list_get_obj(&policy_list, hPolicy)) == NULL)
1594723e4046Schristos 		return TSPERR(TSS_E_INVALID_HANDLE);
1595723e4046Schristos 
1596723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1597723e4046Schristos 
1598723e4046Schristos 	*indexSet = policy->delegationIndexSet;
1599723e4046Schristos 
1600723e4046Schristos 	obj_list_put(&policy_list);
1601723e4046Schristos 
1602723e4046Schristos 	return TSS_SUCCESS;
1603723e4046Schristos }
1604723e4046Schristos 
1605723e4046Schristos void
obj_policy_clear_delegation(struct tr_policy_obj * policy)1606723e4046Schristos obj_policy_clear_delegation(struct tr_policy_obj *policy)
1607723e4046Schristos {
1608723e4046Schristos 	free(policy->delegationBlob);
1609723e4046Schristos 	policy->delegationType = TSS_DELEGATIONTYPE_NONE;
1610723e4046Schristos 	policy->delegationPer1 = 0;
1611723e4046Schristos 	policy->delegationPer2 = 0;
1612723e4046Schristos 	policy->delegationIndexSet = FALSE;
1613723e4046Schristos 	policy->delegationIndex = 0;
1614723e4046Schristos 	policy->delegationBlobLength = 0;
1615723e4046Schristos 	policy->delegationBlob = NULL;
1616723e4046Schristos }
1617723e4046Schristos 
1618723e4046Schristos TSS_RESULT
obj_policy_get_delegate_public(struct tsp_object * obj,TPM_DELEGATE_PUBLIC * public)1619723e4046Schristos obj_policy_get_delegate_public(struct tsp_object *obj, TPM_DELEGATE_PUBLIC *public)
1620723e4046Schristos {
1621723e4046Schristos 	struct tr_policy_obj *policy;
1622723e4046Schristos 	UINT16 tag;
1623723e4046Schristos 	TPM_DELEGATE_OWNER_BLOB ownerBlob;
1624723e4046Schristos 	TPM_DELEGATE_KEY_BLOB keyBlob;
1625723e4046Schristos 	UINT64 offset;
1626723e4046Schristos 	TSS_RESULT result;
1627723e4046Schristos 
1628723e4046Schristos 	policy = (struct tr_policy_obj *)obj->data;
1629723e4046Schristos 
1630723e4046Schristos 	if (policy->delegationIndexSet) {
1631723e4046Schristos 		if ((result = get_delegate_index(obj->tspContext, policy->delegationIndex,
1632723e4046Schristos 				public)))
1633723e4046Schristos 			return result;
1634723e4046Schristos 	} else if (policy->delegationBlob) {
1635723e4046Schristos 		offset = 0;
1636723e4046Schristos 		Trspi_UnloadBlob_UINT16(&offset, &tag, policy->delegationBlob);
1637723e4046Schristos 
1638723e4046Schristos 		offset = 0;
1639723e4046Schristos 		switch (tag) {
1640723e4046Schristos 		case TPM_TAG_DELEGATE_OWNER_BLOB:
1641723e4046Schristos 			if ((result = Trspi_UnloadBlob_TPM_DELEGATE_OWNER_BLOB(&offset,
1642723e4046Schristos 									policy->delegationBlob,
1643723e4046Schristos 									&ownerBlob)))
1644723e4046Schristos 				return result;
1645723e4046Schristos 			*public = ownerBlob.pub;
1646723e4046Schristos 			free(ownerBlob.additionalArea);
1647723e4046Schristos 			free(ownerBlob.sensitiveArea);
1648723e4046Schristos 			break;
1649723e4046Schristos 		case TPM_TAG_DELG_KEY_BLOB:
1650723e4046Schristos 			if ((result = Trspi_UnloadBlob_TPM_DELEGATE_KEY_BLOB(&offset,
1651723e4046Schristos 									     policy->delegationBlob,
1652723e4046Schristos 									     &keyBlob)))
1653723e4046Schristos 				return result;
1654723e4046Schristos 			*public = keyBlob.pub;
1655723e4046Schristos 			free(keyBlob.additionalArea);
1656723e4046Schristos 			free(keyBlob.sensitiveArea);
1657723e4046Schristos 			break;
1658723e4046Schristos 		default:
1659723e4046Schristos 			return TSPERR(TSS_E_INTERNAL_ERROR);
1660723e4046Schristos 		}
1661723e4046Schristos 	} else
1662723e4046Schristos 		return TSPERR(TSS_E_INTERNAL_ERROR);
1663723e4046Schristos 
1664723e4046Schristos 	return TSS_SUCCESS;
1665723e4046Schristos }
1666723e4046Schristos #endif
1667723e4046Schristos 
1668