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."));
88 oldcred
.cred
= (char *)old_pin
;
89 oldcred
.credlen
= old_pinlen
;
91 kmf_set_attr_at_index(setpinattrs
, numattrs
, KMF_CREDENTIAL_ATTR
,
92 &oldcred
, sizeof (oldcred
));
95 newpincred
.cred
= (char *)new_pin
;
96 newpincred
.credlen
= new_pinlen
;
97 kmf_set_attr_at_index(setpinattrs
, numattrs
, KMF_NEWPIN_ATTR
,
98 &newpincred
, sizeof (newpincred
));
101 rv
= kmf_set_token_pin(handle
, numattrs
, setpinattrs
);
110 setpin_pkcs11(KMF_HANDLE_T handle
, char *token_spec
, boolean_t souser
)
114 CK_UTF8CHAR_PTR old_pin
= NULL
, new_pin
= NULL
;
115 CK_ULONG old_pinlen
= 0, new_pinlen
= 0;
117 char *token_name
= NULL
;
118 CK_TOKEN_INFO token_info
;
119 KMF_CREDENTIAL newpincred
= { NULL
, 0 };
120 KMF_CREDENTIAL oldcred
= { NULL
, 0 };
121 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_PK11TOKEN
;
122 KMF_ATTRIBUTE attrlist
[6];
123 CK_USER_TYPE user
= CKU_USER
;
126 /* If nothing is specified, default is to use softtoken. */
127 if (token_spec
== NULL
) {
128 token_spec
= SOFT_TOKEN_LABEL
":" SOFT_MANUFACTURER_ID
;
129 token_name
= SOFT_TOKEN_LABEL
;
132 rv
= kmf_pk11_token_lookup(NULL
, token_spec
, &slot_id
);
134 /* find the pin state for the selected token */
135 if (C_GetTokenInfo(slot_id
, &token_info
) != CKR_OK
)
136 return (PK_ERR_PK11
);
138 pin_state
= token_info
.flags
& CKF_USER_PIN_TO_BE_CHANGED
;
139 if (token_name
== NULL
)
140 token_name
= (char *)token_info
.label
;
144 * If the token is the softtoken, check if the token flags show the
145 * PIN has not been set yet. If not then set the old PIN to the
146 * default "changeme". Otherwise, let user type in the correct old
147 * PIN to unlock token.
149 if (pin_state
== CKF_USER_PIN_TO_BE_CHANGED
&&
150 strcmp(token_name
, SOFT_TOKEN_LABEL
) == 0) {
151 if ((old_pin
= (CK_UTF8CHAR_PTR
) strdup(SOFT_DEFAULT_PIN
)) ==
153 cryptoerror(LOG_STDERR
, "%s.", strerror(errno
));
155 return (PK_ERR_PK11
);
157 old_pinlen
= strlen(SOFT_DEFAULT_PIN
);
159 if ((rv
= get_pin(gettext("Enter token passphrase:"), NULL
,
160 &old_pin
, &old_pinlen
)) != CKR_OK
) {
161 cryptoerror(LOG_STDERR
,
162 gettext("Unable to get token passphrase (%s)."),
163 pkcs11_strerror(rv
));
165 return (PK_ERR_PK11
);
169 /* Get the user's new PIN. */
170 if ((rv
= get_pin(gettext("Create new passphrase:"), gettext(
171 "Re-enter new passphrase:"), &new_pin
, &new_pinlen
)) != CKR_OK
) {
172 if (rv
== CKR_PIN_INCORRECT
)
173 cryptoerror(LOG_STDERR
, gettext(
174 "Passphrases do not match."));
176 cryptoerror(LOG_STDERR
, gettext(
177 "Unable to get and confirm new passphrase (%s)."),
178 pkcs11_strerror(rv
));
181 return (PK_ERR_PK11
);
184 kmf_set_attr_at_index(attrlist
, numattr
, KMF_KEYSTORE_TYPE_ATTR
,
185 &kstype
, sizeof (kstype
));
187 if (token_name
!= NULL
) {
188 kmf_set_attr_at_index(attrlist
, numattr
, KMF_TOKEN_LABEL_ATTR
,
189 token_name
, strlen(token_name
));
192 oldcred
.cred
= (char *)old_pin
;
193 oldcred
.credlen
= old_pinlen
;
194 kmf_set_attr_at_index(attrlist
, numattr
, KMF_CREDENTIAL_ATTR
,
195 &oldcred
, sizeof (oldcred
));
198 kmf_set_attr_at_index(attrlist
, numattr
, KMF_SLOT_ID_ATTR
,
199 &slot_id
, sizeof (slot_id
));
202 newpincred
.cred
= (char *)new_pin
;
203 newpincred
.credlen
= new_pinlen
;
204 kmf_set_attr_at_index(attrlist
, numattr
, KMF_NEWPIN_ATTR
,
205 &newpincred
, sizeof (newpincred
));
210 kmf_set_attr_at_index(attrlist
, numattr
,
211 KMF_PK11_USER_TYPE_ATTR
,
212 &user
, sizeof (user
));
216 rv
= kmf_set_token_pin(handle
, numattr
, attrlist
);
228 * Changes the token's PIN.
231 pk_setpin(int argc
, char *argv
[])
236 extern int optind_av
;
237 extern char *optarg_av
;
238 char *token_spec
= NULL
;
243 KMF_KEYSTORE_TYPE kstype
= KMF_KEYSTORE_PK11TOKEN
;
244 boolean_t souser
= 0;
246 /* Parse command line options. Do NOT i18n/l10n. */
247 while ((opt
= getopt_av(argc
, argv
,
248 "T:(token)k:(keystore)d:(dir)"
249 "p:(prefix)u:(usertype)")) != EOF
) {
252 kstype
= KS2Int(optarg_av
);
254 return (PK_ERR_USAGE
);
256 case 'T': /* token specifier */
258 return (PK_ERR_USAGE
);
259 token_spec
= optarg_av
;
263 return (PK_ERR_USAGE
);
268 return (PK_ERR_USAGE
);
275 return (PK_ERR_USAGE
);
280 /* No additional args allowed. */
284 return (PK_ERR_USAGE
);
286 /* Done parsing command line options. */
287 if (kstype
== KMF_KEYSTORE_PK11TOKEN
&& EMPTYSTRING(token_spec
)) {
288 token_spec
= PK_DEFAULT_PK11TOKEN
;
289 } else if (kstype
== KMF_KEYSTORE_NSS
&& EMPTYSTRING(token_spec
)) {
290 token_spec
= DEFAULT_NSS_TOKEN
;
293 if ((rv
= kmf_initialize(&handle
, NULL
, NULL
)) != KMF_OK
)
297 if (strcmp(utype
, "so") == 0)
299 else if (strcmp(utype
, "user") == 0)
301 else /* Wrong option string */
302 return (PK_ERR_USAGE
);
306 case KMF_KEYSTORE_PK11TOKEN
:
307 rv
= setpin_pkcs11(handle
, token_spec
, souser
);
309 case KMF_KEYSTORE_NSS
:
310 rv
= setpin_nss(handle
, token_spec
, dir
, prefix
);
313 cryptoerror(LOG_STDERR
,
314 gettext("incorrect keystore."));
315 return (PK_ERR_USAGE
);
318 (void) kmf_finalize(handle
);
320 if (rv
== KMF_ERR_AUTH_FAILED
) {
321 cryptoerror(LOG_STDERR
,
322 gettext("Incorrect passphrase."));
323 return (PK_ERR_SYSTEM
);
324 } else if (rv
!= CKR_OK
) {
325 cryptoerror(LOG_STDERR
,
326 gettext("Unable to change passphrase."));
327 return (PK_ERR_SYSTEM
);
329 (void) fprintf(stdout
, gettext("Passphrase changed.\n"));