Example #1
0
static TPM_RESULT execute_TPM_GetPubKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
{
  BYTE *ptr;
  UINT32 len;
  TPM_KEY_HANDLE keyHandle;
  TPM_PUBKEY pubKey;
  TPM_RESULT res;
  /* compute parameter digest */
  tpm_compute_in_param_digest(req);
  /* unmarshal input */
  ptr = req->param;
  len = req->paramSize;
  if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
      || len != 0) return TPM_BAD_PARAMETER;
  /* execute command */
  res = TPM_GetPubKey(keyHandle, &req->auth1, &pubKey);
  if (res != TPM_SUCCESS) return res;
  /* marshal output */
  rsp->paramSize = len = sizeof_TPM_PUBKEY(pubKey);
  rsp->param = ptr = malloc(len);
  if (ptr == NULL
      || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubKey)) {
    free(rsp->param);
    res = TPM_FAIL;
  }
  free_TPM_PUBKEY(pubKey);
  return res;
}
Example #2
0
int main(int argc, char *argv[])
{
    uint32_t ret;
    STACK_TPM_BUFFER(resp);
    int index = 0;
    STACK_TPM_BUFFER( subcap );;
	
    TPM_setlog(0);		/* turn off verbose output */

    ParseArgs(argc, argv);

    while ((int)matrx[index].cap != -1) {
	if (cap == matrx[index].cap) {
	    break;
	}
	index++;
    }
    if (-1 == (int)matrx[index].cap) {
	printf("Unknown or unsupported capability!\n");
	exit(-1);
    }
	
    subcap.used = 0;
    if (matrx[index].subcap_size > 0) {
	if ((int)scap == -1) {
	    printf("Need subcap parameter for this capability!\n");
	    exit(-1);
	}
	if (0 == prepare_subcap(cap, &subcap, scap)) {
	    if (2 == matrx[index].subcap_size) {
		STORE16(subcap.buffer,0,scap);
		subcap.used = 2;
	    } else
		if (matrx[index].subcap_size >= 4) {
		    STORE32(subcap.buffer,0,scap);
		    subcap.used  = 4;
		}
	}
    }
	
#if 0
    /* This was for VTPM extensions and needs retest */
    if (cap == TPM_CAP_MFR) {
	int idx2 = 0;
	while ((int)mfr_matrix[idx2].cap != -1) {
	    if (mfr_matrix[idx2].cap == scap) {
		break;
	    }
	    idx2++;
	}
	if (mfr_matrix[idx2].subcap_size > 0) {
	    uint32_t used = subcap.used +
			    mfr_matrix[idx2].subcap_size;
	    while (subcap.used < used) {
		if (argc <= nxtarg) {
		    printf("Need one more parameter for this "
			   "capability!\n");
		    exit(-1);
		}
		if (!strncmp("0x",argv[nxtarg],2)) {
		    sscanf(argv[nxtarg],"%x",&sscap);
		} else {
		    sscanf(argv[nxtarg],"%d",&sscap);
		}
		nxtarg++;
		if (2 == matrx[index].subcap_size) {
		    STORE16(subcap.buffer,
			    subcap.used,sscap);
		    subcap.used += 2;
		} else
		    if (matrx[index].subcap_size >= 4) {
			STORE32(subcap.buffer,
				subcap.used,sscap);
			subcap.used += 4;
		    }
	    }
	}
    }


#endif
    if (0 == sikeyhandle) {
	ret = TPM_GetCapability(cap,
				&subcap,
				&resp);

	if (0 != ret) {
	    printf("TPM_GetCapability returned %s.\n",
		   TPM_GetErrMsg(ret));
	    exit(ret);
	}
    } else {
	unsigned char antiReplay[TPM_HASH_SIZE];
	unsigned char signature[2048];
	uint32_t signaturelen = sizeof(signature);
	pubkeydata pubkey;
	RSA * rsa;
	unsigned char sighash[TPM_HASH_SIZE];
	unsigned char * buffer = NULL;
	unsigned char * sigkeyhashptr = NULL;
	unsigned char sigkeypasshash[TPM_HASH_SIZE];

	if (NULL != sikeypass) {
	    TSS_sha1(sikeypass,strlen(sikeypass),sigkeypasshash);
	    sigkeyhashptr = sigkeypasshash;
	}

	TSS_gennonce(antiReplay);
		
	ret = TPM_GetPubKey(sikeyhandle,
			    sigkeyhashptr,
			    &pubkey);

	if (0 != ret) {
	    printf("Error while trying to access the signing key's public key.\n");
	    exit(-1);
	}
		
	rsa = TSS_convpubkey(&pubkey);
		
	ret = TPM_GetCapabilitySigned(sikeyhandle,
				      sigkeyhashptr,
				      antiReplay,
				      cap,
				      &subcap,
				      &resp,
				      signature, &signaturelen);

	if (0 != ret) {
	    printf("TPM_GetCapabilitySigned returned %s.\n",
		   TPM_GetErrMsg(ret));
	    exit(ret);
	}

	buffer = malloc(resp.used+TPM_NONCE_SIZE);
	if (NULL == buffer) {
	    printf("Could not allocate buffer.\n");
	    exit(-1);
	}
	memcpy(&buffer[0], resp.buffer, resp.used);
	memcpy(&buffer[resp.used], antiReplay, TPM_NONCE_SIZE);

	TSS_sha1(buffer,
		 resp.used+TPM_NONCE_SIZE,
		 sighash);
	free(buffer);

	ret = RSA_verify(NID_sha1,
			 sighash,TPM_HASH_SIZE,
			 signature,signaturelen,
			 rsa);
	if (1 != ret) {
	    printf("Error: Signature verification failed.\n");
	    exit(-1);
	}
    }

    if (0 == resp.used) {
	printf("Empty response.\n");
    } else {

	if (-1 == (int)scap) {
	    printf("Result for capability 0x%x is : ",cap);
	} else {
	    printf("Result for capability 0x%x, subcapability 0x%x is : ",cap,scap);
	}
	if (TYPE_BOOL == matrx[index].result_size) {
	    if (resp.buffer[0] == 0) {
		printf("FALSE\n");
	    } else {
		printf("TRUE\n");
	    }
	} else
	    if (TYPE_UINT32 == matrx[index].result_size) {
		uint32_t rsp;
		rsp = LOAD32(resp.buffer,0);
		printf("0x%08X  = %d\n",rsp,rsp);
	    } else
		if (TYPE_UINT32_ARRAY == matrx[index].result_size) {
		    int i = 0;
		    printf("\n");
		    while (i+3 < (int)resp.used) {
			uint32_t rsp = LOAD32(resp.buffer,i);
			i+=4;
			if (TPM_CAP_NV_LIST == cap) {
			    /* don't zero extend, grep needs the exact value for test suite */
			    printf("%d. Index : %d = 0x%x.\n",
				   i/4,
				   rsp,
				   rsp);
			} else
			    if (TPM_CAP_KEY_HANDLE == cap) {
				printf("%d. keyhandle : %d.\n",
				       i/4,
				       rsp);
				} else {
				    printf("%d. item : %d.\n",
					   i/4,
					   rsp);
				}
		    }
		} else
		    if (TYPE_STRUCTURE == matrx[index].result_size) {
			switch(cap) {
			  case TPM_CAP_FLAG:
			      {
				  if (scap == TPM_CAP_FLAG_PERMANENT) {
				      TPM_PERMANENT_FLAGS pf;
				      STACK_TPM_BUFFER(tb)
					  TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				      ret = TPM_ReadPermanentFlags(&tb, 0, &pf, resp.used);
				      if ( ( ret & ERR_MASK ) != 0 || ret > resp.used) {
					  printf("ret=%x, responselen=%d\n",ret,resp.used);
					  printf("Error parsing response!\n");
					  exit(-1);
				      }
						
				      printf("\n");
				      showPermanentFlags(&pf, resp.used);
				  } else 
				      if (scap == TPM_CAP_FLAG_VOLATILE) {
					  TPM_STCLEAR_FLAGS sf;
					  STACK_TPM_BUFFER(tb);
					  TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
					  ret = TPM_ReadSTClearFlags(&tb, 0, &sf);
					  if ( ( ret & ERR_MASK ) != 0 || ret > resp.used) {
					      printf("ret=%x, responselen=%d\n",ret,resp.used);
					      printf("Error parsing response!\n");
					      exit(-1);
					  }
						
					  printf("\n");
					  showVolatileFlags(&sf);
						
				      }
			      }
			      break;
				
			  case TPM_CAP_KEY_HANDLE:
			      {
				  uint16_t num = LOAD16(resp.buffer, 0);
				  uint32_t i = 0;
				  uint32_t handle;
				  printf("\n");
				  while (i < num) {
				      handle = LOAD32(resp.buffer,2+i*4);
				      printf("%d. handle: 0x%08X\n",
					     i,
					     handle);
				      i++;
				  }
			      }
			      break;
			  case TPM_CAP_NV_INDEX:
			      {
				  //char scratch_info[256];
				  unsigned char scratch_info[256];
				  uint32_t scratch_info_len;
				  TPM_NV_DATA_PUBLIC ndp;
				  uint32_t i, c;
				  STACK_TPM_BUFFER(tb)
				      TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				  ret = TPM_ReadNVDataPublic(&tb,
							     0,
							     &ndp);
				  if ( ( ret & ERR_MASK) != 0) {
				      printf("Could not deserialize the TPM_NV_DATA_PUBLIC structure.\n");
				      exit(-1);
				  }
				  printf("permission.attributes : %08X\n",(unsigned int)ndp.permission.attributes);
				  printf("ReadSTClear           : %02X\n",ndp.bReadSTClear);
				  printf("WriteSTClear          : %02X\n",ndp.bWriteSTClear);
				  printf("WriteDefine           : %02X\n",ndp.bWriteDefine);
				  printf("dataSize              : %08X = %d",(unsigned int)ndp.dataSize,
					 (unsigned int)ndp.dataSize);

				  c = 0;
				  for (i = 0; i < ndp.pcrInfoRead.pcrSelection.sizeOfSelect*8; i++) {
				      if (ndp.pcrInfoRead.pcrSelection.pcrSelect[(i / 8)] & (1 << (i & 0x7))) {
					      if (!c)
						  printf("\nRead PCRs selected: ");
					      else
						  printf(", ");
					      printf("%d", i);
					      c++;

				      }
				  }

				  if (c) {
				      char pcrmap[4], *pf;

				      memcpy(pcrmap, ndp.pcrInfoRead.pcrSelection.pcrSelect,
					     ndp.pcrInfoRead.pcrSelection.sizeOfSelect);

				 //     printf("\npcrmap: %02x%02x%02x%02x\n", pcrmap[0], pcrmap[1],
				//	     pcrmap[2], pcrmap[3]);

				      ret = TSS_GenPCRInfo(*(uint32_t *)pcrmap,
							   scratch_info,
							   &scratch_info_len);

				      printf("\nRead PCR Composite: ");
				      for (i = 0; i < 20; i++)
					  printf("%02x", ndp.pcrInfoRead.digestAtRelease[i] & 0xff);
				      printf("\n");
#if 1
				      pf = &scratch_info[5];
				      printf("\nCurrent PCR composite: ");
				      for (i = 0; i < 20; i++)
					  //printf("%02x", scratch_info.digestAtRelease[i] & 0xff);
					  printf("%02x", pf[i] & 0xff);
				      printf("\n");
#endif
				      if (!ret) {
					      printf("Matches current TPM state: ");

					      if (!memcmp(&scratch_info[5],
							  &ndp.pcrInfoRead.digestAtRelease,
							  20)) {
						      printf("Yes\n");
					      } else {
						      printf("No\n");
					      }
				      }
				  }


				  c = 0;
				  for (i = 0; i < ndp.pcrInfoWrite.pcrSelection.sizeOfSelect*8; i++) {
				      if (ndp.pcrInfoWrite.pcrSelection.pcrSelect[(i / 8)] & (1 << (i & 0x7))) {
					      if (!c)
						  printf("\nWrite PCRs selected: ");
					      else
						  printf(", ");
					      printf("%d", i);
					      c++;

				      }
				  }

				  if (c) {
				      printf("\nWrite PCR Composite: ");
				      for (i = 0; i < 20; i++)
					  printf("%02x", ndp.pcrInfoWrite.digestAtRelease[i] & 0xff);
				      printf("\n");
				  }
			      }
			      break;
			  case TPM_CAP_HANDLE:
			      {
				  uint16_t num = LOAD16(resp.buffer, 0);
				  uint16_t x = 0;
				  while (x < num) {
				      uint32_t handle = LOAD32(resp.buffer,
							       sizeof(num)+4*x);
				      printf("%02d. 0x%08X\n",x,handle);
				      x++;
				  }
			      }
			      break;
			  case TPM_CAP_VERSION_VAL:
			      {
				  int i = 0;
				  TPM_CAP_VERSION_INFO cvi;
				  STACK_TPM_BUFFER(tb)
				      TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				  ret = TPM_ReadCapVersionInfo(&tb,
							       0,
							       &cvi);
				  if ( ( ret & ERR_MASK) != 0) {
				      printf("Could not read the version info structure.\n");
				      exit(-1);
				  }
					
				  printf("\n");
				  printf("major      : 0x%02X\n",cvi.version.major);
				  printf("minor      : 0x%02X\n",cvi.version.minor);
				  printf("revMajor   : 0x%02X\n",cvi.version.revMajor);
				  printf("revMinor   : 0x%02X\n",cvi.version.revMinor);
				  printf("specLevel  : 0x%04X\n",cvi.specLevel);
				  printf("errataRev  : 0x%02X\n",cvi.errataRev);
	
				  printf("VendorID   : ");
				  while (i < 4) {
				      printf("%02X ",cvi.tpmVendorID[i]);
				      i++;
				  }
				  printf("\n");
				  /* Print vendor ID in text if printable */
				  for (i=0 ; i<4 ; i++) {
				      if (isprint(cvi.tpmVendorID[i])) {
					  if (i == 0) {
					      printf("VendorID   : ");
					  }
					  printf("%c", cvi.tpmVendorID[i]);
				      }
				      else {
					  break;
				      }
				  }	    
				  printf("\n");

				  printf("[not displaying vendor specific information]\n");
			      }
			      break;
#if 0	/* kgold: I don't think these are valid cap values */
			  case TPM_CAP_FLAG_PERMANENT:
			      {
				  TPM_PERMANENT_FLAGS pf;
				  STACK_TPM_BUFFER(tb)
				      TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);

				  if (resp.used == 21) {
				      ret = TPM_ReadPermanentFlagsPre103(&tb, 0, &pf);
				  } else {
				      ret = TPM_ReadPermanentFlags(&tb, 0, &pf);
				  }
				  if ( ( ret & ERR_MASK ) != 0 || ret > resp.used) {
				      printf("ret=%x, responselen=%d\n",ret,resp.used);
				      printf("Error parsing response!\n");
				      exit(-1);
				  }
						
				  printf("\n");
				  showPermanentFlags(&pf, resp.used);
			      }
			      break;
				
			  case TPM_CAP_FLAG_VOLATILE:
			      {
				  TPM_STCLEAR_FLAGS sf;
				  STACK_TPM_BUFFER(tb);
				  TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				  ret = TPM_ReadSTClearFlags(&tb, 0, &sf);
				  if ( ( ret & ERR_MASK ) != 0 || ret > resp.used) {
				      printf("ret=%x, responselen=%d\n",ret,resp.used);
				      printf("Error parsing response!\n");
				      exit(-1);
				  }
						
				  printf("\n");
				  showVolatileFlags(&sf);
			      }
			      break;
#endif
			  case TPM_CAP_DA_LOGIC:
			      {
				  uint32_t ctr;
				  TPM_BOOL lim = FALSE;
				  TPM_DA_INFO dainfo;
				  TPM_DA_INFO_LIMITED dainfo_lim;
				  STACK_TPM_BUFFER(tb);
				  TSS_SetTPMBuffer(&tb, resp.buffer, resp.used);
				  ret = TPM_ReadDAInfo(&tb, 0, &dainfo);
				  if ( ( ret & ERR_MASK) != 0 || ret > resp.used) {
				      ret = TPM_ReadDAInfoLimited(&tb, 0, &dainfo_lim);
				      if ( (ret & ERR_MASK ) != 0 || ret > resp.used) {
					  printf("ret=%x, responselen=%d\n",ret,resp.used);
					  printf("Error parsing response!\n");
					  exit(-1);
				      } else {
					  lim = TRUE;
				      }
				  }
					
				  printf("\n");
				  if (lim) {
				      printf("State      : %d\n",dainfo_lim.state);
				      printf("Actions    : 0x%08x\n",dainfo_lim.actionAtThreshold.actions);
						
				      ctr = 0;
				      while (ctr < dainfo_lim.vendorData.size) {
					  printf("%02x ",(unsigned char)dainfo_lim.vendorData.buffer[ctr]);
					  ctr++;
				      }
				  } else {
				      printf("State              : %d\n",dainfo.state);
				      printf("currentCount       : %d\n",dainfo.currentCount);
				      printf("thresholdCount     : %d\n",dainfo.thresholdCount);
				      printf("Actions            : 0x%08x\n",dainfo.actionAtThreshold.actions);
				      printf("actionDependValue  : %d\n",dainfo.actionDependValue);
						
#if 0
				      ctr = 0;
				      while (ctr < dainfo_lim.vendorData.size) {
					  printf("%02x ",(unsigned char)dainfo_lim.vendorData.buffer[ctr]);
					  ctr++;
				      }
#endif
				  }
			      }
			      break;
			}
		    } else
			if (TYPE_VARIOUS == matrx[index].result_size) {
			    switch(cap) {
			
			      case TPM_CAP_MFR:
				switch (scap) {
				  case TPM_CAP_PROCESS_ID:
				      {
					  uint32_t rsp;
					  rsp = LOAD32(resp.buffer,0);
					  printf("%d\n",rsp);
				      }
				      break;
				}
				break; /* TPM_CAP_MFR */
			
			      default:
				/* Show booleans */
				if (scap == TPM_CAP_PROP_OWNER ||
				    scap == TPM_CAP_PROP_DAA_INTERRUPT
				    ) {
				    if (0 == resp.buffer[0]) {
					printf("FALSE\n");
				    } else {
					printf("TRUE\n");
				    }
				} else /* check for array of 4 UINTs */
				    if (scap == TPM_CAP_PROP_TIS_TIMEOUT /* ||
									    scap == TPM_CAP_PROP_TIMEOUTS      */) {
					int i = 0;
					while (i < 4) {
					    uint32_t val = LOAD32(resp.buffer,i * 4);
					    printf("%d ",
						   val);
					    i++;
					}
					printf("\n");
				    } else /* check for TPM_STARTUP_EFFECTS */
					if (scap == TPM_CAP_PROP_STARTUP_EFFECT) {
					    TPM_STARTUP_EFFECTS se = 0;
					    ret = TPM_ReadStartupEffects(resp.buffer, 
									 &se);
					    if ( ( ret & ERR_MASK ) != 0 ) {
						printf("Could not read startup effects structure.\n");
						exit(-1);
					    }
					    printf("0x%08X=%d\n",
						   (unsigned int)se,
						   (unsigned int)se);
					    printf("\n");
					    printf("Startup effects:\n");
					    printf("Effect on audit digest: %s\n", (se & (1 << 7)) 
						   ? "none"
						   : "active");
					    printf("Audit Digest on TPM_Startup(ST_CLEAR): %s\n", ( se & (1 << 6)) 
						   ? "set to NULL" 
						   : "not set to NULL" );
		
					    printf("Audit Digest on TPM_Startup(any)     : %s\n", ( se & (1 << 5))
						   ? "set to NULL"
						   : "not set to NULL" );
					    printf("TPM_RT_KEY resource initialized on TPM_Startup(ST_ANY)     : %s\n", (se & ( 1 << 4))
						   ? "yes"
						   : "no");
					    printf("TPM_RT_AUTH resource initialized on TPM_Startup(ST_STATE)  : %s\n", (se & ( 1 << 3))
						   ? "yes"
						   : "no");
					    printf("TPM_RT_HASH resource initialized on TPM_Startup(ST_STATE)  : %s\n", (se & ( 1 << 2))
						   ? "yes"
						   : "no");
					    printf("TPM_RT_TRANS resource initialized on TPM_Startup(ST_STATE) : %s\n", (se & ( 1 << 1))
						   ? "yes"
						   : "no");
					    printf("TPM_RT_CONTEXT session initialized on TPM_Startup(ST_STATE): %s\n", (se & ( 1 << 0))
						   ? "yes"
						   : "no");
					} else /* check for  array of 3 UINTs */
					    if (scap == TPM_CAP_PROP_DURATION) {
						int i = 0;
						while (i < 4*3) {
						    uint32_t val = LOAD32(resp.buffer,i);
						    printf("%d ",
							   val);
						    i+= 4;
						}
						printf("\n");
					    } else /* check for TPM_COUNT_ID */
						if (scap == TPM_CAP_PROP_ACTIVE_COUNTER) {
						    uint32_t val = LOAD32(resp.buffer,0);
						    printf("0x%08X=%d",val,val);
						    if (0xffffffff == val) {
							printf(" (no counter is active)");
						    }
						    printf("\n");
						} else { /* just a single UINT32 */
						    printf("%ld=0x%08lX.\n",
							   (long)LOAD32(resp.buffer, 0),
							   (long)LOAD32(resp.buffer, 0));
						}
			    }
			}
    }		
	
    printf("\n");
    exit(0);
}
int main(int argc, char *argv[])
{
	uint32_t startOrdinal = -1;
	int ret;
	int verbose = FALSE;
	TPM_COUNTER_VALUE counter;
	int i = 1;
	char * keypass = NULL;
	unsigned char keyAuth[TPM_HASH_SIZE];
	unsigned char * keyAuthPtr = NULL;
	uint32_t keyhandle = -1;
	STACK_TPM_BUFFER(signature);
	unsigned char digest[TPM_DIGEST_SIZE];
	unsigned char ordinalDigest[TPM_DIGEST_SIZE];
	unsigned char antiReplay[TPM_NONCE_SIZE];
	
	TPM_setlog(0);
	TSS_gennonce(antiReplay);
	
	while (i < argc) {
		if (!strcmp("-s",argv[i])) {
			i++;
			if (i < argc) {
				sscanf(argv[i],"%d",&startOrdinal);
			} else {
				printf("Missing parameter for -s.\n");
				usage();
			}
		} else
		if (!strcmp("-h",argv[i])) {
			i++;
			if (i < argc) {
				sscanf(argv[i],"%x",&keyhandle);
			} else {
				printf("Missing parameter for -h.\n");
				usage();
			}
		} else
		if (!strcmp("-p",argv[i])) {
			i++;
			if (i < argc) {
				keypass = argv[i];
			} else {
				printf("Missing parameter for -p.\n");
				usage();
			}
		} else
		if (!strcmp("-v",argv[i])) {
			verbose = TRUE;
			TPM_setlog(1);
		} else {
		        printf("\n%s is not a valid option\n", argv[i]);
			usage();
		}
		i++;
	}
	(void)verbose;

	if (-1 == (int)startOrdinal ||
	    -1 == (int)keyhandle) {
		printf("Missing command line parameter.\n");
		usage();
	}

	if (NULL != keypass) {
		TSS_sha1(keypass,strlen(keypass),keyAuth);
		keyAuthPtr = keyAuth;
	}
	ret = TPM_GetAuditDigestSigned(keyhandle,
	                               FALSE,
	                               keyAuthPtr,
	                               antiReplay,
	                               &counter,
	                               digest,
	                               ordinalDigest,
	                               &signature);

	if (0 != ret) {
		printf("Error %s from GetAuditDigestSigned.\n",
		       TPM_GetErrMsg(ret));
	} else {
		TPM_SIGN_INFO tsi;
		STACK_TPM_BUFFER(tsi_ser);
		STACK_TPM_BUFFER(serial);
		STACK_TPM_BUFFER(ctr_ser);
		pubkeydata pubkey;
		RSA *rsa;

		i = 0;
		printf("AuditDigest   : ");
		while (i < (int)sizeof(digest)) {
			printf("%02X",digest[i]);
			i++;
		}
		printf("\n");
	
		i = 0;
		printf("OrdinalDigest : ");
		while (i < (int)sizeof(digest)) {
			printf("%02X",ordinalDigest[i]);
			i++;
		}
		printf("\n");

		ret = TPM_GetPubKey(keyhandle, keyAuthPtr, &pubkey);
		if (ret != 0) {
			printf("Could not get public key of signing key.\n");
			exit(-1);
		}
		rsa = TSS_convpubkey(&pubkey);
		if (!rsa) {
			printf("Could not convert public key.\n");
			exit(-1);
		}
		
		tsi.tag = TPM_TAG_SIGNINFO;
		memcpy(tsi.fixed, "ADIG", 4);
		memcpy(tsi.replay, antiReplay, sizeof(antiReplay));
		/* D4=ordinalDigest */
		TPM_WriteCounterValue(&ctr_ser, &counter);
		memcpy(&serial.buffer[0], digest, sizeof(digest));
		memcpy(&serial.buffer[sizeof(digest)],
		                          ctr_ser.buffer, ctr_ser.used);
		memcpy(&serial.buffer[sizeof(digest)+ctr_ser.used],
		                          ordinalDigest, sizeof(ordinalDigest));
		serial.used = sizeof(digest) + ctr_ser.used + sizeof(ordinalDigest);
		tsi.data.size = serial.used;
		tsi.data.buffer = serial.buffer; 
		ret = TPM_WriteSignInfo(&tsi_ser, &tsi);
		if ((ret & ERR_MASK)) {
			printf("Error serializing TPM_SIGN_INFO.\n");
			exit(-1);
		}
		ret = TPM_ValidateSignature(TPM_SS_RSASSAPKCS1v15_SHA1,
		                            &tsi_ser,
		                            &signature,
		                            rsa);
		if (ret != 0) {
			printf("Error validating signature.\n");
			exit(-1);
		}
		printf("Signature verification successful.\n");
	}
	exit(ret);
}
Example #4
0
int main(int argc, char *argv[])
{
	int ret;			/* general return value */
	uint32_t keyhandle = 0;		/* handle of quote key */
	unsigned int  pcrmask = 0;	/* pcr register mask */
	unsigned char passhash1[TPM_HASH_SIZE];	/* hash of key password */
	unsigned char data[TPM_HASH_SIZE];/* nonce data */
	
	STACK_TPM_BUFFER(signature);
	pubkeydata  pubkey;		/* public key structure */
	RSA *rsa;			/* openssl RSA public key */
	unsigned char *passptr;
	TPM_PCR_SELECTION selection;
	TPM_PCR_INFO_SHORT s1;
	TPM_QUOTE_INFO2 quoteinfo;
	STACK_TPM_BUFFER( serQuoteInfo )
	uint32_t pcrs;
	int i;
	uint16_t sigscheme = TPM_SS_RSASSAPKCS1v15_SHA1;
	TPM_BOOL addVersion = FALSE;
	STACK_TPM_BUFFER(versionblob);
	static char *keypass = NULL;

	
	TPM_setlog(0);    /* turn off verbose output from TPM driver */
	for (i=1 ; i<argc ; i++) {
	    if (strcmp(argv[i],"-hk") == 0) {
		i++;
		if (i < argc) {
		    /* convert key handle from hex */
		    if (1 != sscanf(argv[i], "%x", &keyhandle)) {
			printf("Invalid -hk argument '%s'\n",argv[i]);
			exit(2);
		    }
		}
		else {
		    printf("-hk option needs a value\n");
		    printUsage();
		}
	    }
	    else if (!strcmp(argv[i], "-pwdk")) {
		i++;
		if (i < argc) {
		    keypass = argv[i];
		}
		else {
		    printf("Missing parameter to -pwdk\n");
		    printUsage();
		}
	    }
	    else if (strcmp(argv[i],"-bm") == 0) {
		i++;
		if (i < argc) {
		    /* convert key handle from hex */
		    if (1 != sscanf(argv[i], "%x", &pcrmask)) {
			printf("Invalid -bm argument '%s'\n",argv[i]);
			exit(2);
		    }
		}
		else {
		    printf("-bm option needs a value\n");
		    printUsage();
		}
	    }
	    else if (!strcmp(argv[i], "-vinfo")) {
		addVersion = TRUE;
		printf("Adding version info.\n");
	    }
	    else if (!strcmp(argv[i], "-h")) {
		printUsage();
	    }
	    else if (!strcmp(argv[i], "-v")) {
		TPM_setlog(1);
	    }
	    else {
		printf("\n%s is not a valid option\n", argv[i]);
		printUsage();
	    }
	}
	if ((keyhandle == 0) ||
	    (pcrmask == 0)) {
	    printf("Missing argument\n");
	    printUsage();
	}
	memset(&s1, 0x0, sizeof(s1));	
	/*
	** Parse and process the command line arguments
	*/
	/* get the SHA1 hash of the password string for use as the Key Authorization Data */
	if (keypass != NULL) {
	    TSS_sha1((unsigned char *)keypass,strlen(keypass),passhash1);
		passptr = passhash1;
	} else {
		passptr = NULL;
	}
	/* for testing, use the password hash as the test nonce */
	memcpy(data,passhash1,TPM_HASH_SIZE);
	
	ret = TPM_GetNumPCRRegisters(&pcrs);
	if (ret != 0) {
		printf("Error reading number of PCR registers.\n");
		exit(-1);
	}
	if (pcrs > TPM_NUM_PCR) {
		printf("Library does not support that many PCRs.\n");
		exit(-1);
	}

	memset(&selection, 0x0, sizeof(selection));
	selection.sizeOfSelect = pcrs / 8;
	for (i = 0; i < selection.sizeOfSelect; i++) {
		selection.pcrSelect[i] = (pcrmask & 0xff);
		pcrmask >>= 8;
	}

	/*
	** perform the TPM Quote function
	*/
	ret = TPM_Quote2(keyhandle,	/* key handle */
	                 &selection,	/* specify PCR registers */
	                 addVersion,    /* add Version */
	                 passptr,	/* Key Password (hashed), or null */
	                 data,		/* nonce data */
	                 &s1,		/* pointer to pcr info */
	                 &versionblob,	/* pointer to TPM_CAP_VERSION_INFO */
	                 &signature);	/* buffer to receive result, int to receive result length */
	if (ret != 0) {
		printf("Error '%s' from TPM_Quote2\n",TPM_GetErrMsg(ret));
		exit(ret);
	}
	/*
	** Get the public key and convert to an OpenSSL RSA public key
	*/
	ret = TPM_GetPubKey(keyhandle,passptr,&pubkey);
	if (ret != 0) {
		printf("Error '%s' from TPM_GetPubKey\n",TPM_GetErrMsg(ret));
		exit(ret);
	}
	rsa = TSS_convpubkey(&pubkey);
	
	
	/*
	** fill the quote info structure and calculate the hashes needed for verification
	*/
	quoteinfo.tag = TPM_TAG_QUOTE_INFO2;
	memcpy(&(quoteinfo.fixed),"QUT2",4);
	quoteinfo.infoShort = s1;
	memcpy(&(quoteinfo.externalData),data,TPM_NONCE_SIZE);
	unsigned char *corey_ptr = (unsigned char *)&quoteinfo;
	unsigned int x;
	printf("quote info: \n");
	for (x=0;x<128;x++)
	{
	    if (x != 0 && x % 16 == 0)
		printf("\n");
	    printf("%02x ", corey_ptr[x]);
	}
	printf("\n");

	    
	/* create the hash of the quoteinfo structure for signature verification */
	ret = TPM_WriteQuoteInfo2(&serQuoteInfo, &quoteinfo);
	if ( ( ret & ERR_MASK ) != 0) {
		exit(-1);
	}
	printf("serquoteinfo: \n");

	for (x=0;x<128;x++)
	{
	    if (x != 0 && x % 16 == 0)
		printf("\n");
	    printf("%02x ", serQuoteInfo.buffer[x]);
	}
	printf("\n");

	/* append version information if given in response */
	if (addVersion) {
	    printf("addversion is called\n");
	    memcpy(serQuoteInfo.buffer + serQuoteInfo.used,
	           versionblob.buffer,
	           versionblob.used);
	    serQuoteInfo.used += versionblob.used;
	}
	
	ret = TPM_ValidateSignature(sigscheme,
	                            &serQuoteInfo,
	                            &signature,
	                            rsa);
	if (ret != 0) {
		printf("Verification failed\n");
	} else {
		printf("Verification succeeded\n");
	}
	RSA_free(rsa);
	exit(ret);
}
Example #5
0
int main(int argc, char * argv[]) {
	char * ownerpass = NULL;
	char * migpass = NULL;
	char * parpass = NULL;
	char * filename = NULL;
	char * migkeyfile = NULL;
	char * migkeypass = NULL;
	uint32_t parhandle = -1;             /* handle of parent key */
	unsigned char * passptr1 = NULL;
	unsigned char passhash1[20];
	unsigned char hashpass1[20];    /* hash of new key password */
	unsigned char hashpass3[20];    /* hash of parent key password */
	unsigned char hashpass4[20];    /* hash of migration key pwd */
	uint32_t ret = 0;
	int i =	0;
	keydata keyparms;
	keydata idkey;
	unsigned char *aptr1 = NULL;
	unsigned char *aptr3 = NULL;
	unsigned char *aptr4 = NULL;
	keydata migkey;
	uint16_t migscheme = TPM_MS_RESTRICT_MIGRATE;
	uint32_t sigTicketSize = 0;
	char * msa_list_filename = NULL;
	TPM_MSA_COMPOSITE msaList = {0, NULL};
	char * keyfile = NULL;
	keydata q;
	uint32_t sigkeyhandle = -1;
	char * sigkeypass = NULL;
	unsigned char sigkeypasshash[TPM_HASH_SIZE];
	unsigned char * sigkeypassptr = NULL;
	unsigned char sigTicket[TPM_HASH_SIZE];
	TPM_CMK_AUTH restrictTicket;
	TPM_CMK_AUTH *restrictTicketParameter;	/* parameter to command function call */
	unsigned char resTicketHash[TPM_HASH_SIZE];
	
	
	memset(&keyparms, 0x0, sizeof(keyparms));
	memset(&idkey   , 0x0, sizeof(idkey));
	memset(&restrictTicket, 0x0, sizeof(restrictTicket));
	
	i = 1;
	
	TPM_setlog(0);
	
	while (i < argc) {
		if (!strcmp("-hp",argv[i])) {
			i++;
			if (i < argc) {
				sscanf(argv[i],"%x",&parhandle);
			} else {
				printf("Missing parameter for -hp.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-pwdp",argv[i])) {
			i++;
			if (i < argc) {
				parpass = argv[i];
			} else {
				printf("Missing parameter for -pwdp.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-ok",argv[i])) {
			i++;
			if (i < argc) {
				filename = argv[i];
			} else {
				printf("Missing parameter for -ok.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-pwdo",argv[i])) {
			i++;
			if (i < argc) {
				ownerpass = argv[i];
			} else {
				printf("Missing parameter for -pwdo.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-pwdm",argv[i])) {
			i++;
			if (i < argc) {
				migpass = argv[i];
			} else {
				printf("Missing parameter for -pwdm.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-msa",argv[i])) {
			i++;
			if (i < argc) {
				msa_list_filename = argv[i];
			} else {
				printf("Missing parameter for -msa.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-ik",argv[i])) {
			i++;
			if (i < argc) {
				keyfile = argv[i];
			} else {
				printf("Missing parameter for -ik.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-im",argv[i])) {
			i++;
			if (i < argc) {
				migkeyfile = argv[i];
			} else {
				printf("Missing parameter for -im.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-pwdk",argv[i])) {
			i++;
			if (i < argc) {
				migkeypass = argv[i];
			} else {
				printf("Missing parameter for -pwdk.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-v",argv[i])) {
			TPM_setlog(1);
		} else
		if (!strcmp("-hs",argv[i])) {
			i++;
			if (i < argc) {
				sscanf(argv[i],"%x",&sigkeyhandle);
			} else {
				printf("Missing mandatory parameter for -hs.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-pwds",argv[i])) {
			i++;
			if (i < argc) {
				sigkeypass = argv[i];
			} else {
				printf("Missing mandatory parameter for -pwds.\n");
				usage();
				exit(-1);
			}
		} else
		if (!strcmp("-double",argv[i])) {
			migscheme = TPM_MS_RESTRICT_APPROVE;
		} else {
			printf("Unknown option '%s'.",argv[i]);
			usage();
			exit(-1);
		}
		i++;
	}


	if (NULL == keyfile ||
	    NULL == ownerpass || 
	    -1 == (int)parhandle   || 
	    NULL == migkeyfile ||
	    NULL == msa_list_filename) {
		printf("Missing or wrong parameter.\n");
		usage();
		exit(-1);
	}
	
	if (TPM_MS_RESTRICT_APPROVE == migscheme) {
		if (-1 == (int)sigkeyhandle) {
			printf("Must provide signing key data when '-double' has been selected.\n");
			exit(-1);
		}
	}

	if (NULL != ownerpass) {
		TSS_sha1(ownerpass,strlen(ownerpass),passhash1);
		passptr1 = passhash1;
	} else {
		passptr1 = NULL;
	}

	if (NULL !=sigkeypass) {
		TSS_sha1(sigkeypass, strlen(sigkeypass), sigkeypasshash);
		sigkeypassptr = sigkeypasshash;
	} else {
		sigkeypassptr = NULL;
	}
	

	/*
	** use the SHA1 hash of the password string as the Parent Key Authorization Data
	*/
	if (parpass != NULL) { TSS_sha1(parpass,strlen(parpass),hashpass1); aptr1 = hashpass1; }
	/*
	** use the SHA1 hash of the password string as the Key Migration Authorization Data
	*/
	if (migpass != NULL) { TSS_sha1(migpass,strlen(migpass),hashpass3); aptr3 = hashpass3; }
	/*
	** use the SHA1 hash of the password string as the Key Migration Authorization Data
	*/
	if (migkeypass != NULL) { TSS_sha1(migkeypass,strlen(migkeypass),hashpass4); aptr4 = hashpass4; }
	
	/*
	 * 
	 * - Create an RSA key pair.
	 * - Call TPM_AuthorizeMigrationKey for the RSA public key authorization
	 * - Call TPM_CreateMigrationBlob   with the result from AuthorizeMigrationKey
	 *                                  and the encrypted TPM_STORE_ASYMKEY structure
	 * 
	 */

	/*
	 * readthe msa list from the file.
	 */
	ret = TPM_ReadMSAFile(msa_list_filename, &msaList);
	if ( ( ret & ERR_MASK ) != 0) {
		printf("Error while reading msa list file.\n");
		exit(-1);
	}

	/*
	** create and wrap an asymmetric key and get back the
	** resulting keydata structure with the public and encrypted
	** private keys filled in by the TPM
	*/
	
	/*
	 * q is the key that we want to migrate. Create one such key.
	 * migkey is the (public) key part from another TPM that we want to use 
	 *   to migrate q. Since I am not loading a public key from another TPM,
	 *   I create a migration key here as well. I must never refer to this
	 *   key via any handle or load it into the TPM
	 */
	
	printf("Loading the (public) key to use for migration...\n");
	if (0 == ret) {
		printf("Migration key is: %s\n",migkeyfile);
		ret = TPM_ReadKeyfile(migkeyfile, &migkey);
		if ((ret & ERR_MASK)) {
			ret = TPM_ReadPubKeyfile(migkeyfile, &migkey.pub);
			if ((ret & ERR_MASK)) {
				printf("Could not read the keyfile %s as a "
				       "key or a pubkey.\n", migkeyfile);
				exit(-1);
			}
		}
		ret = TPM_ReadKeyfile(keyfile, &q);
		if ((ret & ERR_MASK)) {
			printf("Could not read the keyfile %s.\n",
			       keyfile);
		}
	}
	
	/*
	 * Create a ticket if needed.
	 */
	if (migscheme == TPM_MS_RESTRICT_APPROVE) {
		keydata signingkey;
		unsigned char signatureValue[2048];
		uint32_t signatureValueSize = sizeof(signatureValue);
		STACK_TPM_BUFFER(sigkey)
		
		/*
		 * Get the public key part of the signing key.
		 */
		ret = TPM_GetPubKey(sigkeyhandle,
		                    sigkeypassptr,
		                    &signingkey.pub);
		if ( 0 != ret ) {
			printf("Error %s while retrieving public signing key.\n", 
			       TPM_GetErrMsg(ret));
			exit(-1);
		}

		/*
		 * Build the restrictTicket!!!
		 */
		restrictTicketParameter = &restrictTicket;	/* command needs restrictTicket */     
		ret = TPM_HashPubKey(&q,
		                     restrictTicket.sourceKeyDigest);

		if ( ( ret & ERR_MASK ) != 0) {
			printf("Could not calculate hash over the public key of the key to be migrated.\n");
			exit(ret);
		}
		
		ret = TPM_HashPubKey(&migkey,
		                     restrictTicket.destinationKeyDigest);

		if ( ( ret & ERR_MASK ) != 0) {
			printf("Could not calculate hash over the public key of the migration key.\n");
			exit(ret);
		}

		ret = TPM_HashCMKAuth(&restrictTicket, resTicketHash);

		ret = TPM_Sign(sigkeyhandle, sigkeypassptr,
		               resTicketHash, sizeof(resTicketHash),
		               signatureValue, &signatureValueSize);

		if ( 0 != ret) {
			printf("Error %s while sigining.\n",
			       TPM_GetErrMsg(ret));
			exit(ret);
		}


		ret = TPM_CMK_CreateTicket(&signingkey,
		                           resTicketHash,
		                           signatureValue, signatureValueSize,
		                           passptr1,
		                           sigTicket);
		sigTicketSize = TPM_DIGEST_SIZE;
		
	}
	else {	/* TPM_MS_RESTRICT_MIGRATE */
	    restrictTicketParameter = NULL;	/* command does not need restrictTicket */     
	}
	if (0 == ret) {
		if (0 == ret) {

			STACK_TPM_BUFFER( keyblob)
			STACK_TPM_BUFFER( migblob);
			keydata keyd;

			memset(&keyd, 0x0, sizeof(keyd));

			ret = TPM_WriteKeyPub(&keyblob, &migkey);

			if ((ret & ERR_MASK) != 0) {
				printf("Could not serialize the keydata: %s\n",
				       TPM_GetErrMsg(ret));
				exit(-1);
			}

			ret = TPM_AuthorizeMigrationKey(passptr1,
			                                migscheme,         // migration scheme
			                                &keyblob,  // public key to be authorized
			                                &migblob);
			if (0 == ret) {
				unsigned char rndblob[1024];
				uint32_t rndblen = sizeof(rndblob);
				unsigned char outblob[1024];
				uint32_t outblen = sizeof(outblob);
				unsigned char sourceKeyDigest[TPM_DIGEST_SIZE];

				unsigned char encblob[1024];
				uint32_t encblen;
				
				memcpy(encblob,
				       q.encData.buffer,
				       q.encData.size);
				encblen = q.encData.size;

				if (0!= ret) {
					printf("Error occurred while creating encrypted blob.\n");
					exit (-1);
				}
				
				TPM_HashPubKey(&q,sourceKeyDigest);
				
				printf("parhandle = %x\n",parhandle);
				/*
				 * Now call the TPM_CreateMigrationBlob function.
				 */
				ret = TPM_CMK_CreateBlob(parhandle,         // handle of a key that can decrypt the encblob below
				                         aptr1,             // password for that parent key
				                         migscheme,
				                         &migblob,
				                         sourceKeyDigest,
				                         &msaList,
				                         restrictTicketParameter,	/* either NULL or restrictTicket */
				                         sigTicket, sigTicketSize,
				                         encblob, encblen,  // encrypted private key that will show up re-encrypted in outblob
				                         rndblob, &rndblen, // output: used for xor encryption
				                         outblob, &outblen);// output: re-encrypted private key
				if (0 == ret) {
					if (NULL != filename) {
						STACK_TPM_BUFFER(keybuf)
						// serialize the key in 'q'
						ret = TPM_WriteKey(&keybuf,&q);
						if (ret > 0) {
							unsigned int keybuflen = ret;
							FILE * f = fopen(filename,"wb");
							if (NULL != f) {
								struct tpm_buffer * filebuf = TSS_AllocTPMBuffer(10240);
								if (NULL != filebuf) {
									int l;
									l = TSS_buildbuff("@ @ @",filebuf,
									                   rndblen, rndblob,
									                     outblen, outblob,
									                       keybuflen, keybuf.buffer);
									fwrite(filebuf->buffer,
									       l,
									       1,
									       f);
									fclose(f);
									TSS_FreeTPMBuffer(filebuf);
									printf("Wrote migration blob and associated data to file.\n");
									ret = 0;
									
								} else {
									printf("Error. Could not allocate memory.\n");
									ret = -1;
								}
							} else {
								printf("Error. Could not write blob to file.\n");
								ret = -1;
							}
						} else {
							printf("Error while serializing key!\n");
						}
					} else {
					}
				} else {
					printf("CMK_CreateBlob returned '%s' (%d).\n",
					       TPM_GetErrMsg(ret),
					       ret);
				}

			} else {
				printf("AuthorizeMigrationKey returned '%s' (0x%x).\n",
				       TPM_GetErrMsg(ret),
				       ret);
			}

		} else {
		}
	} else {
	}
	return ret;
}
Example #6
0
int main(int argc, char *argv[])
{
    int ret;			/* general return value */
    uint32_t keyhandle = 0;	/* handle of quote key */
    unsigned int pcrmask = 0;	/* pcr register mask */
    unsigned char passhash1[TPM_HASH_SIZE];	/* hash of key password */
    unsigned char nonce[TPM_NONCE_SIZE];	/* nonce data */

    STACK_TPM_BUFFER(signature);
    pubkeydata pubkey;	/* public key structure */
    unsigned char *passptr;
    TPM_PCR_COMPOSITE tpc;
    STACK_TPM_BUFFER (ser_tpc);
    STACK_TPM_BUFFER (ser_tqi);
    STACK_TPM_BUFFER (response);
    uint32_t pcrs;
    int i;
    uint16_t sigscheme = TPM_SS_RSASSAPKCS1v15_SHA1;
    TPM_PCR_SELECTION tps;
    static char *keypass = NULL;
    const char *certFilename = NULL;
    int verbose = FALSE;
    
    TPM_setlog(0);		/* turn off verbose output from TPM driver */
    for (i=1 ; i<argc ; i++) {
	if (strcmp(argv[i],"-hk") == 0) {
	    i++;
	    if (i < argc) {
		/* convert key handle from hex */
		if (1 != sscanf(argv[i], "%x", &keyhandle)) {
		    printf("Invalid -hk argument '%s'\n",argv[i]);
		    exit(2);
		}
		if (keyhandle == 0) {
		    printf("Invalid -hk argument '%s'\n",argv[i]);
		    exit(2);
		}		 
	    }
	    else {
		printf("-hk option needs a value\n");
		printUsage();
	    }
	}
	else if (!strcmp(argv[i], "-pwdk")) {
	    i++;
	    if (i < argc) {
		keypass = argv[i];
	    }
	    else {
		printf("Missing parameter to -pwdk\n");
		printUsage();
	    }
	}
	else if (strcmp(argv[i],"-bm") == 0) {
	    i++;
	    if (i < argc) {
		/* convert key handle from hex */
		if (1 != sscanf(argv[i], "%x", &pcrmask)) {
		    printf("Invalid -bm argument '%s'\n",argv[i]);
		    exit(2);
		}
	    }
	    else {
		printf("-bm option needs a value\n");
		printUsage();
	    }
	}
	else if (!strcmp(argv[i], "-cert")) {
	    i++;
	    if (i < argc) {
		certFilename = argv[i];
	    }
	    else {
		printf("Missing parameter to -cert\n");
		printUsage();
	    }
	}
	else if (!strcmp(argv[i], "-h")) {
	    printUsage();
	}
	else if (!strcmp(argv[i], "-v")) {
	    verbose = TRUE;
	    TPM_setlog(1);
	}
	else {
	    printf("\n%s is not a valid option\n", argv[i]);
	    printUsage();
	}
    }
    if ((keyhandle == 0) ||
	(pcrmask == 0)) {
	printf("Missing argument\n");
	printUsage();
    }
    /* get the SHA1 hash of the password string for use as the Key Authorization Data */
    if (keypass != NULL) {
	TSS_sha1((unsigned char *)keypass, strlen(keypass), passhash1);
	passptr = passhash1;
    }
    else {
	passptr = NULL;
    }
    /* for testing, use the password hash as the test nonce */
    memcpy(nonce, passhash1, TPM_HASH_SIZE);
	
    ret = TPM_GetNumPCRRegisters(&pcrs);
    if (ret != 0) {
	printf("Error reading number of PCR registers.\n");
	exit(-1);
    }
    if (pcrs > TPM_NUM_PCR) {
	printf("Library does not support that many PCRs.\n");
	exit(-1);
    }
	
    tps.sizeOfSelect = pcrs / 8;
    for (i = 0; i < tps.sizeOfSelect; i++) {
	tps.pcrSelect[i] = (pcrmask & 0xff);
	pcrmask >>= 8;
    }
    /*
    ** perform the TPM Quote function
    */
    ret = TPM_Quote(keyhandle,	/* KEY handle */
		    passptr,	/* Key Password (hashed), or null */
		    nonce,	        /* nonce data */
		    &tps,	        /* specify PCR registers */
		    &tpc,		/* pointer to pcr composite */
		    &signature);/* buffer to receive result, int to receive result length */
    if (ret != 0) {
	printf("Error '%s' from TPM_Quote\n", TPM_GetErrMsg(ret));
	exit(ret);
    }
    /*
    ** Get the public key and convert to an OpenSSL RSA public key
    */
    ret = TPM_GetPubKey(keyhandle, passptr, &pubkey);
    if (ret != 0) {
	printf("quote: Error '%s' from TPM_GetPubKey\n", TPM_GetErrMsg(ret));
	exit(-6);
    }
	
    ret = TPM_ValidatePCRCompositeSignature(&tpc,
					    nonce,
					    &pubkey,
					    &signature,
					    sigscheme);
    if (ret) {
	printf("Error %s from validating the signature over the PCR composite.\n",
	       TPM_GetErrMsg(ret));
	exit(ret);
    }
    printf("Verification against AIK succeeded\n");

    /* optionally verify the quote signature against the key certificate */
    if (certFilename != NULL) {
	unsigned char *certStream = NULL;	/* freed @1 */
	uint32_t certStreamLength;
	X509 *x509Certificate = NULL;		/* freed @2 */
	unsigned char 	*tmpPtr;		/* because d2i_X509 moves the ptr */
	
	/* AIK public key parts */
	RSA *rsaKey = NULL; 			/* freed @3 */

	if (verbose) printf("quote: verifying the signature against the certificate\n");
	/* load the key certificate */
	if (ret == 0) {
	    ret = TPM_ReadFile(certFilename,
			       &certStream,	/* freed @1 */
			       &certStreamLength);
	}
	/* convert to openssl X509 */
	if (ret == 0) {
	    if (verbose) printf("quote: parsing the certificate stream\n");
	    tmpPtr = certStream;
	    x509Certificate = d2i_X509(NULL,
				       (const unsigned char **)&tmpPtr, certStreamLength);
	    if (x509Certificate == NULL) {
		printf("Error in certificate deserialization d2i_X509()\n");
		ret = -1;
	    }
	}
	if (ret == 0) {
	    if (verbose) printf("quote: get the certificate public key\n");
	    ret = GetRSAKey(&rsaKey,	/* freed @3 */
			    x509Certificate);
	}
	if (ret == 0) {
	    if (verbose) printf("quote: quote validate signature\n");
	    ret = TPM_ValidatePCRCompositeSignatureRSA(&tpc,
						       nonce,
						       rsaKey,
						       &signature,
						       sigscheme);
	    if (ret != 0) {
		printf("Verification against certificate failed\n");
	    }
	}
	if (ret == 0) {
	    printf("Verification against certificate succeeded\n");
	}
	free(certStream);		/* @1 */
	X509_free(x509Certificate); 	/* @2 */
	RSA_free(rsaKey);		/* @3 */
    }
    exit(ret);
}