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
help(const char * aCmd)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
parse(const int aOpt,const char * aArg)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
tpmChangeAuth(TSS_HCONTEXT aObjToChange,TSS_HOBJECT aParent,TSS_HPOLICY aNewPolicy)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 */
main(int argc,char ** argv)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