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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
28 * This file implements the setpin operation for this tool.
29 * The basic flow of the process is to load the PKCS#11 module,
30 * finds the soft token, prompt the user for the old PIN (if
31 * any) and the new PIN, change the token's PIN, and clean up.
38 #include <cryptoutil.h>
39 #include <security/cryptoki.h>
43 setpin_nss(KMF_HANDLE_T handle
,
44 char *token_spec
, char *dir
, char *prefix
)
47 KMF_CREDENTIAL oldcred
= { NULL
, 0 };
48 KMF_CREDENTIAL newpincred
= { NULL
, 0 };
49 CK_UTF8CHAR_PTR old_pin
= NULL
, new_pin
= NULL
;
50 CK_ULONG old_pinlen
= 0, new_pinlen
= 0;
51 KMF_ATTRIBUTE setpinattrs
[6];
52 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_NSS
;
55 rv
= configure_nss(handle
, dir
, prefix
);
59 kmf_set_attr_at_index(setpinattrs
, numattrs
, KMF_KEYSTORE_TYPE_ATTR
,
60 &kstype
, sizeof (kstype
));
62 if (token_spec
!= NULL
) {
63 kmf_set_attr_at_index(setpinattrs
, numattrs
,
65 token_spec
, strlen(token_spec
));
69 if ((rv
= get_pin(gettext("Enter current token passphrase "
70 "(<CR> if not set):"), NULL
, &old_pin
, &old_pinlen
)) != CKR_OK
) {
71 cryptoerror(LOG_STDERR
,
72 gettext("Unable to get token passphrase."));
75 /* Get the user's new PIN. */
76 if ((rv
= get_pin(gettext("Create new passphrase:"), gettext(
77 "Re-enter new passphrase:"), &new_pin
, &new_pinlen
)) != CKR_OK
) {
78 if (rv
== CKR_PIN_INCORRECT
)
79 cryptoerror(LOG_STDERR
, gettext(
80 "Passphrases do not match."));
82 cryptoerror(LOG_STDERR
, gettext(
83 "Unable to get and confirm new passphrase."));
89 oldcred
.cred
= (char *)old_pin
;
90 oldcred
.credlen
= old_pinlen
;
92 kmf_set_attr_at_index(setpinattrs
, numattrs
, KMF_CREDENTIAL_ATTR
,
93 &oldcred
, sizeof (oldcred
));
96 newpincred
.cred
= (char *)new_pin
;
97 newpincred
.credlen
= new_pinlen
;
98 kmf_set_attr_at_index(setpinattrs
, numattrs
, KMF_NEWPIN_ATTR
,
99 &newpincred
, sizeof (newpincred
));
102 rv
= kmf_set_token_pin(handle
, numattrs
, setpinattrs
);
113 setpin_pkcs11(KMF_HANDLE_T handle
, char *token_spec
, boolean_t souser
)
117 CK_UTF8CHAR_PTR old_pin
= NULL
, new_pin
= NULL
;
118 CK_ULONG old_pinlen
= 0, new_pinlen
= 0;
120 char *token_name
= NULL
;
121 CK_TOKEN_INFO token_info
;
122 KMF_CREDENTIAL newpincred
= { NULL
, 0 };
123 KMF_CREDENTIAL oldcred
= { NULL
, 0 };
124 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_PK11TOKEN
;
125 KMF_ATTRIBUTE attrlist
[6];
126 CK_USER_TYPE user
= CKU_USER
;
129 /* If nothing is specified, default is to use softtoken. */
130 if (token_spec
== NULL
) {
131 token_spec
= SOFT_TOKEN_LABEL
":" SOFT_MANUFACTURER_ID
;
132 token_name
= SOFT_TOKEN_LABEL
;
135 rv
= kmf_pk11_token_lookup(NULL
, token_spec
, &slot_id
);
137 /* find the pin state for the selected token */
138 if (C_GetTokenInfo(slot_id
, &token_info
) != CKR_OK
)
139 return (PK_ERR_PK11
);
141 pin_state
= token_info
.flags
& CKF_USER_PIN_TO_BE_CHANGED
;
142 if (token_name
== NULL
)
143 token_name
= (char *)token_info
.label
;
147 * If the token is the softtoken, check if the token flags show the
148 * PIN has not been set yet. If not then set the old PIN to the
149 * default "changeme". Otherwise, let user type in the correct old
150 * PIN to unlock token.
152 if (pin_state
== CKF_USER_PIN_TO_BE_CHANGED
&&
153 strcmp(token_name
, SOFT_TOKEN_LABEL
) == 0) {
154 if ((old_pin
= (CK_UTF8CHAR_PTR
) strdup(SOFT_DEFAULT_PIN
)) ==
156 cryptoerror(LOG_STDERR
, "%s.", strerror(errno
));
158 return (PK_ERR_PK11
);
160 old_pinlen
= strlen(SOFT_DEFAULT_PIN
);
162 if ((rv
= get_pin(gettext("Enter token passphrase:"), NULL
,
163 &old_pin
, &old_pinlen
)) != CKR_OK
) {
164 cryptoerror(LOG_STDERR
,
165 gettext("Unable to get token passphrase (%s)."),
166 pkcs11_strerror(rv
));
168 return (PK_ERR_PK11
);
172 /* Get the user's new PIN. */
173 if ((rv
= get_pin(gettext("Create new passphrase:"), gettext(
174 "Re-enter new passphrase:"), &new_pin
, &new_pinlen
)) != CKR_OK
) {
175 if (rv
== CKR_PIN_INCORRECT
)
176 cryptoerror(LOG_STDERR
, gettext(
177 "Passphrases do not match."));
179 cryptoerror(LOG_STDERR
, gettext(
180 "Unable to get and confirm new passphrase (%s)."),
181 pkcs11_strerror(rv
));
184 return (PK_ERR_PK11
);
187 kmf_set_attr_at_index(attrlist
, numattr
, KMF_KEYSTORE_TYPE_ATTR
,
188 &kstype
, sizeof (kstype
));
190 if (token_name
!= NULL
) {
191 kmf_set_attr_at_index(attrlist
, numattr
, KMF_TOKEN_LABEL_ATTR
,
192 token_name
, strlen(token_name
));
195 oldcred
.cred
= (char *)old_pin
;
196 oldcred
.credlen
= old_pinlen
;
197 kmf_set_attr_at_index(attrlist
, numattr
, KMF_CREDENTIAL_ATTR
,
198 &oldcred
, sizeof (oldcred
));
201 kmf_set_attr_at_index(attrlist
, numattr
, KMF_SLOT_ID_ATTR
,
202 &slot_id
, sizeof (slot_id
));
205 newpincred
.cred
= (char *)new_pin
;
206 newpincred
.credlen
= new_pinlen
;
207 kmf_set_attr_at_index(attrlist
, numattr
, KMF_NEWPIN_ATTR
,
208 &newpincred
, sizeof (newpincred
));
213 kmf_set_attr_at_index(attrlist
, numattr
,
214 KMF_PK11_USER_TYPE_ATTR
,
215 &user
, sizeof (user
));
219 rv
= kmf_set_token_pin(handle
, numattr
, attrlist
);
231 * Changes the token's PIN.
234 pk_setpin(int argc
, char *argv
[])
239 extern int optind_av
;
240 extern char *optarg_av
;
241 char *token_spec
= NULL
;
246 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_PK11TOKEN
;
247 boolean_t souser
= 0;
249 /* Parse command line options. Do NOT i18n/l10n. */
250 while ((opt
= getopt_av(argc
, argv
,
251 "T:(token)k:(keystore)d:(dir)"
252 "p:(prefix)u:(usertype)")) != EOF
) {
255 kstype
= KS2Int(optarg_av
);
257 return (PK_ERR_USAGE
);
259 case 'T': /* token specifier */
261 return (PK_ERR_USAGE
);
262 token_spec
= optarg_av
;
266 return (PK_ERR_USAGE
);
271 return (PK_ERR_USAGE
);
278 return (PK_ERR_USAGE
);
283 /* No additional args allowed. */
287 return (PK_ERR_USAGE
);
289 /* Done parsing command line options. */
290 if (kstype
== KMF_KEYSTORE_PK11TOKEN
&& EMPTYSTRING(token_spec
)) {
291 token_spec
= PK_DEFAULT_PK11TOKEN
;
292 } else if (kstype
== KMF_KEYSTORE_NSS
&& EMPTYSTRING(token_spec
)) {
293 token_spec
= DEFAULT_NSS_TOKEN
;
296 if ((rv
= kmf_initialize(&handle
, NULL
, NULL
)) != KMF_OK
)
300 if (strcmp(utype
, "so") == 0)
302 else if (strcmp(utype
, "user") == 0)
304 else /* Wrong option string */
305 return (PK_ERR_USAGE
);
309 case KMF_KEYSTORE_PK11TOKEN
:
310 rv
= setpin_pkcs11(handle
, token_spec
, souser
);
312 case KMF_KEYSTORE_NSS
:
313 rv
= setpin_nss(handle
, token_spec
, dir
, prefix
);
316 cryptoerror(LOG_STDERR
,
317 gettext("incorrect keystore."));
318 return (PK_ERR_USAGE
);
321 (void) kmf_finalize(handle
);
323 if (rv
== KMF_ERR_AUTH_FAILED
) {
324 cryptoerror(LOG_STDERR
,
325 gettext("Incorrect passphrase."));
326 return (PK_ERR_SYSTEM
);
327 } else if (rv
!= CKR_OK
) {
328 cryptoerror(LOG_STDERR
,
329 gettext("Unable to change passphrase."));
330 return (PK_ERR_SYSTEM
);
332 (void) fprintf(stdout
, gettext("Passphrase changed.\n"));