1 /* 2 * The Initial Developer of the Original Code is International 3 * Business Machines Corporation. Portions created by IBM 4 * Corporation are Copyright (C) 2005 International Business 5 * Machines Corporation. All Rights Reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the Common Public License as published by 9 * IBM Corporation; either version 1 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * Common Public License for more details. 16 * 17 * You should have received a copy of the Common Public License 18 * along with this program; if not, a copy can be viewed at 19 * http://www.opensource.org/licenses/cpl1.0.php. 20 */ 21 22 #include <stdio.h> 23 #include "tpm_utils.h" 24 #include "tpm_tspi.h" 25 26 struct changeAuth { 27 char *name; 28 char *prompt; 29 BOOL change; 30 }; 31 32 static BOOL changeRequested = FALSE; 33 static BOOL origUnicode = FALSE; 34 static BOOL newUnicode = FALSE; 35 static BOOL wellKnown = FALSE; 36 static BOOL setWellKnown = FALSE; 37 TSS_HCONTEXT hContext = 0; 38 39 //Order important so you authenticate once even if both changed with one command 40 enum { 41 srk = 0, 42 owner 43 }; 44 45 static struct changeAuth auths[] = { 46 {N_("SRK"), N_("Enter new SRK password: "), FALSE}, 47 {N_("owner"), N_("Enter new owner password: "), FALSE}, 48 {NULL, NULL, FALSE }, 49 }; 50 51 static void help(const char *aCmd) 52 { 53 logCmdHelp(aCmd); 54 logUnicodeCmdOption(); 55 logCmdOption("-o, --owner", _("Change the owner password.")); 56 logCmdOption("-s, --srk", _("Change the SRK password.")); 57 logCmdOption("-g, --original_password_unicode", _("Use TSS UNICODE encoding for original password to comply with applications using TSS popup boxes")); 58 logCmdOption("-n, --new_password_unicode", _("Use TSS UNICODE encoding for new password to comply with applications using TSS popup boxes")); 59 logCmdOption("-z, --well-known", _("Change password to a new one when current owner password is a secret of all zeros (20 bytes of zeros). It must be specified which password (owner, SRK or both) to change")); 60 logCmdOption("-r, --set-well-known", _("Change password to a secret of all zeros (20 bytes of zeros). It must be specified which password (owner, SRK or both) to change")); 61 } 62 63 static int parse(const int aOpt, const char *aArg) 64 { 65 66 switch (aOpt) { 67 68 case 'o': 69 auths[owner].change = TRUE; 70 changeRequested = TRUE; 71 break; 72 case 's': 73 auths[srk].change = TRUE; 74 changeRequested = TRUE; 75 break; 76 case 'g': 77 origUnicode = TRUE; 78 break; 79 case 'n': 80 newUnicode = TRUE; 81 break; 82 case 'z': 83 wellKnown = TRUE; 84 break; 85 case 'r': 86 setWellKnown = TRUE; 87 break; 88 default: 89 return -1; 90 } 91 return 0; 92 } 93 94 static TSS_RESULT 95 tpmChangeAuth(TSS_HCONTEXT aObjToChange, 96 TSS_HOBJECT aParent, TSS_HPOLICY aNewPolicy) 97 { 98 TSS_RESULT result = 99 Tspi_ChangeAuth(aObjToChange, aParent, aNewPolicy); 100 tspiResult("Tspi_ChangeAuth", result); 101 102 return result; 103 } 104 105 /* 106 * Affect: Change owner or srk password 107 * Default: No action 108 * Required: Owner authentication 109 */ 110 int main(int argc, char **argv) 111 { 112 113 int i = 0, iRc = -1; 114 char *passwd = NULL; 115 int pswd_len; 116 TSS_HPOLICY hTpmPolicy, hNewPolicy; 117 TSS_HTPM hTpm; 118 TSS_HTPM hSrk; 119 BYTE well_known_secret[] = TSS_WELL_KNOWN_SECRET; 120 struct option opts[] = { {"owner", no_argument, NULL, 'o'}, 121 {"srk", no_argument, NULL, 's'}, 122 {"original_password_unicode", no_argument, NULL, 'g'}, 123 {"new_password_unicode", no_argument, NULL, 'n'}, 124 {"well-known", no_argument, NULL, 'z'}, 125 {"set-well-known", no_argument, NULL, 'r'}, 126 }; 127 128 initIntlSys(); 129 130 if (genericOptHandler 131 (argc, argv, "zrsogn", opts, sizeof(opts) / sizeof(struct option), 132 parse, help) != 0) 133 goto out; 134 135 //nothing selected 136 if ((!changeRequested && wellKnown) || (!changeRequested)) { 137 help(argv[0]); 138 goto out; 139 } 140 141 //Connect to TSS and TPM 142 if (contextCreate(&hContext) != TSS_SUCCESS) 143 goto out; 144 145 if (contextConnect(hContext) != TSS_SUCCESS) 146 goto out_close; 147 148 if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) 149 goto out_close; 150 151 if (wellKnown) { 152 passwd = (char *)well_known_secret; 153 pswd_len = TCPA_SHA1_160_HASH_LEN; 154 } else { 155 passwd = _GETPASSWD(_("Enter owner password: "), &pswd_len, 156 FALSE, origUnicode || useUnicode ); 157 if (!passwd) { 158 logError(_("Failed to get owner password\n")); 159 goto out_close; 160 } 161 } 162 163 if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) 164 goto out_close; 165 166 if (policySetSecret(hTpmPolicy, pswd_len, (BYTE *)passwd) != TSS_SUCCESS) 167 goto out_close; 168 169 if (!wellKnown && !setWellKnown) { 170 shredPasswd(passwd); 171 passwd = NULL; 172 } 173 174 do { 175 if (auths[i].change) { 176 logInfo(_("Changing password for: %s.\n"), _(auths[i].name)); 177 if (setWellKnown) { 178 passwd = (char *)well_known_secret; 179 pswd_len = TCPA_SHA1_160_HASH_LEN; 180 } else { 181 passwd = _GETPASSWD(_(auths[i].prompt), &pswd_len, 182 TRUE, newUnicode || useUnicode ); 183 if (!passwd) { 184 logError(_("Failed to get new password.\n")); 185 goto out_close; 186 } 187 } 188 189 if (contextCreateObject 190 (hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, 191 &hNewPolicy) != TSS_SUCCESS) 192 goto out_close; 193 194 if (policySetSecret 195 (hNewPolicy, pswd_len, 196 (BYTE *)passwd) != TSS_SUCCESS) 197 goto out_close; 198 199 if (i == owner) { 200 if (tpmChangeAuth(hTpm, NULL_HOBJECT, hNewPolicy) != TSS_SUCCESS) 201 goto out_close; 202 } else if (i == srk) { 203 if (keyLoadKeyByUUID 204 (hContext, TSS_PS_TYPE_SYSTEM, 205 SRK_UUID, &hSrk) != TSS_SUCCESS) 206 goto out_close; 207 if (tpmChangeAuth(hSrk, hTpm, hNewPolicy) != TSS_SUCCESS) 208 goto out_close; 209 } 210 logInfo(_("Change of %s password successful.\n"), _(auths[i].name)); 211 if (!wellKnown && !setWellKnown) { 212 shredPasswd(passwd); 213 passwd = NULL; 214 } 215 } 216 } while (auths[++i].name); 217 218 iRc = 0; 219 220 out_close: 221 contextClose(hContext); 222 223 out: 224 if (passwd && !wellKnown && !setWellKnown) 225 shredPasswd(passwd); 226 227 return iRc; 228 } 229