xref: /onnv-gate/usr/src/lib/pkcs11/pkcs11_kms/common/kmsSlotToken.c (revision 12720:3db6e0082404)
1*12720SWyllys.Ingersoll@Sun.COM /*
2*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER START
3*12720SWyllys.Ingersoll@Sun.COM  *
4*12720SWyllys.Ingersoll@Sun.COM  * The contents of this file are subject to the terms of the
5*12720SWyllys.Ingersoll@Sun.COM  * Common Development and Distribution License (the "License").
6*12720SWyllys.Ingersoll@Sun.COM  * You may not use this file except in compliance with the License.
7*12720SWyllys.Ingersoll@Sun.COM  *
8*12720SWyllys.Ingersoll@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12720SWyllys.Ingersoll@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*12720SWyllys.Ingersoll@Sun.COM  * See the License for the specific language governing permissions
11*12720SWyllys.Ingersoll@Sun.COM  * and limitations under the License.
12*12720SWyllys.Ingersoll@Sun.COM  *
13*12720SWyllys.Ingersoll@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*12720SWyllys.Ingersoll@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12720SWyllys.Ingersoll@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*12720SWyllys.Ingersoll@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*12720SWyllys.Ingersoll@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12720SWyllys.Ingersoll@Sun.COM  *
19*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER END
20*12720SWyllys.Ingersoll@Sun.COM  */
21*12720SWyllys.Ingersoll@Sun.COM 
22*12720SWyllys.Ingersoll@Sun.COM /*
23*12720SWyllys.Ingersoll@Sun.COM  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24*12720SWyllys.Ingersoll@Sun.COM  */
25*12720SWyllys.Ingersoll@Sun.COM 
26*12720SWyllys.Ingersoll@Sun.COM 
27*12720SWyllys.Ingersoll@Sun.COM #include <stdlib.h>
28*12720SWyllys.Ingersoll@Sun.COM #include <strings.h>
29*12720SWyllys.Ingersoll@Sun.COM #include <security/cryptoki.h>
30*12720SWyllys.Ingersoll@Sun.COM #include <cryptoutil.h>
31*12720SWyllys.Ingersoll@Sun.COM #include <errno.h>
32*12720SWyllys.Ingersoll@Sun.COM #include <aes_impl.h>
33*12720SWyllys.Ingersoll@Sun.COM 
34*12720SWyllys.Ingersoll@Sun.COM #include "kmsGlobal.h"
35*12720SWyllys.Ingersoll@Sun.COM #include "kmsSlot.h"
36*12720SWyllys.Ingersoll@Sun.COM #include "kmsKeystoreUtil.h"
37*12720SWyllys.Ingersoll@Sun.COM 
38*12720SWyllys.Ingersoll@Sun.COM /*
39*12720SWyllys.Ingersoll@Sun.COM  * Just basic AES mechanisms (for now...)
40*12720SWyllys.Ingersoll@Sun.COM  */
41*12720SWyllys.Ingersoll@Sun.COM static CK_MECHANISM_TYPE kms_mechanisms[] = {
42*12720SWyllys.Ingersoll@Sun.COM 	CKM_AES_KEY_GEN,
43*12720SWyllys.Ingersoll@Sun.COM 	CKM_AES_CBC,
44*12720SWyllys.Ingersoll@Sun.COM 	CKM_AES_CBC_PAD
45*12720SWyllys.Ingersoll@Sun.COM };
46*12720SWyllys.Ingersoll@Sun.COM 
47*12720SWyllys.Ingersoll@Sun.COM /*
48*12720SWyllys.Ingersoll@Sun.COM  * KMS only supports 256 bit keys, so the range below is MAX-MAX
49*12720SWyllys.Ingersoll@Sun.COM  * instead of MIN-MAX.
50*12720SWyllys.Ingersoll@Sun.COM  */
51*12720SWyllys.Ingersoll@Sun.COM static CK_MECHANISM_INFO kms_mechanism_info[] = {
52*12720SWyllys.Ingersoll@Sun.COM 	{AES_MAX_KEY_BYTES, AES_MAX_KEY_BYTES, CKF_GENERATE},
53*12720SWyllys.Ingersoll@Sun.COM 	{AES_MAX_KEY_BYTES, AES_MAX_KEY_BYTES, CKF_ENCRYPT|CKF_DECRYPT|
54*12720SWyllys.Ingersoll@Sun.COM 		CKF_WRAP|CKF_UNWRAP},		/* CKM_AES_CBC */
55*12720SWyllys.Ingersoll@Sun.COM 	{AES_MAX_KEY_BYTES, AES_MAX_KEY_BYTES, CKF_ENCRYPT|CKF_DECRYPT|
56*12720SWyllys.Ingersoll@Sun.COM 		CKF_WRAP|CKF_UNWRAP}		/* CKM_AES_CBC_PAD */
57*12720SWyllys.Ingersoll@Sun.COM };
58*12720SWyllys.Ingersoll@Sun.COM 
59*12720SWyllys.Ingersoll@Sun.COM /* ARGSUSED */
60*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_GetSlotList(CK_BBOOL tokenPresent,CK_SLOT_ID_PTR pSlotList,CK_ULONG_PTR pulCount)61*12720SWyllys.Ingersoll@Sun.COM C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
62*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG_PTR pulCount)
63*12720SWyllys.Ingersoll@Sun.COM {
64*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
65*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
66*12720SWyllys.Ingersoll@Sun.COM 
67*12720SWyllys.Ingersoll@Sun.COM 	if (pulCount == NULL) {
68*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
69*12720SWyllys.Ingersoll@Sun.COM 	}
70*12720SWyllys.Ingersoll@Sun.COM 
71*12720SWyllys.Ingersoll@Sun.COM 	/*
72*12720SWyllys.Ingersoll@Sun.COM 	 * If KMS is not available or initialized, return 0 slots
73*12720SWyllys.Ingersoll@Sun.COM 	 * but CKR_OK status.
74*12720SWyllys.Ingersoll@Sun.COM 	 */
75*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_is_initialized()) {
76*12720SWyllys.Ingersoll@Sun.COM 		*pulCount = 0;
77*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
78*12720SWyllys.Ingersoll@Sun.COM 	}
79*12720SWyllys.Ingersoll@Sun.COM 
80*12720SWyllys.Ingersoll@Sun.COM 	if (pSlotList == NULL) {
81*12720SWyllys.Ingersoll@Sun.COM 		*pulCount = KMS_SLOTS;
82*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
83*12720SWyllys.Ingersoll@Sun.COM 	}
84*12720SWyllys.Ingersoll@Sun.COM 
85*12720SWyllys.Ingersoll@Sun.COM 	if (*pulCount < KMS_SLOTS) {
86*12720SWyllys.Ingersoll@Sun.COM 		*pulCount = KMS_SLOTS;
87*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_BUFFER_TOO_SMALL);
88*12720SWyllys.Ingersoll@Sun.COM 	}
89*12720SWyllys.Ingersoll@Sun.COM 
90*12720SWyllys.Ingersoll@Sun.COM 	*pulCount = 1;
91*12720SWyllys.Ingersoll@Sun.COM 	pSlotList[0] = KMS_TOKEN_SLOTID;
92*12720SWyllys.Ingersoll@Sun.COM 
93*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
94*12720SWyllys.Ingersoll@Sun.COM }
95*12720SWyllys.Ingersoll@Sun.COM 
96*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_GetSlotInfo(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR pInfo)97*12720SWyllys.Ingersoll@Sun.COM C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
98*12720SWyllys.Ingersoll@Sun.COM {
99*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
100*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
101*12720SWyllys.Ingersoll@Sun.COM 
102*12720SWyllys.Ingersoll@Sun.COM 	if (slotID != KMS_TOKEN_SLOTID ||
103*12720SWyllys.Ingersoll@Sun.COM 	    !kms_is_initialized()) {
104*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_SLOT_ID_INVALID);
105*12720SWyllys.Ingersoll@Sun.COM 	}
106*12720SWyllys.Ingersoll@Sun.COM 
107*12720SWyllys.Ingersoll@Sun.COM 	if (pInfo == NULL)
108*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
109*12720SWyllys.Ingersoll@Sun.COM 
110*12720SWyllys.Ingersoll@Sun.COM 	/* Provide information about the slot in the provided buffer */
111*12720SWyllys.Ingersoll@Sun.COM 	(void) strncpy((char *)pInfo->slotDescription, SLOT_DESCRIPTION,
112*12720SWyllys.Ingersoll@Sun.COM 	    64);
113*12720SWyllys.Ingersoll@Sun.COM 	(void) strncpy((char *)pInfo->manufacturerID, MANUFACTURER_ID, 32);
114*12720SWyllys.Ingersoll@Sun.COM 	pInfo->flags = CKF_TOKEN_PRESENT;
115*12720SWyllys.Ingersoll@Sun.COM 	pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
116*12720SWyllys.Ingersoll@Sun.COM 	pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
117*12720SWyllys.Ingersoll@Sun.COM 	pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
118*12720SWyllys.Ingersoll@Sun.COM 	pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
119*12720SWyllys.Ingersoll@Sun.COM 
120*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
121*12720SWyllys.Ingersoll@Sun.COM }
122*12720SWyllys.Ingersoll@Sun.COM 
123*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)124*12720SWyllys.Ingersoll@Sun.COM C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
125*12720SWyllys.Ingersoll@Sun.COM {
126*12720SWyllys.Ingersoll@Sun.COM 	kms_cfg_info_t kmscfg;
127*12720SWyllys.Ingersoll@Sun.COM 	KMSAGENT_PROFILE_FLAGS kmsflags = 0;
128*12720SWyllys.Ingersoll@Sun.COM 
129*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
130*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
131*12720SWyllys.Ingersoll@Sun.COM 
132*12720SWyllys.Ingersoll@Sun.COM 	if (slotID != KMS_TOKEN_SLOTID ||
133*12720SWyllys.Ingersoll@Sun.COM 	    !kms_is_initialized())
134*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_SLOT_ID_INVALID);
135*12720SWyllys.Ingersoll@Sun.COM 
136*12720SWyllys.Ingersoll@Sun.COM 	if (pInfo == NULL)
137*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
138*12720SWyllys.Ingersoll@Sun.COM 
139*12720SWyllys.Ingersoll@Sun.COM 	/* Provide information about a token in the provided buffer */
140*12720SWyllys.Ingersoll@Sun.COM 	(void) strncpy((char *)pInfo->label, KMS_TOKEN_LABEL, 32);
141*12720SWyllys.Ingersoll@Sun.COM 	(void) strncpy((char *)pInfo->manufacturerID, MANUFACTURER_ID, 32);
142*12720SWyllys.Ingersoll@Sun.COM 	(void) strncpy((char *)pInfo->model, KMS_TOKEN_MODEL, 16);
143*12720SWyllys.Ingersoll@Sun.COM 	(void) strncpy((char *)pInfo->serialNumber, KMS_TOKEN_SERIAL, 16);
144*12720SWyllys.Ingersoll@Sun.COM 
145*12720SWyllys.Ingersoll@Sun.COM 	pInfo->flags = KMS_TOKEN_FLAGS;
146*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
147*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulSessionCount = kms_session_cnt;
148*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
149*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulRwSessionCount = kms_session_rw_cnt;
150*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulMaxPinLen = MAX_PIN_LEN;
151*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulMinPinLen = MIN_PIN_LEN;
152*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
153*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
154*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
155*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
156*12720SWyllys.Ingersoll@Sun.COM 	pInfo->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
157*12720SWyllys.Ingersoll@Sun.COM 	pInfo->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
158*12720SWyllys.Ingersoll@Sun.COM 	pInfo->firmwareVersion.major = FIRMWARE_VERSION_MAJOR;
159*12720SWyllys.Ingersoll@Sun.COM 	pInfo->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
160*12720SWyllys.Ingersoll@Sun.COM 	(void) memset(pInfo->utcTime, ' ', 16);
161*12720SWyllys.Ingersoll@Sun.COM 
162*12720SWyllys.Ingersoll@Sun.COM 	if (KMS_GetConfigInfo(&kmscfg) == CKR_OK &&
163*12720SWyllys.Ingersoll@Sun.COM 	    KMSAgent_GetProfileStatus(kmscfg.name, &kmsflags) ==
164*12720SWyllys.Ingersoll@Sun.COM 	    KMS_AGENT_STATUS_OK) {
165*12720SWyllys.Ingersoll@Sun.COM 
166*12720SWyllys.Ingersoll@Sun.COM 		if ((kmsflags & KMSAGENT_PROFILE_EXISTS_FLAG) &&
167*12720SWyllys.Ingersoll@Sun.COM 		    (kmsflags & KMSAGENT_CLIENTKEY_EXISTS_FLAG))
168*12720SWyllys.Ingersoll@Sun.COM 			pInfo->flags |= CKF_TOKEN_INITIALIZED;
169*12720SWyllys.Ingersoll@Sun.COM 		else
170*12720SWyllys.Ingersoll@Sun.COM 			pInfo->flags &= ~CKF_TOKEN_INITIALIZED;
171*12720SWyllys.Ingersoll@Sun.COM 	}
172*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
173*12720SWyllys.Ingersoll@Sun.COM }
174*12720SWyllys.Ingersoll@Sun.COM 
175*12720SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/
176*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_WaitForSlotEvent(CK_FLAGS flags,CK_SLOT_ID_PTR pSlot,CK_VOID_PTR pReserved)177*12720SWyllys.Ingersoll@Sun.COM C_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
178*12720SWyllys.Ingersoll@Sun.COM {
179*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
180*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
181*12720SWyllys.Ingersoll@Sun.COM 
182*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_FUNCTION_NOT_SUPPORTED);
183*12720SWyllys.Ingersoll@Sun.COM }
184*12720SWyllys.Ingersoll@Sun.COM 
185*12720SWyllys.Ingersoll@Sun.COM 
186*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_GetMechanismList(CK_SLOT_ID slotID,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)187*12720SWyllys.Ingersoll@Sun.COM C_GetMechanismList(CK_SLOT_ID slotID,
188*12720SWyllys.Ingersoll@Sun.COM 	CK_MECHANISM_TYPE_PTR pMechanismList,
189*12720SWyllys.Ingersoll@Sun.COM 	CK_ULONG_PTR pulCount)
190*12720SWyllys.Ingersoll@Sun.COM {
191*12720SWyllys.Ingersoll@Sun.COM 	int i;
192*12720SWyllys.Ingersoll@Sun.COM 	ulong_t mechnum;
193*12720SWyllys.Ingersoll@Sun.COM 
194*12720SWyllys.Ingersoll@Sun.COM 	/*
195*12720SWyllys.Ingersoll@Sun.COM 	 * Just check to see if the library has been
196*12720SWyllys.Ingersoll@Sun.COM 	 * properly initialized.
197*12720SWyllys.Ingersoll@Sun.COM 	 */
198*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
199*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
200*12720SWyllys.Ingersoll@Sun.COM 
201*12720SWyllys.Ingersoll@Sun.COM 	/*
202*12720SWyllys.Ingersoll@Sun.COM 	 * This is different from above check, this verifies that
203*12720SWyllys.Ingersoll@Sun.COM 	 * the KMS token is actually configured.
204*12720SWyllys.Ingersoll@Sun.COM 	 */
205*12720SWyllys.Ingersoll@Sun.COM 	if (slotID != KMS_TOKEN_SLOTID ||
206*12720SWyllys.Ingersoll@Sun.COM 	    !kms_is_initialized())
207*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_SLOT_ID_INVALID);
208*12720SWyllys.Ingersoll@Sun.COM 
209*12720SWyllys.Ingersoll@Sun.COM 	mechnum = sizeof (kms_mechanisms) / sizeof (CK_MECHANISM_TYPE);
210*12720SWyllys.Ingersoll@Sun.COM 	if (pMechanismList == NULL) {
211*12720SWyllys.Ingersoll@Sun.COM 		*pulCount = mechnum;
212*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
213*12720SWyllys.Ingersoll@Sun.COM 	}
214*12720SWyllys.Ingersoll@Sun.COM 	if (*pulCount < mechnum) {
215*12720SWyllys.Ingersoll@Sun.COM 		*pulCount = mechnum;
216*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_BUFFER_TOO_SMALL);
217*12720SWyllys.Ingersoll@Sun.COM 	}
218*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < mechnum; i++)
219*12720SWyllys.Ingersoll@Sun.COM 		pMechanismList[i] = kms_mechanisms[i];
220*12720SWyllys.Ingersoll@Sun.COM 
221*12720SWyllys.Ingersoll@Sun.COM 	*pulCount = mechnum;
222*12720SWyllys.Ingersoll@Sun.COM 
223*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
224*12720SWyllys.Ingersoll@Sun.COM }
225*12720SWyllys.Ingersoll@Sun.COM 
226*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_GetMechanismInfo(CK_SLOT_ID slotID,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)227*12720SWyllys.Ingersoll@Sun.COM C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
228*12720SWyllys.Ingersoll@Sun.COM     CK_MECHANISM_INFO_PTR pInfo)
229*12720SWyllys.Ingersoll@Sun.COM {
230*12720SWyllys.Ingersoll@Sun.COM 	CK_ULONG mechnum, i;
231*12720SWyllys.Ingersoll@Sun.COM 
232*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
233*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
234*12720SWyllys.Ingersoll@Sun.COM 
235*12720SWyllys.Ingersoll@Sun.COM 	if (slotID != KMS_TOKEN_SLOTID ||
236*12720SWyllys.Ingersoll@Sun.COM 	    !kms_is_initialized())
237*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_SLOT_ID_INVALID);
238*12720SWyllys.Ingersoll@Sun.COM 
239*12720SWyllys.Ingersoll@Sun.COM 	if (pInfo == NULL) {
240*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
241*12720SWyllys.Ingersoll@Sun.COM 	}
242*12720SWyllys.Ingersoll@Sun.COM 
243*12720SWyllys.Ingersoll@Sun.COM 	mechnum = sizeof (kms_mechanisms) / sizeof (CK_MECHANISM_TYPE);
244*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < mechnum; i++) {
245*12720SWyllys.Ingersoll@Sun.COM 		if (kms_mechanisms[i] == type)
246*12720SWyllys.Ingersoll@Sun.COM 			break;
247*12720SWyllys.Ingersoll@Sun.COM 	}
248*12720SWyllys.Ingersoll@Sun.COM 
249*12720SWyllys.Ingersoll@Sun.COM 	if (i == mechnum)
250*12720SWyllys.Ingersoll@Sun.COM 		/* unsupported mechanism */
251*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_MECHANISM_INVALID);
252*12720SWyllys.Ingersoll@Sun.COM 
253*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulMinKeySize = kms_mechanism_info[i].ulMinKeySize;
254*12720SWyllys.Ingersoll@Sun.COM 	pInfo->ulMaxKeySize = kms_mechanism_info[i].ulMaxKeySize;
255*12720SWyllys.Ingersoll@Sun.COM 	pInfo->flags = kms_mechanism_info[i].flags;
256*12720SWyllys.Ingersoll@Sun.COM 
257*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
258*12720SWyllys.Ingersoll@Sun.COM }
259*12720SWyllys.Ingersoll@Sun.COM 
260*12720SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/
261*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_InitToken(CK_SLOT_ID slotID,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel)262*12720SWyllys.Ingersoll@Sun.COM C_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
263*12720SWyllys.Ingersoll@Sun.COM     CK_UTF8CHAR_PTR pLabel)
264*12720SWyllys.Ingersoll@Sun.COM {
265*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_FUNCTION_FAILED;
266*12720SWyllys.Ingersoll@Sun.COM 	kms_cfg_info_t kmscfg;
267*12720SWyllys.Ingersoll@Sun.COM 	KMSAGENT_PROFILE_FLAGS kmsflags;
268*12720SWyllys.Ingersoll@Sun.COM 
269*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
270*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
271*12720SWyllys.Ingersoll@Sun.COM 
272*12720SWyllys.Ingersoll@Sun.COM 	if (slotID != KMS_TOKEN_SLOTID ||
273*12720SWyllys.Ingersoll@Sun.COM 	    !kms_is_initialized())
274*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_SLOT_ID_INVALID);
275*12720SWyllys.Ingersoll@Sun.COM 
276*12720SWyllys.Ingersoll@Sun.COM 	if (KMS_GetConfigInfo(&kmscfg) != CKR_OK ||
277*12720SWyllys.Ingersoll@Sun.COM 	    KMSAgent_GetProfileStatus(kmscfg.name, &kmsflags) !=
278*12720SWyllys.Ingersoll@Sun.COM 	    KMS_AGENT_STATUS_OK)
279*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
280*12720SWyllys.Ingersoll@Sun.COM 
281*12720SWyllys.Ingersoll@Sun.COM 	if (!(kmsflags & KMSAGENT_PROFILE_EXISTS_FLAG) ||
282*12720SWyllys.Ingersoll@Sun.COM 	    !(kmsflags & KMSAGENT_CLIENTKEY_EXISTS_FLAG)) {
283*12720SWyllys.Ingersoll@Sun.COM 		KMSClientProfile kmsProfile;
284*12720SWyllys.Ingersoll@Sun.COM 		/*
285*12720SWyllys.Ingersoll@Sun.COM 		 * Attempt to enroll and load a KMS profile.
286*12720SWyllys.Ingersoll@Sun.COM 		 * This will force the KMSAgent library to fetch
287*12720SWyllys.Ingersoll@Sun.COM 		 * the profile, the CA certificate, and the
288*12720SWyllys.Ingersoll@Sun.COM 		 * client private key and store them locally so that
289*12720SWyllys.Ingersoll@Sun.COM 		 * the KMS agent API can be used later.
290*12720SWyllys.Ingersoll@Sun.COM 		 */
291*12720SWyllys.Ingersoll@Sun.COM 		rv = KMS_LoadProfile(
292*12720SWyllys.Ingersoll@Sun.COM 		    &kmsProfile,
293*12720SWyllys.Ingersoll@Sun.COM 		    &kmscfg,
294*12720SWyllys.Ingersoll@Sun.COM 		    (const char *)pPin,
295*12720SWyllys.Ingersoll@Sun.COM 		    (size_t)ulPinLen);
296*12720SWyllys.Ingersoll@Sun.COM 
297*12720SWyllys.Ingersoll@Sun.COM 		if (rv == CKR_OK)
298*12720SWyllys.Ingersoll@Sun.COM 			KMS_UnloadProfile(&kmsProfile);
299*12720SWyllys.Ingersoll@Sun.COM 	}
300*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
301*12720SWyllys.Ingersoll@Sun.COM }
302*12720SWyllys.Ingersoll@Sun.COM 
303*12720SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/
304*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_InitPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)305*12720SWyllys.Ingersoll@Sun.COM C_InitPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
306*12720SWyllys.Ingersoll@Sun.COM {
307*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
308*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
309*12720SWyllys.Ingersoll@Sun.COM 
310*12720SWyllys.Ingersoll@Sun.COM 	/*
311*12720SWyllys.Ingersoll@Sun.COM 	 * Could be supported once the agent library supports
312*12720SWyllys.Ingersoll@Sun.COM 	 * storing the client certificate in a PKCS#12 file.
313*12720SWyllys.Ingersoll@Sun.COM 	 */
314*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_FUNCTION_NOT_SUPPORTED);
315*12720SWyllys.Ingersoll@Sun.COM }
316*12720SWyllys.Ingersoll@Sun.COM 
317*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_SetPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pOldPin,CK_ULONG ulOldLen,CK_UTF8CHAR_PTR pNewPin,CK_ULONG ulNewLen)318*12720SWyllys.Ingersoll@Sun.COM C_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
319*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
320*12720SWyllys.Ingersoll@Sun.COM {
321*12720SWyllys.Ingersoll@Sun.COM 	CK_RV	rv = CKR_OK;
322*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t *session_p;
323*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
324*12720SWyllys.Ingersoll@Sun.COM 
325*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
326*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
327*12720SWyllys.Ingersoll@Sun.COM 
328*12720SWyllys.Ingersoll@Sun.COM 	/*
329*12720SWyllys.Ingersoll@Sun.COM 	 * Obtain the session pointer. Also, increment the session
330*12720SWyllys.Ingersoll@Sun.COM 	 * reference count.
331*12720SWyllys.Ingersoll@Sun.COM 	 */
332*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(hSession, &session_p);
333*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
334*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
335*12720SWyllys.Ingersoll@Sun.COM 
336*12720SWyllys.Ingersoll@Sun.COM 	/* Make sure it is a RW session. */
337*12720SWyllys.Ingersoll@Sun.COM 	if (session_p->ses_RO) {
338*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_SESSION_READ_ONLY;
339*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
340*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
341*12720SWyllys.Ingersoll@Sun.COM 	}
342*12720SWyllys.Ingersoll@Sun.COM 
343*12720SWyllys.Ingersoll@Sun.COM 	/*
344*12720SWyllys.Ingersoll@Sun.COM 	 * If the token is not yet initialized, we cannot set the pin.
345*12720SWyllys.Ingersoll@Sun.COM 	 */
346*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_is_initialized()) {
347*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
348*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_FUNCTION_FAILED);
349*12720SWyllys.Ingersoll@Sun.COM 	}
350*12720SWyllys.Ingersoll@Sun.COM 
351*12720SWyllys.Ingersoll@Sun.COM 	if (pOldPin == NULL || ulOldLen == 0 ||
352*12720SWyllys.Ingersoll@Sun.COM 	    pNewPin == NULL || ulNewLen == 0) {
353*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
354*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
355*12720SWyllys.Ingersoll@Sun.COM 	}
356*12720SWyllys.Ingersoll@Sun.COM 
357*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_is_pin_set()) {
358*12720SWyllys.Ingersoll@Sun.COM 		/*
359*12720SWyllys.Ingersoll@Sun.COM 		 * We don't yet support this mode since
360*12720SWyllys.Ingersoll@Sun.COM 		 * the KMS private key file will automatically
361*12720SWyllys.Ingersoll@Sun.COM 		 * be generated using the KMS Agent passphrase
362*12720SWyllys.Ingersoll@Sun.COM 		 * which is initialized out-of-band.
363*12720SWyllys.Ingersoll@Sun.COM 		 */
364*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_FUNCTION_NOT_SUPPORTED;
365*12720SWyllys.Ingersoll@Sun.COM 
366*12720SWyllys.Ingersoll@Sun.COM 	} else {
367*12720SWyllys.Ingersoll@Sun.COM 		/*
368*12720SWyllys.Ingersoll@Sun.COM 		 * Login to KMS by attempting to load the profile using
369*12720SWyllys.Ingersoll@Sun.COM 		 * the given password.
370*12720SWyllys.Ingersoll@Sun.COM 		 */
371*12720SWyllys.Ingersoll@Sun.COM 		rv = KMS_LoadProfile(&session_p->kmsProfile,
372*12720SWyllys.Ingersoll@Sun.COM 		    &session_p->configInfo,
373*12720SWyllys.Ingersoll@Sun.COM 		    (const char *)pOldPin,
374*12720SWyllys.Ingersoll@Sun.COM 		    (size_t)ulOldLen);
375*12720SWyllys.Ingersoll@Sun.COM 		if (rv == CKR_USER_ANOTHER_ALREADY_LOGGED_IN)
376*12720SWyllys.Ingersoll@Sun.COM 			rv = CKR_OK;
377*12720SWyllys.Ingersoll@Sun.COM 
378*12720SWyllys.Ingersoll@Sun.COM 		if (rv == CKR_OK)
379*12720SWyllys.Ingersoll@Sun.COM 			rv = KMS_ChangeLocalPWD(session_p,
380*12720SWyllys.Ingersoll@Sun.COM 			    (const char *)pOldPin,
381*12720SWyllys.Ingersoll@Sun.COM 			    (const char *)pNewPin);
382*12720SWyllys.Ingersoll@Sun.COM 	}
383*12720SWyllys.Ingersoll@Sun.COM 
384*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
385*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
386*12720SWyllys.Ingersoll@Sun.COM }
387