1 /*
2  * GnuTLS PKCS#11 support
3  * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4  * Copyright (C) 2008, Joe Orton <joe@manyfish.co.uk>
5  *
6  * Authors: Nikos Mavrogiannopoulos, Stef Walter
7  *
8  * Inspired and some parts (pkcs11_login) based on neon PKCS #11 support
9  * by Joe Orton. More ideas came from the pkcs11-helper library by
10  * Alon Bar-Lev.
11  *
12  * The GnuTLS is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public License
14  * as published by the Free Software Foundation; either version 2.1 of
15  * the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * along with this program.  If not, see <https://www.gnu.org/licenses/>
24  */
25 
26 #include "gnutls_int.h"
27 #include <gnutls/pkcs11.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include "errors.h"
31 #include <datum.h>
32 
33 #include <pin.h>
34 #include <pkcs11_int.h>
35 #include <p11-kit/p11-kit.h>
36 #include <p11-kit/pkcs11.h>
37 #include <p11-kit/pin.h>
38 
39 ck_rv_t
pkcs11_get_slot_list(struct ck_function_list * module,unsigned char token_present,ck_slot_id_t * slot_list,unsigned long * count)40 pkcs11_get_slot_list(struct ck_function_list * module,
41 		     unsigned char token_present, ck_slot_id_t * slot_list,
42 		     unsigned long *count)
43 {
44 	return (module)->C_GetSlotList(token_present, slot_list, count);
45 }
46 
47 ck_rv_t
pkcs11_get_module_info(struct ck_function_list * module,struct ck_info * info)48 pkcs11_get_module_info(struct ck_function_list * module,
49 		       struct ck_info * info)
50 {
51 	return (module)->C_GetInfo(info);
52 }
53 
54 ck_rv_t
pkcs11_get_slot_info(struct ck_function_list * module,ck_slot_id_t slot_id,struct ck_slot_info * info)55 pkcs11_get_slot_info(struct ck_function_list * module,
56 		     ck_slot_id_t slot_id, struct ck_slot_info * info)
57 {
58 	return (module)->C_GetSlotInfo(slot_id, info);
59 }
60 
61 ck_rv_t
pkcs11_get_token_info(struct ck_function_list * module,ck_slot_id_t slot_id,struct ck_token_info * info)62 pkcs11_get_token_info(struct ck_function_list * module,
63 		      ck_slot_id_t slot_id, struct ck_token_info * info)
64 {
65 	return (module)->C_GetTokenInfo(slot_id, info);
66 }
67 
68 ck_rv_t
pkcs11_find_objects_init(struct ck_function_list * module,ck_session_handle_t sess,struct ck_attribute * templ,unsigned long count)69 pkcs11_find_objects_init(struct ck_function_list * module,
70 			 ck_session_handle_t sess,
71 			 struct ck_attribute * templ, unsigned long count)
72 {
73 	return (module)->C_FindObjectsInit(sess, templ, count);
74 }
75 
76 ck_rv_t
pkcs11_find_objects(struct ck_function_list * module,ck_session_handle_t sess,ck_object_handle_t * objects,unsigned long max_object_count,unsigned long * object_count)77 pkcs11_find_objects(struct ck_function_list * module,
78 		    ck_session_handle_t sess,
79 		    ck_object_handle_t * objects,
80 		    unsigned long max_object_count,
81 		    unsigned long *object_count)
82 {
83 	return (module)->C_FindObjects(sess, objects, max_object_count,
84 				       object_count);
85 }
86 
pkcs11_find_objects_final(struct pkcs11_session_info * sinfo)87 ck_rv_t pkcs11_find_objects_final(struct pkcs11_session_info * sinfo)
88 {
89 	return (sinfo->module)->C_FindObjectsFinal(sinfo->pks);
90 }
91 
pkcs11_close_session(struct pkcs11_session_info * sinfo)92 ck_rv_t pkcs11_close_session(struct pkcs11_session_info * sinfo)
93 {
94 	sinfo->init = 0;
95 	return (sinfo->module)->C_CloseSession(sinfo->pks);
96 }
97 
98 ck_rv_t
pkcs11_set_attribute_value(struct ck_function_list * module,ck_session_handle_t sess,ck_object_handle_t object,struct ck_attribute * templ,unsigned long count)99 pkcs11_set_attribute_value(struct ck_function_list * module,
100 			   ck_session_handle_t sess,
101 			   ck_object_handle_t object,
102 			   struct ck_attribute * templ,
103 			   unsigned long count)
104 {
105 	return (module)->C_SetAttributeValue(sess, object, templ, count);
106 }
107 
108 ck_rv_t
pkcs11_get_attribute_value(struct ck_function_list * module,ck_session_handle_t sess,ck_object_handle_t object,struct ck_attribute * templ,unsigned long count)109 pkcs11_get_attribute_value(struct ck_function_list * module,
110 			   ck_session_handle_t sess,
111 			   ck_object_handle_t object,
112 			   struct ck_attribute * templ,
113 			   unsigned long count)
114 {
115 	return (module)->C_GetAttributeValue(sess, object, templ, count);
116 }
117 
118 /* Returns only a single attribute value, but allocates its data
119  * Only the type needs to be set.
120  */
121 ck_rv_t
pkcs11_get_attribute_avalue(struct ck_function_list * module,ck_session_handle_t sess,ck_object_handle_t object,ck_attribute_type_t type,gnutls_datum_t * res)122 pkcs11_get_attribute_avalue(struct ck_function_list * module,
123 			   ck_session_handle_t sess,
124 			   ck_object_handle_t object,
125 			   ck_attribute_type_t type,
126 			   gnutls_datum_t *res)
127 {
128 	ck_rv_t rv;
129 	struct ck_attribute templ;
130 	void *t;
131 
132 	res->data = NULL;
133 	res->size = 0;
134 
135 	templ.type = type;
136 	templ.value = NULL;
137 	templ.value_len = 0;
138 	rv = (module)->C_GetAttributeValue(sess, object, &templ, 1);
139 	if (rv == CKR_OK) {
140 		/* PKCS#11 v2.20 requires sensitive values to set a length
141 		 * of -1. In that case an error should have been returned,
142 		 * but some implementations return CKR_OK instead. */
143 		if (templ.value_len == (unsigned long)-1)
144 			return CKR_ATTRIBUTE_SENSITIVE;
145 
146 		if (templ.value_len == 0)
147 			return rv;
148 
149 		templ.type = type;
150 		t = gnutls_malloc(templ.value_len);
151 		if (t == NULL)
152 			return gnutls_assert_val(CKR_HOST_MEMORY);
153 		templ.value = t;
154 		rv = (module)->C_GetAttributeValue(sess, object, &templ, 1);
155 		if (rv != CKR_OK) {
156 			gnutls_free(t);
157 			return rv;
158 		}
159 		res->data = t;
160 		res->size = templ.value_len;
161 	}
162 	return rv;
163 }
164 
165 ck_rv_t
pkcs11_get_mechanism_list(struct ck_function_list * module,ck_slot_id_t slot_id,ck_mechanism_type_t * mechanism_list,unsigned long * count)166 pkcs11_get_mechanism_list(struct ck_function_list * module,
167 			  ck_slot_id_t slot_id,
168 			  ck_mechanism_type_t * mechanism_list,
169 			  unsigned long *count)
170 {
171 	return (module)->C_GetMechanismList(slot_id, mechanism_list,
172 					    count);
173 }
174 
175 ck_rv_t
pkcs11_get_mechanism_info(struct ck_function_list * module,ck_slot_id_t slot_id,ck_mechanism_type_t mechanism,struct ck_mechanism_info * ptr)176 pkcs11_get_mechanism_info(struct ck_function_list *module,
177 			  ck_slot_id_t slot_id,
178 			  ck_mechanism_type_t mechanism,
179 			  struct ck_mechanism_info *ptr)
180 {
181 	return (module)->C_GetMechanismInfo(slot_id, mechanism,
182 					    ptr);
183 }
184 
185 ck_rv_t
pkcs11_sign_init(struct ck_function_list * module,ck_session_handle_t sess,struct ck_mechanism * mechanism,ck_object_handle_t key)186 pkcs11_sign_init(struct ck_function_list * module,
187 		 ck_session_handle_t sess,
188 		 struct ck_mechanism * mechanism, ck_object_handle_t key)
189 {
190 	return (module)->C_SignInit(sess, mechanism, key);
191 }
192 
193 ck_rv_t
pkcs11_sign(struct ck_function_list * module,ck_session_handle_t sess,unsigned char * data,unsigned long data_len,unsigned char * signature,unsigned long * signature_len)194 pkcs11_sign(struct ck_function_list * module,
195 	    ck_session_handle_t sess,
196 	    unsigned char *data,
197 	    unsigned long data_len,
198 	    unsigned char *signature, unsigned long *signature_len)
199 {
200 	return (module)->C_Sign(sess, data, data_len, signature,
201 				signature_len);
202 }
203 
204 ck_rv_t
pkcs11_generate_key(struct ck_function_list * module,ck_session_handle_t sess,struct ck_mechanism * mechanism,struct ck_attribute * templ,unsigned long count,ck_object_handle_t * key)205 pkcs11_generate_key(struct ck_function_list * module,
206 		    ck_session_handle_t sess,
207 		    struct ck_mechanism * mechanism,
208 		    struct ck_attribute * templ,
209 		    unsigned long count,
210 		    ck_object_handle_t * key)
211 {
212 	return (module)->C_GenerateKey(sess, mechanism, templ, count, key);
213 }
214 
215 ck_rv_t
pkcs11_generate_key_pair(struct ck_function_list * module,ck_session_handle_t sess,struct ck_mechanism * mechanism,struct ck_attribute * pub_templ,unsigned long pub_templ_count,struct ck_attribute * priv_templ,unsigned long priv_templ_count,ck_object_handle_t * pub_ctx,ck_object_handle_t * priv_ctx)216 pkcs11_generate_key_pair(struct ck_function_list * module,
217 			 ck_session_handle_t sess,
218 			 struct ck_mechanism * mechanism,
219 			 struct ck_attribute * pub_templ,
220 			 unsigned long pub_templ_count,
221 			 struct ck_attribute * priv_templ,
222 			 unsigned long priv_templ_count,
223 			 ck_object_handle_t * pub_ctx,
224 			 ck_object_handle_t * priv_ctx)
225 {
226 	return (module)->C_GenerateKeyPair(sess, mechanism, pub_templ,
227 					   pub_templ_count, priv_templ,
228 					   priv_templ_count, pub_ctx, priv_ctx);
229 }
230 
231 ck_rv_t
pkcs11_decrypt_init(struct ck_function_list * module,ck_session_handle_t sess,struct ck_mechanism * mechanism,ck_object_handle_t key_ctx)232 pkcs11_decrypt_init(struct ck_function_list * module,
233 		    ck_session_handle_t sess,
234 		    struct ck_mechanism * mechanism,
235 		    ck_object_handle_t key_ctx)
236 {
237 	return (module)->C_DecryptInit(sess, mechanism, key_ctx);
238 }
239 
240 ck_rv_t
pkcs11_decrypt(struct ck_function_list * module,ck_session_handle_t sess,unsigned char * encrypted_data,unsigned long encrypted_data_len,unsigned char * data,unsigned long * data_len)241 pkcs11_decrypt(struct ck_function_list * module,
242 	       ck_session_handle_t sess,
243 	       unsigned char *encrypted_data,
244 	       unsigned long encrypted_data_len,
245 	       unsigned char *data, unsigned long *data_len)
246 {
247 	return (module)->C_Decrypt(sess, encrypted_data,
248 				   encrypted_data_len, data, data_len);
249 }
250 
251 ck_rv_t
pkcs11_create_object(struct ck_function_list * module,ck_session_handle_t sess,struct ck_attribute * templ,unsigned long count,ck_object_handle_t * ctx)252 pkcs11_create_object(struct ck_function_list * module,
253 		     ck_session_handle_t sess,
254 		     struct ck_attribute * templ,
255 		     unsigned long count, ck_object_handle_t * ctx)
256 {
257 	return (module)->C_CreateObject(sess, templ, count, ctx);
258 }
259 
260 ck_rv_t
pkcs11_destroy_object(struct ck_function_list * module,ck_session_handle_t sess,ck_object_handle_t ctx)261 pkcs11_destroy_object(struct ck_function_list * module,
262 		      ck_session_handle_t sess, ck_object_handle_t ctx)
263 {
264 	return (module)->C_DestroyObject(sess, ctx);
265 }
266 
267 ck_rv_t
pkcs11_init_token(struct ck_function_list * module,ck_slot_id_t slot_id,unsigned char * pin,unsigned long pin_len,unsigned char * label)268 pkcs11_init_token(struct ck_function_list * module,
269 		  ck_slot_id_t slot_id, unsigned char *pin,
270 		  unsigned long pin_len, unsigned char *label)
271 {
272 	return (module)->C_InitToken(slot_id, pin, pin_len, label);
273 }
274 
275 ck_rv_t
pkcs11_init_pin(struct ck_function_list * module,ck_session_handle_t sess,unsigned char * pin,unsigned long pin_len)276 pkcs11_init_pin(struct ck_function_list * module,
277 		ck_session_handle_t sess,
278 		unsigned char *pin, unsigned long pin_len)
279 {
280 	return (module)->C_InitPIN(sess, pin, pin_len);
281 }
282 
283 ck_rv_t
pkcs11_set_pin(struct ck_function_list * module,ck_session_handle_t sess,const char * old_pin,unsigned long old_len,const char * new_pin,unsigned long new_len)284 pkcs11_set_pin(struct ck_function_list * module,
285 	       ck_session_handle_t sess,
286 	       const char *old_pin,
287 	       unsigned long old_len,
288 	       const char *new_pin, unsigned long new_len)
289 {
290 	return (module)->C_SetPIN(sess, (uint8_t *) old_pin, old_len,
291 				  (uint8_t *) new_pin, new_len);
292 }
293 
294 ck_rv_t
_gnutls_pkcs11_get_random(struct ck_function_list * module,ck_session_handle_t sess,void * data,size_t len)295 _gnutls_pkcs11_get_random(struct ck_function_list * module,
296 		  ck_session_handle_t sess, void *data, size_t len)
297 {
298 	return (module)->C_GenerateRandom(sess, data, len);
299 }
300 
pkcs11_strerror(ck_rv_t rv)301 const char *pkcs11_strerror(ck_rv_t rv)
302 {
303 	return p11_kit_strerror(rv);
304 }
305