1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 #include <stdlib.h> 29 #include <stdio.h> 30 #include <unistd.h> 31 #include <strings.h> 32 #include <libintl.h> 33 #include <locale.h> 34 35 #include <tss/tspi.h> 36 #include <trousers/trousers.h> 37 #include "tpmadm.h" 38 39 extern cmdtable_t commands[]; 40 41 static void 42 print_usage(char *progname, cmdtable_t cmds[]) 43 { 44 cmdtable_t *p; 45 46 (void) fprintf(stderr, 47 gettext("usage: %s command args ...\n"), progname); 48 (void) fprintf(stderr, 49 gettext("where 'command' is one of the following:\n")); 50 for (p = &cmds[0]; p->name != NULL; p++) { 51 (void) fprintf(stderr, "\t%s %s\n", p->name, p->args); 52 } 53 } 54 55 int 56 main(int argc, char *argv[]) 57 { 58 char *progname; 59 cmdtable_t *p; 60 cmdfunc_t fptr = NULL; 61 int ret; 62 TSS_HCONTEXT hContext; 63 TSS_HOBJECT hTPM; 64 65 /* Set up for i18n/l10n. */ 66 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D. */ 67 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't. */ 68 #endif 69 (void) setlocale(LC_ALL, ""); 70 (void) textdomain(TEXT_DOMAIN); 71 72 progname = argv[0]; 73 argc--; 74 argv++; 75 76 if (argc <= 0) { 77 print_usage(progname, commands); 78 return (ERR_USAGE); 79 } 80 81 for (p = &commands[0]; p->name != NULL; p++) { 82 if (0 == strcmp(p->name, argv[0])) { 83 fptr = p->func; 84 break; 85 } 86 } 87 if (fptr == NULL) { 88 print_usage(progname, commands); 89 return (ERR_USAGE); 90 } 91 92 if (tpm_preamble(&hContext, &hTPM)) 93 return (ERR_FAIL); 94 ret = fptr(hContext, hTPM, argc, argv); 95 (void) tpm_postamble(hContext); 96 97 return (ret); 98 } 99 100 101 /* 102 * Utility functions 103 */ 104 105 void 106 print_bytes(BYTE *bytes, size_t len, int formatted) 107 { 108 int i; 109 for (i = 0; i < len; i++) { 110 (void) printf("%02X ", bytes[i]); 111 if (formatted && i % 16 == 7) 112 (void) printf(" "); 113 if (formatted && i % 16 == 15) 114 (void) printf("\n"); 115 } 116 (void) printf("\n"); 117 } 118 119 120 /* 121 * TSS convenience functions 122 */ 123 124 void 125 print_error(TSS_RESULT ret, char *msg) 126 { 127 char *err_string; 128 129 /* Print the standard error string and error code. */ 130 err_string = Trspi_Error_String(ret); 131 (void) fprintf(stderr, "%s: %s (0x%0x)\n", msg, err_string, ret); 132 133 /* For a few special cases, add a more verbose error message. */ 134 switch (ret) { 135 case TPM_E_DEACTIVATED: 136 case TPM_E_DISABLED: 137 (void) fprintf(stderr, 138 gettext("Enable the TPM and restart Solaris.\n")); 139 break; 140 case TSP_ERROR(TSS_E_COMM_FAILURE): 141 (void) fprintf(stderr, 142 gettext("Make sure the tcsd service " 143 "(svc:/application/security/tcsd) is running.\n")); 144 break; 145 } 146 } 147 148 int 149 get_tpm_capability(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM, UINT32 cap, 150 UINT32 subcap, void *buf, size_t bufsize) 151 { 152 TSS_RESULT ret; 153 UINT32 datalen; 154 BYTE *data; 155 156 ret = Tspi_TPM_GetCapability(hTPM, cap, sizeof (subcap), 157 (BYTE *)&subcap, &datalen, &data); 158 if (ret) { 159 print_error(ret, gettext("Get TPM capability")); 160 return (ERR_FAIL); 161 } 162 163 if (datalen > bufsize) { 164 (void) fprintf(stderr, 165 gettext("Capability 0x%x returned %u bytes " 166 "(expected %u)\n"), cap, datalen, bufsize); 167 return (ERR_FAIL); 168 } 169 bcopy(data, buf, datalen); 170 171 ret = Tspi_Context_FreeMemory(hContext, data); 172 if (ret) { 173 print_error(ret, gettext("Free capability buffer")); 174 return (ERR_FAIL); 175 } 176 177 return (0); 178 } 179 180 int 181 set_policy_options(TSS_HPOLICY hPolicy, TSS_FLAG mode, char *prompt, 182 UINT32 secret_len, BYTE *secret) 183 { 184 TSS_RESULT ret; 185 BYTE *unicode_prompt; 186 UINT32 len; 187 188 ret = Tspi_Policy_SetSecret(hPolicy, mode, secret_len, secret); 189 if (ret) { 190 print_error(ret, gettext("Set policy secret")); 191 return (ERR_FAIL); 192 } 193 if (prompt != NULL) { 194 unicode_prompt = Trspi_Native_To_UNICODE((BYTE *)prompt, &len); 195 ret = Tspi_SetAttribData(hPolicy, 196 TSS_TSPATTRIB_POLICY_POPUPSTRING, 197 NULL, len, unicode_prompt); 198 if (ret) { 199 print_error(ret, gettext("Set policy prompt")); 200 return (ERR_FAIL); 201 } 202 } 203 204 return (0); 205 } 206 207 int 208 set_object_policy(TSS_HOBJECT handle, TSS_FLAG mode, char *prompt, 209 UINT32 secret_len, BYTE *secret) 210 { 211 TSS_HPOLICY hPolicy; 212 TSS_RESULT ret; 213 214 ret = Tspi_GetPolicyObject(handle, TSS_POLICY_USAGE, &hPolicy); 215 if (ret) { 216 print_error(ret, gettext("Get object policy")); 217 return (ERR_FAIL); 218 } 219 220 return (set_policy_options(hPolicy, mode, prompt, secret_len, secret)); 221 } 222 223 int 224 tpm_preamble(TSS_HCONTEXT *hContext, TSS_HOBJECT *hTPM) 225 { 226 TSS_RESULT ret; 227 228 ret = Tspi_Context_Create(hContext); 229 if (ret) { 230 print_error(ret, gettext("Create context")); 231 return (ERR_FAIL); 232 } 233 234 ret = Tspi_Context_Connect(*hContext, NULL); 235 if (ret) { 236 print_error(ret, gettext("Connect context")); 237 (void) Tspi_Context_Close(*hContext); 238 return (ERR_FAIL); 239 } 240 241 ret = Tspi_Context_GetTpmObject(*hContext, hTPM); 242 if (ret) { 243 print_error(ret, gettext("Get TPM object")); 244 (void) Tspi_Context_Close(*hContext); 245 return (ERR_FAIL); 246 } 247 return (0); 248 } 249 250 int 251 tpm_postamble(TSS_HCONTEXT hContext) 252 { 253 TSS_RESULT ret; 254 255 ret = Tspi_Context_Close(hContext); 256 if (ret) { 257 print_error(ret, gettext("Close context")); 258 return (ERR_FAIL); 259 } 260 return (0); 261 } 262