1 /*
2  * GnuTLS PKCS#11 support
3  * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4  *
5  * Authors: Nikos Mavrogiannopoulos, Stef Walter
6  *
7  * The GnuTLS is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>
19  */
20 
21 #ifndef GNUTLS_LIB_PKCS11_INT_H
22 #define GNUTLS_LIB_PKCS11_INT_H
23 
24 #ifdef ENABLE_PKCS11
25 
26 #define CRYPTOKI_GNU
27 #include <p11-kit/pkcs11.h>
28 #include <gnutls/pkcs11.h>
29 #include <x509/x509_int.h>
30 
31 /* Part of PKCS#11 3.0 interface, which was added in p11-kit 0.23.14 */
32 #ifdef CKM_EDDSA
33 #define HAVE_CKM_EDDSA
34 #endif
35 
36 #define PKCS11_ID_SIZE 128
37 #define PKCS11_LABEL_SIZE 128
38 
39 #include <p11-kit/p11-kit.h>
40 #include <p11-kit/pin.h>
41 #include <p11-kit/uri.h>
42 typedef unsigned char ck_bool_t;
43 
44 struct pkcs11_session_info {
45 	struct ck_function_list *module;
46 	struct ck_token_info tinfo;
47 	struct ck_slot_info slot_info;
48 	ck_session_handle_t pks;
49 	ck_slot_id_t sid;
50 	unsigned int init;
51 	unsigned int trusted; /* whether module is marked as trusted */
52 };
53 
54 struct gnutls_pkcs11_obj_st {
55 	gnutls_datum_t raw;
56 	gnutls_pkcs11_obj_type_t type;
57 	ck_object_class_t class;
58 
59 	unsigned int flags;
60 	struct p11_kit_uri *info;
61 
62 	/* only when pubkey */
63 	gnutls_datum_t pubkey[MAX_PUBLIC_PARAMS_SIZE];
64 	unsigned pubkey_size;
65 	gnutls_pk_algorithm_t pk_algorithm;
66 	unsigned int key_usage;
67 
68 	struct pin_info_st pin;
69 };
70 
71 struct gnutls_pkcs11_privkey_st {
72 	gnutls_pk_algorithm_t pk_algorithm;
73 	unsigned int rsa_pss_ok; /* if it is an RSA key, it can do RSA-PSS */
74 	unsigned int bits;
75 
76 	unsigned int flags;
77 	struct p11_kit_uri *uinfo;
78 	char *url;
79 
80 	struct pkcs11_session_info sinfo;
81 	ck_object_handle_t ref;	/* the key in the session */
82 	unsigned reauth; /* whether we need to login on each operation */
83 
84 	void *mutex; /* lock for operations requiring co-ordination */
85 
86 	struct pin_info_st pin;
87 };
88 
89 /* This must be called on every function that uses a PKCS #11 function
90  * directly. It can be provided a callback function to run when a reinitialization
91  * occurs. */
92 typedef int (*pkcs11_reinit_function)(void *priv);
93 
94 typedef enum init_level_t {
95 	PROV_UNINITIALIZED = 0,
96 	PROV_INIT_MANUAL,
97 	PROV_INIT_MANUAL_TRUSTED,
98 	PROV_INIT_TRUSTED,
99 	PROV_INIT_ALL
100 } init_level_t;
101 
102 /* See _gnutls_pkcs11_check_init() for possible Transitions.
103  */
104 
105 int _gnutls_pkcs11_check_init(init_level_t req_level, void *priv, pkcs11_reinit_function cb);
106 
107 #define FIX_KEY_USAGE(pk, usage) \
108 	if (usage == 0) { \
109 		if (pk == GNUTLS_PK_RSA) \
110 			usage = GNUTLS_KEY_DECIPHER_ONLY|GNUTLS_KEY_DIGITAL_SIGNATURE; \
111 		else \
112 			usage = GNUTLS_KEY_DIGITAL_SIGNATURE; \
113 	}
114 
115 #define PKCS11_CHECK_INIT \
116 	ret = _gnutls_pkcs11_check_init(PROV_INIT_ALL, NULL, NULL); \
117 	if (ret < 0) \
118 		return gnutls_assert_val(ret)
119 
120 #define PKCS11_CHECK_INIT_RET(x) \
121 	ret = _gnutls_pkcs11_check_init(PROV_INIT_ALL, NULL, NULL); \
122 	if (ret < 0) \
123 		return gnutls_assert_val(x)
124 
125 #define PKCS11_CHECK_INIT_FLAGS(f) \
126 	ret = _gnutls_pkcs11_check_init((f & GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE)?PROV_INIT_TRUSTED:PROV_INIT_ALL, NULL, NULL); \
127 	if (ret < 0) \
128 		return gnutls_assert_val(ret)
129 
130 #define PKCS11_CHECK_INIT_FLAGS_RET(f, x) \
131 	ret = _gnutls_pkcs11_check_init((f & GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE)?PROV_INIT_TRUSTED:PROV_INIT_ALL, NULL, NULL); \
132 	if (ret < 0) \
133 		return gnutls_assert_val(x)
134 
135 
136 /* thus function is called for every token in the traverse_tokens
137  * function. Once everything is traversed it is called with NULL tinfo.
138  * It should return 0 if found what it was looking for.
139  */
140 typedef int (*find_func_t) (struct ck_function_list *, struct pkcs11_session_info *,
141 			    struct ck_token_info * tinfo, struct ck_info *,
142 			    void *input);
143 
144 int pkcs11_rv_to_err(ck_rv_t rv);
145 int pkcs11_url_to_info(const char *url, struct p11_kit_uri **info, unsigned flags);
146 int
147 pkcs11_find_slot(struct ck_function_list **module, ck_slot_id_t * slot,
148 		 struct p11_kit_uri *info, struct ck_token_info *_tinfo,
149 		 struct ck_slot_info *_slot_info, unsigned int *trusted);
150 
151 int pkcs11_read_pubkey(struct ck_function_list *module,
152 		       ck_session_handle_t pks, ck_object_handle_t obj,
153 		       ck_key_type_t key_type, gnutls_pkcs11_obj_t pobj);
154 
155 int pkcs11_override_cert_exts(struct pkcs11_session_info *sinfo, gnutls_datum_t *spki, gnutls_datum_t *der);
156 
157 int pkcs11_get_info(struct p11_kit_uri *info,
158 		    gnutls_pkcs11_obj_info_t itype, void *output,
159 		    size_t * output_size);
160 int pkcs11_login(struct pkcs11_session_info *sinfo,
161 		 struct pin_info_st *pin_info,
162 		 struct p11_kit_uri *info, unsigned flags);
163 
164 int pkcs11_call_token_func(struct p11_kit_uri *info, const unsigned retry);
165 
166 extern gnutls_pkcs11_token_callback_t _gnutls_token_func;
167 extern void *_gnutls_token_data;
168 
169 void pkcs11_rescan_slots(void);
170 int pkcs11_info_to_url(struct p11_kit_uri *info,
171 		       gnutls_pkcs11_url_type_t detailed, char **url);
172 
173 int
174 _gnutls_x509_crt_import_pkcs11_url(gnutls_x509_crt_t crt,
175 				  const char *url, unsigned int flags);
176 
177 #define SESSION_WRITE (1<<0)
178 #define SESSION_LOGIN (1<<1)
179 #define SESSION_SO (1<<2)	/* security officer session */
180 #define SESSION_TRUSTED (1<<3) /* session on a marked as trusted (p11-kit) module */
181 #define SESSION_FORCE_LOGIN (1<<4) /* force login even when CFK_LOGIN_REQUIRED is not set */
182 #define SESSION_CONTEXT_SPECIFIC (1<<5)
183 #define SESSION_NO_CLOSE (1<<6) /* don't close session on success */
184 
185 int pkcs11_open_session(struct pkcs11_session_info *sinfo,
186 			struct pin_info_st *pin_info,
187 			struct p11_kit_uri *info, unsigned int flags);
188 int _pkcs11_traverse_tokens(find_func_t find_func, void *input,
189 			    struct p11_kit_uri *info,
190 			    struct pin_info_st *pin_info,
191 			    unsigned int flags);
192 ck_object_class_t pkcs11_strtype_to_class(const char *type);
193 
194 /* Additional internal flags for gnutls_pkcs11_obj_flags */
195 /* @GNUTLS_PKCS11_OBJ_FLAG_EXPECT_CERT: When importing an object, provide a hint on the type, to allow incomplete URLs
196  * @GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PRIVKEY: Hint for private key */
197 #define GNUTLS_PKCS11_OBJ_FLAG_FIRST_CLOSE_MATCH ((unsigned int)1<<28)
198 #define GNUTLS_PKCS11_OBJ_FLAG_EXPECT_CERT (1<<29)
199 #define GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PRIVKEY (1<<30)
200 #define GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PUBKEY ((unsigned int)1<<31)
201 
202 int pkcs11_token_matches_info(struct p11_kit_uri *info,
203 			      struct ck_token_info *tinfo,
204 			      struct ck_info *lib_info);
205 
206 unsigned int pkcs11_obj_flags_to_int(unsigned int flags);
207 
208 int
209 _gnutls_pkcs11_privkey_sign(gnutls_pkcs11_privkey_t key,
210 			    const gnutls_sign_entry_st *se,
211 			    const gnutls_datum_t * hash,
212 			    gnutls_datum_t * signature,
213 			    gnutls_x509_spki_st *spki_params);
214 
215 int
216 _gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key,
217 				    unsigned int flags,
218 				    const gnutls_datum_t * ciphertext,
219 				    gnutls_datum_t * plaintext);
220 
221 int
222 _gnutls_pkcs11_privkey_decrypt_data2(gnutls_pkcs11_privkey_t key,
223 				     unsigned int flags,
224 				     const gnutls_datum_t * ciphertext,
225 			             unsigned char * plaintext,
226 			             size_t plaintext_size);
227 
228 int
229 _pkcs11_privkey_get_pubkey (gnutls_pkcs11_privkey_t pkey, gnutls_pubkey_t *pub, unsigned flags);
230 
pk_to_mech(gnutls_pk_algorithm_t pk)231 static inline int pk_to_mech(gnutls_pk_algorithm_t pk)
232 {
233 	if (pk == GNUTLS_PK_DSA)
234 		return CKM_DSA;
235 	else if (pk == GNUTLS_PK_EC)
236 		return CKM_ECDSA;
237 	else if (pk == GNUTLS_PK_RSA)
238 		return CKM_RSA_PKCS;
239 	else if (pk == GNUTLS_PK_RSA_PSS)
240 		return CKM_RSA_PKCS_PSS;
241 #ifdef HAVE_CKM_EDDSA
242         else if (pk == GNUTLS_PK_EDDSA_ED25519)
243                 return CKM_EDDSA;
244 #endif
245 	else
246 		return -1;
247 }
248 
pk_to_key_type(gnutls_pk_algorithm_t pk)249 static inline int pk_to_key_type(gnutls_pk_algorithm_t pk)
250 {
251 	if (pk == GNUTLS_PK_DSA)
252 		return CKK_DSA;
253 	else if (pk == GNUTLS_PK_EC)
254 		return CKK_ECDSA;
255 	else if (pk == GNUTLS_PK_RSA_PSS || pk == GNUTLS_PK_RSA)
256 		return CKK_RSA;
257 #ifdef HAVE_CKM_EDDSA
258         else if (pk == GNUTLS_PK_EDDSA_ED25519)
259                 return CKK_EC_EDWARDS;
260 #endif
261 	else
262 		return -1;
263 }
264 
key_type_to_pk(ck_key_type_t m)265 static inline gnutls_pk_algorithm_t key_type_to_pk(ck_key_type_t m)
266 {
267 	if (m == CKK_RSA)
268 		return GNUTLS_PK_RSA;
269 	else if (m == CKK_DSA)
270 		return GNUTLS_PK_DSA;
271 	else if (m == CKK_ECDSA)
272 		return GNUTLS_PK_EC;
273 #ifdef HAVE_CKM_EDDSA
274         else if (m == CKK_EC_EDWARDS)
275                 return GNUTLS_PK_EDDSA_ED25519;
276 #endif
277 	else
278 		return GNUTLS_PK_UNKNOWN;
279 }
280 
pk_to_genmech(gnutls_pk_algorithm_t pk,ck_key_type_t * type)281 static inline int pk_to_genmech(gnutls_pk_algorithm_t pk, ck_key_type_t *type)
282 {
283 	if (pk == GNUTLS_PK_DSA) {
284 		*type = CKK_DSA;
285 		return CKM_DSA_KEY_PAIR_GEN;
286 	} else if (pk == GNUTLS_PK_EC) {
287 		*type = CKK_ECDSA;
288 		return CKM_ECDSA_KEY_PAIR_GEN;
289 	} else if (pk == GNUTLS_PK_RSA_PSS || pk == GNUTLS_PK_RSA) {
290 		*type = CKK_RSA;
291 		return CKM_RSA_PKCS_KEY_PAIR_GEN;
292 #ifdef HAVE_CKM_EDDSA
293         } else if (pk == GNUTLS_PK_EDDSA_ED25519) {
294                 *type = CKK_EC_EDWARDS;
295                 return CKM_EDDSA;
296 #endif
297 	} else {
298 		*type = -1;
299 		return -1;
300 	}
301 }
302 
303 int
304 pkcs11_retrieve_pin(struct pin_info_st *pin_info, struct p11_kit_uri *info,
305 		    struct ck_token_info *token_info, int attempts,
306 		    ck_user_type_t user_type, struct p11_kit_pin **pin);
307 
308 ck_object_class_t pkcs11_type_to_class(gnutls_pkcs11_obj_type_t type);
309 
310 ck_rv_t
311 pkcs11_generate_key(struct ck_function_list * module,
312 		    ck_session_handle_t sess,
313 		    struct ck_mechanism * mechanism,
314 		    struct ck_attribute * templ,
315 		    unsigned long count,
316 		    ck_object_handle_t * key);
317 
318 ck_rv_t
319 pkcs11_generate_key_pair(struct ck_function_list * module,
320 			 ck_session_handle_t sess,
321 			 struct ck_mechanism * mechanism,
322 			 struct ck_attribute * pub_templ,
323 			 unsigned long pub_templ_count,
324 			 struct ck_attribute * priv_templ,
325 			 unsigned long priv_templ_count,
326 			 ck_object_handle_t * pub,
327 			 ck_object_handle_t * priv);
328 
329 ck_rv_t
330 pkcs11_get_slot_list(struct ck_function_list *module,
331 		     unsigned char token_present,
332 		     ck_slot_id_t * slot_list, unsigned long *count);
333 
334 ck_rv_t
335 pkcs11_get_module_info(struct ck_function_list *module,
336 		       struct ck_info *info);
337 
338 ck_rv_t
339 pkcs11_get_slot_info(struct ck_function_list *module,
340 		     ck_slot_id_t slot_id, struct ck_slot_info *info);
341 
342 ck_rv_t
343 pkcs11_get_token_info(struct ck_function_list *module,
344 		      ck_slot_id_t slot_id, struct ck_token_info *info);
345 
346 ck_rv_t
347 pkcs11_find_objects_init(struct ck_function_list *module,
348 			 ck_session_handle_t sess,
349 			 struct ck_attribute *templ, unsigned long count);
350 
351 ck_rv_t
352 pkcs11_find_objects(struct ck_function_list *module,
353 		    ck_session_handle_t sess,
354 		    ck_object_handle_t * objects,
355 		    unsigned long max_object_count,
356 		    unsigned long *object_count);
357 
358 ck_rv_t pkcs11_find_objects_final(struct pkcs11_session_info *);
359 
360 ck_rv_t pkcs11_close_session(struct pkcs11_session_info *);
361 
362 ck_rv_t
363 pkcs11_set_attribute_value(struct ck_function_list * module,
364 			   ck_session_handle_t sess,
365 			   ck_object_handle_t object,
366 			   struct ck_attribute * templ,
367 			   unsigned long count);
368 
369 ck_rv_t
370 pkcs11_get_attribute_value(struct ck_function_list *module,
371 			   ck_session_handle_t sess,
372 			   ck_object_handle_t object,
373 			   struct ck_attribute *templ,
374 			   unsigned long count);
375 
376 ck_rv_t
377 pkcs11_get_attribute_avalue(struct ck_function_list * module,
378 			   ck_session_handle_t sess,
379 			   ck_object_handle_t object,
380 			   ck_attribute_type_t type,
381 			   gnutls_datum_t *res);
382 
383 ck_rv_t
384 pkcs11_get_mechanism_list(struct ck_function_list *module,
385 			  ck_slot_id_t slot_id,
386 			  ck_mechanism_type_t * mechanism_list,
387 			  unsigned long *count);
388 
389 ck_rv_t
390 pkcs11_get_mechanism_info(struct ck_function_list *module,
391 			  ck_slot_id_t slot_id,
392 			  ck_mechanism_type_t mechanism,
393 			  struct ck_mechanism_info *ptr);
394 
395 ck_rv_t
396 pkcs11_sign_init(struct ck_function_list *module,
397 		 ck_session_handle_t sess,
398 		 struct ck_mechanism *mechanism, ck_object_handle_t key);
399 
400 ck_rv_t
401 pkcs11_sign(struct ck_function_list *module,
402 	    ck_session_handle_t sess,
403 	    unsigned char *data,
404 	    unsigned long data_len,
405 	    unsigned char *signature, unsigned long *signature_len);
406 
407 ck_rv_t
408 pkcs11_decrypt_init(struct ck_function_list *module,
409 		    ck_session_handle_t sess,
410 		    struct ck_mechanism *mechanism,
411 		    ck_object_handle_t key);
412 
413 ck_rv_t
414 pkcs11_decrypt(struct ck_function_list *module,
415 	       ck_session_handle_t sess,
416 	       unsigned char *encrypted_data,
417 	       unsigned long encrypted_data_len,
418 	       unsigned char *data, unsigned long *data_len);
419 
420 ck_rv_t
421 pkcs11_create_object(struct ck_function_list *module,
422 		     ck_session_handle_t sess,
423 		     struct ck_attribute *templ,
424 		     unsigned long count, ck_object_handle_t * object);
425 
426 ck_rv_t
427 pkcs11_destroy_object(struct ck_function_list *module,
428 		      ck_session_handle_t sess, ck_object_handle_t object);
429 
430 ck_rv_t
431 pkcs11_init_token(struct ck_function_list *module,
432 		  ck_slot_id_t slot_id, unsigned char *pin,
433 		  unsigned long pin_len, unsigned char *label);
434 
435 ck_rv_t
436 pkcs11_init_pin(struct ck_function_list *module,
437 		ck_session_handle_t sess,
438 		unsigned char *pin, unsigned long pin_len);
439 
440 ck_rv_t
441 pkcs11_set_pin(struct ck_function_list *module,
442 	       ck_session_handle_t sess,
443 	       const char *old_pin,
444 	       unsigned long old_len,
445 	       const char *new_pin, unsigned long new_len);
446 
447 ck_rv_t
448 _gnutls_pkcs11_get_random(struct ck_function_list *module,
449 		  ck_session_handle_t sess, void *data, size_t len);
450 
451 
452 const char *pkcs11_strerror(ck_rv_t rv);
453 
454 /* Returns 1 if the provided URL is an object, rather than
455  * a token. */
is_pkcs11_url_object(const char * url)456 inline static bool is_pkcs11_url_object(const char *url)
457 {
458 	if (strstr(url, "id=") != 0 || strstr(url, "object=") != 0)
459 		return 1;
460 	return 0;
461 }
462 
463 unsigned
464 _gnutls_pkcs11_crt_is_known(const char *url, gnutls_x509_crt_t cert,
465 			    unsigned int flags,
466 			    gnutls_x509_crt_t *trusted_cert);
467 
468 #endif				/* ENABLE_PKCS11 */
469 
470 #endif /* GNUTLS_LIB_PKCS11_INT_H */
471