1
2/*
3 * Licensed Materials - Property of IBM
4 *
5 * trousers - An open source TCG Software Stack
6 *
7 * (C) Copyright International Business Machines Corp. 2006
8 *
9 */
10
11#include <stdlib.h>
12#include <string.h>
13#include <errno.h>
14
15#include "daa_structs.h"
16#include "trousers/tss.h"
17#include "trousers/trousers.h"
18#include "spi_internal_types.h"
19#include "spi_utils.h"
20#include "obj.h"
21#include "tsplog.h"
22#include "daa_parameter.h"
23#include "verifier.h"
24#include "platform.h"
25
26// for RSA Key
27#include <openssl/rsa.h>
28
29#define DEFAULT_CREDENTIAL_FILENAME "credential.txt"
30#define DEFAULT_OWN_PASSWD "OWN_PWD"
31
32int print_usage(char  *exec) {
33	fprintf(stderr, "usage: %s\n", exec);
34	fprintf(stderr,
35		"\t-m,\t--message\n\t\tif define, the data is signed using this message\n\
36\t\totherwise an AIK will be generated and used\n");
37	fprintf(stderr,
38		"\t-pw,\t--passwd\n\t\ttpm owner password (default: %s)\n",
39		DEFAULT_OWN_PASSWD);
40	fprintf(stderr,
41		"\t-cr,\t--credential\n\t\tcredential filename (default: %s)\n",
42		DEFAULT_CREDENTIAL_FILENAME);
43	return -1;
44}
45
46int main(int argc, char *argv[]) {
47	TSS_HCONTEXT hContext;
48	TSS_RESULT result;
49	TSS_HTPM hTPM;
50	TSS_HPOLICY hPolicy;
51	char *credential_filename = DEFAULT_CREDENTIAL_FILENAME;
52	UINT32 nonceVerifierLength;
53	BYTE *nonceVerifier;
54	TSS_HDAA hDAA;
55	TSS_DAA_CREDENTIAL *hDaaCredential;
56	TSS_DAA_SIGN_DATA signData;
57	TSS_DAA_SIGNATURE daaSignature;
58	TSS_DAA_SELECTED_ATTRIB revealAttributes;
59	char *szTpmPasswd = DEFAULT_OWN_PASSWD;
60	char *message = NULL;
61	BYTE **attributes = NULL;
62	FILE *file;
63	char *param;
64	int i, length, rv;
65	bi_ptr random = NULL;
66	TSS_BOOL isCorrect;
67	EVP_MD_CTX *mdctx;
68	TSS_HKEY hKEY;
69
70	init_tss_version( &signData);
71	init_tss_version( &daaSignature);
72	init_tss_version( &revealAttributes);
73	i = 1;
74	while( i < argc) {
75		param = argv[ i];
76		if ( strcmp( param, "-m") == 0 || strcmp( param, "--message") == 0) {
77			i++;
78			if( i == argc) return print_usage( argv[0]);
79			message = argv[i];
80		} else if( strcmp( param, "-cr") == 0 || strcmp( param, "--credential") == 0){
81			i++;
82			if( i == argc) return print_usage( argv[0]);
83			credential_filename = argv[i];
84		} else if( strcmp( param, "-pw") == 0 || strcmp( param, "--passwd") == 0){
85			i++;
86			if( i == argc) return print_usage( argv[0]);
87			szTpmPasswd = argv[i];
88		} else {
89			fprintf(stderr, "%s:unrecognized option `%s'\n", argv[0], param);
90			return print_usage( argv[0]);
91		}
92		i++;
93	}
94	bi_init( NULL);
95	printf("Loading credential: %s ", credential_filename);
96	file = fopen( credential_filename, "r");
97	if( (hDaaCredential = load_TSS_DAA_CREDENTIAL( file)) == 0) {
98		LogError( "[test_join]: Error when loading \'%s\': %s\n",
99			credential_filename,
100			strerror( errno));
101		result = TSS_E_FAIL;
102		goto out_close;
103	}
104	fclose( file);
105	printf("Done\n");
106
107	// Create Context
108	LogDebug("Create Context");
109	result = Tspi_Context_Create( &hContext );
110	if ( result != TSS_SUCCESS )
111	{
112		LogError( "Tspi_Context_Create %d\n", result );
113		goto out;
114	}
115	// Connect to Context
116	result = Tspi_Context_Connect( hContext, NULL );
117	if ( result != TSS_SUCCESS) goto out_close;
118	printf("\nConnect to the context: %X\n", hContext);
119
120	if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS)
121		goto out_close;
122	// Get the correct policy using the TPM ownership PASSWD
123	if( (result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hPolicy)) != TSS_SUCCESS)
124		goto out_close;
125	if( (result = Tspi_Policy_SetSecret( hPolicy,
126						TSS_SECRET_MODE_PLAIN,
127						strlen( szTpmPasswd),
128						szTpmPasswd)) != TSS_SUCCESS)
129		goto out_close;
130	LogDebug("Tspi_Policy_SetSecret hPolicy received;%d", hPolicy);
131
132	//Create Object
133	result = obj_daa_add( hContext, &hDAA);
134	if (result != TSS_SUCCESS) {
135		LogError("Tspi_Context_CreateObject:%d", result);
136		Tspi_Context_Close(hContext);
137		LogError("%s: %s", argv[0], err_string(result));
138		exit(result);
139	}
140	LogDebug("created DAA object:%X", hDAA);
141
142	// TODO: verifier base name ??
143	result = Tspi_DAA_VerifyInit(
144		hDAA,	// in
145		&nonceVerifierLength,	// out
146		&nonceVerifier,	// out
147		0, //baseNameLength,	// out
148		NULL //baseName		// out
149	);
150	if (result != TSS_SUCCESS) goto out_close;
151	LogDebug("Verify Init return nonceVerifier [%s]",
152			dump_byte_array( nonceVerifierLength, nonceVerifier));
153
154	create_TSS_DAA_SELECTED_ATTRIB( &revealAttributes, 5, 0, 1, 1, 0, 0);
155
156	mdctx = EVP_MD_CTX_create();
157
158	// create the TSS_DAA_SIGN_DATA struct
159	// .selector: 0 -> payload contains a handle to an AIK
160	//            1 -> payload contains a hashed message
161	if( message != NULL) {
162		signData.selector = TSS_FLAG_DAA_SIGN_MESSAGE_HASH;
163		signData.payloadFlag = TSS_FLAG_DAA_SIGN_MESSAGE_HASH;
164		EVP_DigestInit(mdctx, DAA_PARAM_get_message_digest());
165		EVP_DigestUpdate(mdctx,  (BYTE *)message, strlen( message));
166		signData.payloadLength = EVP_MD_CTX_size(mdctx);
167		signData.payload = (BYTE *)EVP_MD_CTX_create();
168		EVP_DigestFinal(mdctx, signData.payload, NULL);
169	} else {
170		signData.selector = TSS_FLAG_DAA_SIGN_IDENTITY_KEY;
171		result = Tspi_Context_CreateObject(
172			hContext,	 //  in
173			TSS_OBJECT_TYPE_RSAKEY,		//  in
174			TSS_KEY_SIZE_2048,		//  in
175			&hKEY	//  out
176		);
177		if( result != TSS_SUCCESS) goto out_close;
178
179	}
180
181	result = Tspi_TPM_DAA_Sign(
182		hDAA,	// in
183		hTPM,	// in
184		(TSS_HKEY)hDaaCredential,	// in
185		revealAttributes,	// in
186		0, // verifierBaseNameLength,	// in
187		NULL, // verifierBaseName,	// in
188		nonceVerifierLength,	// in
189		nonceVerifier,	// in
190		signData,	// in
191		&daaSignature	// out
192	);
193	if (result != TSS_SUCCESS) goto out_close;
194	LogDebug("TPM_DAA_Sign return daaSignature [%s]",
195			dump_byte_array( nonceVerifierLength, nonceVerifier));
196
197	// generate attributes list but without copying the not revealed ones
198	attributes = malloc( sizeof(BYTE *) * hDaaCredential->attributesLength);
199	for( i=0; i < (int)(hDaaCredential->attributesLength); i++) {
200		if( revealAttributes.indicesList[i]) {
201			attributes[i] = (BYTE *)malloc( DAA_PARAM_SIZE_F_I / 8);
202			memcpy( attributes[i],
203				hDaaCredential->attributes[i],
204				DAA_PARAM_SIZE_F_I / 8);
205		} else {
206			attributes[i] = NULL;
207		}
208	}
209
210	result = Tspi_DAA_VerifySignature(
211		hDAA,	// in
212		daaSignature,	// in
213		(TSS_HKEY)&(hDaaCredential->issuerPK),	// in
214		signData,	// in
215		hDaaCredential->attributesLength,	// in
216		attributes,	// in
217		nonceVerifierLength,	// in
218		nonceVerifier,	// in
219		0,	//baseNameLength,	//in
220		NULL,	// in
221		&isCorrect	// out
222	);
223	printf("Signature correct:%s\n", ( isCorrect ? "yes" : "no"));
224
225out_close:
226	EVP_MD_CTX_destroy(mdctx);
227	if( attributes != NULL) {
228		for( i=0; i<(int)hDaaCredential->attributesLength; i++) {
229			if( attributes[i] != NULL) free( attributes[i]);
230		}
231		free( attributes);
232	}
233	if( random != NULL) bi_free_ptr( random);
234	Tspi_Context_FreeMemory( hContext, NULL );
235	Tspi_Context_Close( hContext );
236out:
237	bi_release();
238	LogDebug("THE END result=%d:%s",result, err_string( result) );;
239	return result;
240}
241
242