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. 2004-2007 8 * 9 */ 10 11 #include <stdlib.h> 12 #include <stdio.h> 13 #include <syslog.h> 14 #include <string.h> 15 #include <netdb.h> 16 #if (defined (__OpenBSD__) || defined (__FreeBSD__) || defined(__NetBSD__)) 17 #include <sys/types.h> 18 #include <sys/socket.h> 19 #include <netinet/in.h> 20 #endif 21 #include <errno.h> 22 23 #include "trousers/tss.h" 24 #include "trousers_types.h" 25 #include "tcs_tsp.h" 26 #include "tcs_utils.h" 27 #include "tcs_int_literals.h" 28 #include "capabilities.h" 29 #include "tcslog.h" 30 #include "tcsd_wrap.h" 31 #include "tcsd.h" 32 #include "rpc_tcstp_tcs.h" 33 34 35 /* Lock is not static because we need to reference it in the auth manager */ 36 MUTEX_DECLARE_INIT(tcsp_lock); 37 38 39 void 40 LoadBlob_Auth_Special(UINT64 *offset, BYTE *blob, TPM_AUTH *auth) 41 { 42 LoadBlob(offset, TCPA_SHA1BASED_NONCE_LEN, blob, auth->NonceEven.nonce); 43 LoadBlob_BOOL(offset, auth->fContinueAuthSession, blob); 44 LoadBlob(offset, TCPA_SHA1BASED_NONCE_LEN, blob, (BYTE *)&auth->HMAC); 45 } 46 47 void 48 UnloadBlob_Auth_Special(UINT64 *offset, BYTE *blob, TPM_AUTH *auth) 49 { 50 UnloadBlob_UINT32(offset, &auth->AuthHandle, blob); 51 UnloadBlob(offset, TCPA_SHA1BASED_NONCE_LEN, blob, auth->NonceOdd.nonce); 52 UnloadBlob_BOOL(offset, &auth->fContinueAuthSession, blob); 53 UnloadBlob(offset, TCPA_SHA1BASED_NONCE_LEN, blob, (BYTE *)&auth->HMAC); 54 } 55 56 int 57 recv_from_socket(int sock, void *buffer, int size) 58 { 59 int recv_size = 0, recv_total = 0; 60 61 while (recv_total < size) { 62 errno = 0; 63 if ((recv_size = recv(sock, buffer+recv_total, size-recv_total, 0)) <= 0) { 64 if (recv_size < 0) { 65 if (errno == EINTR) 66 continue; 67 LogError("Socket receive connection error: %s.", strerror(errno)); 68 } else { 69 LogDebug("Socket connection closed."); 70 } 71 72 return -1; 73 } 74 recv_total += recv_size; 75 } 76 77 return recv_total; 78 } 79 80 int 81 send_to_socket(int sock, void *buffer, int size) 82 { 83 int send_size = 0, send_total = 0; 84 85 while (send_total < size) { 86 if ((send_size = send(sock, buffer+send_total, size-send_total, 0)) < 0) { 87 LogError("Socket send connection error: %s.", strerror(errno)); 88 return -1; 89 } 90 send_total += send_size; 91 } 92 93 return send_total; 94 } 95 96 97 void 98 initData(struct tcsd_comm_data *comm, int parm_count) 99 { 100 /* min packet size should be the size of the header */ 101 memset(&comm->hdr, 0, sizeof(struct tcsd_packet_hdr)); 102 comm->hdr.packet_size = sizeof(struct tcsd_packet_hdr); 103 if (parm_count > 0) { 104 comm->hdr.type_offset = sizeof(struct tcsd_packet_hdr); 105 comm->hdr.parm_offset = comm->hdr.type_offset + 106 (sizeof(TCSD_PACKET_TYPE) * parm_count); 107 comm->hdr.packet_size = comm->hdr.parm_offset; 108 } 109 110 memset(comm->buf, 0, comm->buf_size); 111 } 112 113 int 114 loadData(UINT64 *offset, TCSD_PACKET_TYPE data_type, void *data, int data_size, BYTE *blob) 115 { 116 switch (data_type) { 117 case TCSD_PACKET_TYPE_BYTE: 118 LoadBlob_BYTE(offset, *((BYTE *) (data)), blob); 119 break; 120 case TCSD_PACKET_TYPE_BOOL: 121 LoadBlob_BOOL(offset, *((TSS_BOOL *) (data)), blob); 122 break; 123 case TCSD_PACKET_TYPE_UINT16: 124 LoadBlob_UINT16(offset, *((UINT16 *) (data)), blob); 125 break; 126 case TCSD_PACKET_TYPE_UINT32: 127 LoadBlob_UINT32(offset, *((UINT32 *) (data)), blob); 128 break; 129 case TCSD_PACKET_TYPE_UINT64: 130 LoadBlob_UINT64(offset, *((UINT64 *) (data)), blob); 131 break; 132 case TCSD_PACKET_TYPE_PBYTE: 133 LoadBlob(offset, data_size, blob, data); 134 break; 135 case TCSD_PACKET_TYPE_NONCE: 136 LoadBlob(offset, sizeof(TCPA_NONCE), blob, ((TCPA_NONCE *)data)->nonce); 137 break; 138 case TCSD_PACKET_TYPE_DIGEST: 139 LoadBlob(offset, sizeof(TCPA_DIGEST), blob, ((TCPA_DIGEST *)data)->digest); 140 break; 141 case TCSD_PACKET_TYPE_AUTH: 142 LoadBlob_Auth_Special(offset, blob, ((TPM_AUTH *)data)); 143 break; 144 #ifdef TSS_BUILD_PS 145 case TCSD_PACKET_TYPE_UUID: 146 LoadBlob_UUID(offset, blob, *((TSS_UUID *)data)); 147 break; 148 case TCSD_PACKET_TYPE_KM_KEYINFO: 149 LoadBlob_KM_KEYINFO(offset, blob, ((TSS_KM_KEYINFO *)data)); 150 break; 151 case TCSD_PACKET_TYPE_KM_KEYINFO2: 152 LoadBlob_KM_KEYINFO2(offset, blob, ((TSS_KM_KEYINFO2 *)data)); 153 break; 154 case TCSD_PACKET_TYPE_LOADKEY_INFO: 155 LoadBlob_LOADKEY_INFO(offset, blob, ((TCS_LOADKEY_INFO *)data)); 156 break; 157 #endif 158 case TCSD_PACKET_TYPE_ENCAUTH: 159 LoadBlob(offset, sizeof(TCPA_ENCAUTH), blob, 160 ((TCPA_ENCAUTH *)data)->authdata); 161 break; 162 case TCSD_PACKET_TYPE_VERSION: 163 LoadBlob_VERSION(offset, blob, ((TPM_VERSION *)data)); 164 break; 165 #ifdef TSS_BUILD_PCR_EVENTS 166 case TCSD_PACKET_TYPE_PCR_EVENT: 167 LoadBlob_PCR_EVENT(offset, blob, ((TSS_PCR_EVENT *)data)); 168 break; 169 #endif 170 case TCSD_PACKET_TYPE_SECRET: 171 LoadBlob(offset, sizeof(TCPA_SECRET), blob, 172 ((TCPA_SECRET *)data)->authdata); 173 break; 174 default: 175 LogError("TCSD packet type unknown! (0x%x)", data_type & 0xff); 176 return TCSERR(TSS_E_INTERNAL_ERROR); 177 } 178 179 return TSS_SUCCESS; 180 } 181 182 183 int 184 setData(TCSD_PACKET_TYPE dataType, 185 unsigned int index, 186 void *theData, 187 int theDataSize, 188 struct tcsd_comm_data *comm) 189 { 190 UINT64 old_offset, offset; 191 TSS_RESULT result; 192 TCSD_PACKET_TYPE *type; 193 194 /* Calculate the size of the area needed (use NULL for blob address) */ 195 offset = 0; 196 if ((result = loadData(&offset, dataType, theData, theDataSize, NULL)) != TSS_SUCCESS) 197 return result; 198 199 if ((comm->hdr.packet_size + offset) > comm->buf_size) { 200 /* reallocate the buffer */ 201 BYTE *buffer; 202 int buffer_size = comm->hdr.packet_size + offset; 203 204 LogDebug("Increasing communication buffer to %d bytes.", buffer_size); 205 buffer = realloc(comm->buf, buffer_size); 206 if (buffer == NULL) { 207 LogError("realloc of %d bytes failed.", buffer_size); 208 return TCSERR(TSS_E_INTERNAL_ERROR); 209 } 210 comm->buf_size = buffer_size; 211 comm->buf = buffer; 212 } 213 214 offset = old_offset = comm->hdr.parm_offset + comm->hdr.parm_size; 215 if ((result = loadData(&offset, dataType, theData, theDataSize, comm->buf)) != TSS_SUCCESS) 216 return result; 217 type = (TCSD_PACKET_TYPE *)(comm->buf + comm->hdr.type_offset) + index; 218 *type = dataType; 219 comm->hdr.type_size += sizeof(TCSD_PACKET_TYPE); 220 comm->hdr.parm_size += (offset - old_offset); 221 222 comm->hdr.packet_size = offset; 223 comm->hdr.num_parms++; 224 225 return TSS_SUCCESS; 226 } 227 228 UINT32 229 getData(TCSD_PACKET_TYPE dataType, 230 unsigned int index, 231 void *theData, 232 int theDataSize, 233 struct tcsd_comm_data *comm) 234 { 235 UINT64 old_offset, offset; 236 TCSD_PACKET_TYPE *type; 237 238 if ((comm->hdr.type_offset + index) > comm->buf_size) 239 return TSS_TCP_RPC_BAD_PACKET_TYPE; 240 241 type = (comm->buf + comm->hdr.type_offset) + index; 242 243 if ((UINT32)index >= comm->hdr.num_parms || dataType != *type) { 244 LogDebug("Data type of TCS packet element %d doesn't match.", index); 245 return TSS_TCP_RPC_BAD_PACKET_TYPE; 246 } 247 old_offset = offset = comm->hdr.parm_offset; 248 switch (dataType) { 249 case TCSD_PACKET_TYPE_BYTE: 250 if (old_offset + sizeof(BYTE) > comm->hdr.packet_size) 251 return TCSERR(TSS_E_INTERNAL_ERROR); 252 253 UnloadBlob_BYTE(&offset, (BYTE *) (theData), comm->buf); 254 break; 255 case TCSD_PACKET_TYPE_BOOL: 256 if (old_offset + sizeof(TSS_BOOL) > comm->hdr.packet_size) 257 return TCSERR(TSS_E_INTERNAL_ERROR); 258 259 UnloadBlob_BOOL(&offset, (TSS_BOOL *) (theData), comm->buf); 260 break; 261 case TCSD_PACKET_TYPE_UINT16: 262 if (old_offset + sizeof(UINT16) > comm->hdr.packet_size) 263 return TCSERR(TSS_E_INTERNAL_ERROR); 264 265 UnloadBlob_UINT16(&offset, (UINT16 *) (theData), comm->buf); 266 break; 267 case TCSD_PACKET_TYPE_UINT32: 268 if (old_offset + sizeof(UINT32) > comm->hdr.packet_size) 269 return TCSERR(TSS_E_INTERNAL_ERROR); 270 271 UnloadBlob_UINT32(&offset, (UINT32 *) (theData), comm->buf); 272 break; 273 case TCSD_PACKET_TYPE_PBYTE: 274 if (old_offset + theDataSize > comm->hdr.packet_size) 275 return TCSERR(TSS_E_INTERNAL_ERROR); 276 277 UnloadBlob(&offset, theDataSize, comm->buf, theData); 278 break; 279 case TCSD_PACKET_TYPE_NONCE: 280 if (old_offset + sizeof(TPM_NONCE) > comm->hdr.packet_size) 281 return TCSERR(TSS_E_INTERNAL_ERROR); 282 283 UnloadBlob(&offset, sizeof(TCPA_NONCE), comm->buf, 284 ((TCPA_NONCE *) (theData))->nonce); 285 break; 286 case TCSD_PACKET_TYPE_DIGEST: 287 if (old_offset + sizeof(TPM_DIGEST) > comm->hdr.packet_size) 288 return TCSERR(TSS_E_INTERNAL_ERROR); 289 290 UnloadBlob(&offset, sizeof(TCPA_DIGEST), comm->buf, 291 ((TCPA_DIGEST *) (theData))->digest); 292 break; 293 case TCSD_PACKET_TYPE_AUTH: 294 if ((old_offset + sizeof(TCS_AUTHHANDLE) 295 + sizeof(TPM_BOOL) 296 + (2 * sizeof(TPM_NONCE))) > comm->hdr.packet_size) 297 return TCSERR(TSS_E_INTERNAL_ERROR); 298 299 UnloadBlob_Auth_Special(&offset, comm->buf, ((TPM_AUTH *) theData)); 300 break; 301 case TCSD_PACKET_TYPE_ENCAUTH: 302 if (old_offset + sizeof(TPM_ENCAUTH) > comm->hdr.packet_size) 303 return TCSERR(TSS_E_INTERNAL_ERROR); 304 305 UnloadBlob(&offset, sizeof(TCPA_ENCAUTH), comm->buf, 306 ((TCPA_ENCAUTH *) theData)->authdata); 307 break; 308 case TCSD_PACKET_TYPE_VERSION: 309 if (old_offset + sizeof(TPM_VERSION) > comm->hdr.packet_size) 310 return TCSERR(TSS_E_INTERNAL_ERROR); 311 312 UnloadBlob_VERSION(&offset, comm->buf, ((TPM_VERSION *) theData)); 313 break; 314 #ifdef TSS_BUILD_PS 315 case TCSD_PACKET_TYPE_KM_KEYINFO: 316 UnloadBlob_KM_KEYINFO(&old_offset, comm->buf, NULL); 317 318 if (old_offset > comm->hdr.packet_size) 319 return TCSERR(TSS_E_INTERNAL_ERROR); 320 321 old_offset = offset; 322 UnloadBlob_KM_KEYINFO(&offset, comm->buf, ((TSS_KM_KEYINFO *)theData)); 323 break; 324 case TCSD_PACKET_TYPE_LOADKEY_INFO: 325 UnloadBlob_LOADKEY_INFO(&old_offset, comm->buf, NULL); 326 327 if (old_offset > comm->hdr.packet_size) 328 return TCSERR(TSS_E_INTERNAL_ERROR); 329 330 old_offset = offset; 331 UnloadBlob_LOADKEY_INFO(&offset, comm->buf, ((TCS_LOADKEY_INFO *)theData)); 332 break; 333 case TCSD_PACKET_TYPE_UUID: 334 if (old_offset + sizeof(TSS_UUID) > comm->hdr.packet_size) 335 return TCSERR(TSS_E_INTERNAL_ERROR); 336 337 UnloadBlob_UUID(&offset, comm->buf, (TSS_UUID *) theData); 338 break; 339 #endif 340 #ifdef TSS_BUILD_PCR_EVENTS 341 case TCSD_PACKET_TYPE_PCR_EVENT: 342 { 343 TSS_RESULT result; 344 345 (void)UnloadBlob_PCR_EVENT(&old_offset, comm->buf, NULL); 346 347 if (old_offset > comm->hdr.packet_size) 348 return TCSERR(TSS_E_INTERNAL_ERROR); 349 350 old_offset = offset; 351 if ((result = UnloadBlob_PCR_EVENT(&offset, comm->buf, 352 ((TSS_PCR_EVENT *)theData)))) 353 return result; 354 break; 355 } 356 #endif 357 case TCSD_PACKET_TYPE_SECRET: 358 if (old_offset + sizeof(TPM_SECRET) > comm->hdr.packet_size) 359 return TCSERR(TSS_E_INTERNAL_ERROR); 360 361 UnloadBlob(&offset, sizeof(TCPA_SECRET), comm->buf, 362 ((TCPA_SECRET *) theData)->authdata); 363 break; 364 default: 365 LogError("TCSD packet type unknown! (0x%x)", dataType & 0xff); 366 return TCSERR(TSS_E_INTERNAL_ERROR); 367 } 368 comm->hdr.parm_offset = offset; 369 comm->hdr.parm_size -= (offset - old_offset); 370 371 return TSS_SUCCESS; 372 } 373 374 TSS_RESULT 375 tcs_wrap_Error(struct tcsd_thread_data *data) 376 { 377 LogError("%s reached.", __FUNCTION__); 378 379 initData(&data->comm, 0); 380 381 data->comm.hdr.u.result = TCSERR(TSS_E_FAIL); 382 383 return TSS_SUCCESS; 384 385 } 386 387 /* Dispatch */ 388 typedef struct tdDispatchTable { 389 TSS_RESULT (*Func) (struct tcsd_thread_data *); 390 const char *name; 391 } DispatchTable; 392 393 DispatchTable tcs_func_table[TCSD_MAX_NUM_ORDS] = { 394 {tcs_wrap_Error,"Error"}, /* 0 */ 395 {tcs_wrap_OpenContext,"OpenContext"}, 396 {tcs_wrap_CloseContext,"CloseContext"}, 397 {tcs_wrap_Error,"Error"}, 398 {tcs_wrap_TCSGetCapability,"TCSGetCapability"}, 399 {tcs_wrap_RegisterKey,"RegisterKey"}, /* 5 */ 400 {tcs_wrap_UnregisterKey,"UnregisterKey"}, 401 {tcs_wrap_EnumRegisteredKeys,"EnumRegisteredKeys"}, 402 {tcs_wrap_Error,"Error"}, 403 {tcs_wrap_GetRegisteredKeyBlob,"GetRegisteredKeyBlob"}, 404 {tcs_wrap_GetRegisteredKeyByPublicInfo,"GetRegisteredKeyByPublicInfo"}, /* 10 */ 405 {tcs_wrap_LoadKeyByBlob,"LoadKeyByBlob"}, 406 {tcs_wrap_LoadKeyByUUID,"LoadKeyByUUID"}, 407 {tcs_wrap_EvictKey,"EvictKey"}, 408 {tcs_wrap_CreateWrapKey,"CreateWrapKey"}, 409 {tcs_wrap_GetPubkey,"GetPubkey"}, /* 15 */ 410 {tcs_wrap_MakeIdentity,"MakeIdentity"}, 411 {tcs_wrap_LogPcrEvent,"LogPcrEvent"}, 412 {tcs_wrap_GetPcrEvent,"GetPcrEvent"}, 413 {tcs_wrap_GetPcrEventsByPcr,"GetPcrEventsByPcr"}, 414 {tcs_wrap_GetPcrEventLog,"GetPcrEventLog"}, /* 20 */ 415 {tcs_wrap_SetOwnerInstall,"SetOwnerInstall"}, 416 {tcs_wrap_TakeOwnership,"TakeOwnership"}, 417 {tcs_wrap_OIAP,"OIAP"}, 418 {tcs_wrap_OSAP,"OSAP"}, 419 {tcs_wrap_ChangeAuth,"ChangeAuth"}, /* 25 */ 420 {tcs_wrap_ChangeAuthOwner,"ChangeAuthOwner"}, 421 {tcs_wrap_Error,"Error"}, 422 {tcs_wrap_Error,"Error"}, 423 {tcs_wrap_TerminateHandle,"TerminateHandle"}, 424 {tcs_wrap_ActivateIdentity,"ActivateIdentity"}, /* 30 */ 425 {tcs_wrap_Extend,"Extend"}, 426 {tcs_wrap_PcrRead,"PcrRead"}, 427 {tcs_wrap_Quote,"Quote"}, 428 {tcs_wrap_DirWriteAuth,"DirWriteAuth"}, 429 {tcs_wrap_DirRead,"DirRead"}, /* 35 */ 430 {tcs_wrap_Seal,"Seal"}, 431 {tcs_wrap_UnSeal,"UnSeal"}, 432 {tcs_wrap_UnBind,"UnBind"}, 433 {tcs_wrap_CreateMigrationBlob,"CreateMigrationBlob"}, 434 {tcs_wrap_ConvertMigrationBlob,"ConvertMigrationBlob"}, /* 40 */ 435 {tcs_wrap_AuthorizeMigrationKey,"AuthorizeMigrationKey"}, 436 {tcs_wrap_CertifyKey,"CertifyKey"}, 437 {tcs_wrap_Sign,"Sign"}, 438 {tcs_wrap_GetRandom,"GetRandom"}, 439 {tcs_wrap_StirRandom,"StirRandom"}, /* 45 */ 440 {tcs_wrap_GetCapability,"GetCapability"}, 441 {tcs_wrap_Error,"Error"}, 442 {tcs_wrap_GetCapabilityOwner,"GetCapabilityOwner"}, 443 {tcs_wrap_CreateEndorsementKeyPair,"CreateEndorsementKeyPair"}, 444 {tcs_wrap_ReadPubek,"ReadPubek"}, /* 50 */ 445 {tcs_wrap_DisablePubekRead,"DisablePubekRead"}, 446 {tcs_wrap_OwnerReadPubek,"OwnerReadPubek"}, 447 {tcs_wrap_SelfTestFull,"SelfTestFull"}, 448 {tcs_wrap_CertifySelfTest,"CertifySelfTest"}, 449 {tcs_wrap_Error,"Error"}, /* 55 */ 450 {tcs_wrap_GetTestResult,"GetTestResult"}, 451 {tcs_wrap_OwnerSetDisable,"OwnerSetDisable"}, 452 {tcs_wrap_OwnerClear,"OwnerClear"}, 453 {tcs_wrap_DisableOwnerClear,"DisableOwnerClear"}, 454 {tcs_wrap_ForceClear,"ForceClear"}, /* 60 */ 455 {tcs_wrap_DisableForceClear,"DisableForceClear"}, 456 {tcs_wrap_PhysicalDisable,"PhysicalDisable"}, 457 {tcs_wrap_PhysicalEnable,"PhysicalEnable"}, 458 {tcs_wrap_PhysicalSetDeactivated,"PhysicalSetDeactivated"}, 459 {tcs_wrap_SetTempDeactivated,"SetTempDeactivated"}, /* 65 */ 460 {tcs_wrap_PhysicalPresence,"PhysicalPresence"}, 461 {tcs_wrap_Error,"Error"}, 462 {tcs_wrap_Error,"Error"}, 463 {tcs_wrap_CreateMaintenanceArchive,"CreateMaintenanceArchive"}, 464 {tcs_wrap_LoadMaintenanceArchive,"LoadMaintenanceArchive"}, /* 70 */ 465 {tcs_wrap_KillMaintenanceFeature,"KillMaintenanceFeature"}, 466 {tcs_wrap_LoadManuMaintPub,"LoadManuMaintPub"}, 467 {tcs_wrap_ReadManuMaintPub,"ReadManuMaintPub"}, 468 {tcs_wrap_DaaJoin,"DaaJoin"}, 469 {tcs_wrap_DaaSign,"DaaSign"}, /* 75 */ 470 {tcs_wrap_SetCapability,"SetCapability"}, 471 {tcs_wrap_ResetLockValue,"ResetLockValue"}, 472 {tcs_wrap_PcrReset,"PcrReset"}, 473 {tcs_wrap_ReadCounter,"ReadCounter"}, 474 {tcs_wrap_CreateCounter,"CreateCounter"}, /* 80 */ 475 {tcs_wrap_IncrementCounter,"IncrementCounter"}, 476 {tcs_wrap_ReleaseCounter,"ReleaseCounter"}, 477 {tcs_wrap_ReleaseCounterOwner,"ReleaseCounterOwner"}, 478 {tcs_wrap_ReadCurrentTicks,"ReadCurrentTicks"}, 479 {tcs_wrap_TickStampBlob,"TicksStampBlob"}, /* 85 */ 480 {tcs_wrap_GetCredential,"GetCredential"}, 481 {tcs_wrap_NV_DefineOrReleaseSpace,"NVDefineOrReleaseSpace"}, 482 {tcs_wrap_NV_WriteValue,"NVWriteValue"}, 483 {tcs_wrap_NV_WriteValueAuth,"NVWriteValueAuth"}, 484 {tcs_wrap_NV_ReadValue,"NVReadValue"}, /* 90 */ 485 {tcs_wrap_NV_ReadValueAuth,"NVReadValueAuth"}, 486 {tcs_wrap_EstablishTransport,"EstablishTransport"}, 487 {tcs_wrap_ExecuteTransport,"ExecuteTransport"}, 488 {tcs_wrap_ReleaseTransportSigned,"ReleaseTransportSigned"}, 489 {tcs_wrap_SetOrdinalAuditStatus,"SetOrdinalAuditStatus"}, /* 95 */ 490 {tcs_wrap_GetAuditDigest,"GetAuditDigest"}, 491 {tcs_wrap_GetAuditDigestSigned,"GetAuditDigestSigned"}, 492 {tcs_wrap_Sealx,"Sealx"}, 493 {tcs_wrap_SetOperatorAuth,"SetOperatorAuth"}, 494 {tcs_wrap_OwnerReadInternalPub,"OwnerReadInternalPub"}, /* 100 */ 495 {tcs_wrap_EnumRegisteredKeys2,"EnumRegisteredKeys2"}, 496 {tcs_wrap_SetTempDeactivated2,"SetTempDeactivated2"}, 497 {tcs_wrap_Delegate_Manage,"Delegate_Manage"}, 498 {tcs_wrap_Delegate_CreateKeyDelegation,"Delegate_CreateKeyDelegation"}, 499 {tcs_wrap_Delegate_CreateOwnerDelegation,"Delegate_CreateOwnerDelegation"}, /* 105 */ 500 {tcs_wrap_Delegate_LoadOwnerDelegation,"Delegate_LoadOwnerDelegation"}, 501 {tcs_wrap_Delegate_ReadTable,"Delegate_ReadTable"}, 502 {tcs_wrap_Delegate_UpdateVerificationCount,"Delegate_UpdateVerificationCount"}, 503 {tcs_wrap_Delegate_VerifyDelegation,"Delegate_VerifyDelegation"}, 504 {tcs_wrap_CreateRevocableEndorsementKeyPair,"CreateRevocableEndorsementKeyPair"}, /* 110 */ 505 {tcs_wrap_RevokeEndorsementKeyPair,"RevokeEndorsementKeyPair"}, 506 {tcs_wrap_Error,"Error - was MakeIdentity2"}, 507 {tcs_wrap_Quote2,"Quote2"}, 508 {tcs_wrap_CMK_SetRestrictions,"CMK_SetRestrictions"}, 509 {tcs_wrap_CMK_ApproveMA,"CMK_ApproveMA"}, /* 115 */ 510 {tcs_wrap_CMK_CreateKey,"CMK_CreateKey"}, 511 {tcs_wrap_CMK_CreateTicket,"CMK_CreateTicket"}, 512 {tcs_wrap_CMK_CreateBlob,"CMK_CreateBlob"}, 513 {tcs_wrap_CMK_ConvertMigration,"CMK_ConvertMigration"}, 514 {tcs_wrap_FlushSpecific,"FlushSpecific"}, /* 120 */ 515 {tcs_wrap_KeyControlOwner, "KeyControlOwner"}, 516 {tcs_wrap_DSAP, "DSAP"} 517 }; 518 519 int 520 access_control(struct tcsd_thread_data *thread_data) 521 { 522 int i = 0; 523 int is_localhost; 524 struct sockaddr_storage sas; 525 struct sockaddr *sa; 526 socklen_t sas_len = sizeof(sas); 527 528 if (getpeername(thread_data->sock, (struct sockaddr *)&sas, 529 &sas_len) == -1) { 530 LogError("Error retrieving local socket address: %s", strerror(errno)); 531 return 1; 532 } 533 534 sa = (struct sockaddr *)&sas; 535 536 is_localhost = 0; 537 // Check if it's localhost for both inet protocols 538 if (sa->sa_family == AF_INET) { 539 struct sockaddr_in *sa_in = (struct sockaddr_in *)sa; 540 in_addr_t nloopaddr = htonl(INADDR_LOOPBACK); 541 if (memcmp(&sa_in->sin_addr.s_addr, &nloopaddr, 542 sizeof(in_addr_t)) == 0) 543 is_localhost = 1; 544 } 545 else if (sa->sa_family == AF_INET6) { 546 struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa; 547 if (memcmp(&sa_in6->sin6_addr.s6_addr, &in6addr_loopback, 548 sizeof(struct in6_addr)) == 0) 549 is_localhost = 1; 550 } 551 552 /* if the request comes from localhost, or is in the accepted ops list, 553 * approve it */ 554 if (is_localhost) 555 return 0; 556 else { 557 while (tcsd_options.remote_ops[i]) { 558 if ((UINT32)tcsd_options.remote_ops[i] == thread_data->comm.hdr.u.ordinal) { 559 LogInfo("Accepted %s operation from %s", 560 tcs_func_table[thread_data->comm.hdr.u.ordinal].name, 561 thread_data->hostname); 562 return 0; 563 } 564 i++; 565 } 566 } 567 568 return 1; 569 } 570 571 TSS_RESULT 572 dispatchCommand(struct tcsd_thread_data *data) 573 { 574 UINT64 offset; 575 TSS_RESULT result; 576 577 /* First, check the ordinal bounds */ 578 if (data->comm.hdr.u.ordinal >= TCSD_MAX_NUM_ORDS) { 579 LogError("Illegal TCSD Ordinal"); 580 return TCSERR(TSS_E_FAIL); 581 } 582 583 LogDebug("Dispatching ordinal %u (%s)", data->comm.hdr.u.ordinal, 584 tcs_func_table[data->comm.hdr.u.ordinal].name); 585 /* We only need to check access_control if there are remote operations that are defined 586 * in the config file, which means we allow remote connections */ 587 if (tcsd_options.remote_ops[0] && access_control(data)) { 588 LogWarn("Denied %s operation from %s", 589 tcs_func_table[data->comm.hdr.u.ordinal].name, data->hostname); 590 591 /* set platform header */ 592 memset(&data->comm.hdr, 0, sizeof(data->comm.hdr)); 593 data->comm.hdr.packet_size = sizeof(struct tcsd_packet_hdr); 594 data->comm.hdr.u.result = TCSERR(TSS_E_FAIL); 595 596 /* set the comm buffer */ 597 memset(data->comm.buf, 0, data->comm.buf_size); 598 offset = 0; 599 LoadBlob_UINT32(&offset, data->comm.hdr.packet_size, data->comm.buf); 600 LoadBlob_UINT32(&offset, data->comm.hdr.u.result, data->comm.buf); 601 602 return TSS_SUCCESS; 603 } 604 605 /* Now, dispatch */ 606 if ((result = tcs_func_table[data->comm.hdr.u.ordinal].Func(data)) == TSS_SUCCESS) { 607 /* set the comm buffer */ 608 offset = 0; 609 LoadBlob_UINT32(&offset, data->comm.hdr.packet_size, data->comm.buf); 610 LoadBlob_UINT32(&offset, data->comm.hdr.u.result, data->comm.buf); 611 LoadBlob_UINT32(&offset, data->comm.hdr.num_parms, data->comm.buf); 612 LoadBlob_UINT32(&offset, data->comm.hdr.type_size, data->comm.buf); 613 LoadBlob_UINT32(&offset, data->comm.hdr.type_offset, data->comm.buf); 614 LoadBlob_UINT32(&offset, data->comm.hdr.parm_size, data->comm.buf); 615 LoadBlob_UINT32(&offset, data->comm.hdr.parm_offset, data->comm.buf); 616 } 617 618 return result; 619 620 } 621 622 TSS_RESULT 623 getTCSDPacket(struct tcsd_thread_data *data) 624 { 625 if (data->comm.hdr.packet_size != 626 (UINT32)(data->comm.hdr.parm_offset + data->comm.hdr.parm_size)) { 627 LogError("Invalid packet received by TCSD"); 628 return TCSERR(TSS_E_INTERNAL_ERROR); 629 } 630 631 /* dispatch the command to the TCS */ 632 return dispatchCommand(data); 633 } 634