Line data Source code
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 :
231 206 : static inline int pk_to_mech(gnutls_pk_algorithm_t pk)
232 : {
233 206 : if (pk == GNUTLS_PK_DSA)
234 : return CKM_DSA;
235 206 : else if (pk == GNUTLS_PK_EC)
236 : return CKM_ECDSA;
237 101 : else if (pk == GNUTLS_PK_RSA)
238 : return CKM_RSA_PKCS;
239 22 : else if (pk == GNUTLS_PK_RSA_PSS)
240 : return CKM_RSA_PKCS_PSS;
241 : #ifdef HAVE_CKM_EDDSA
242 22 : else if (pk == GNUTLS_PK_EDDSA_ED25519)
243 : return CKM_EDDSA;
244 : #endif
245 : else
246 0 : return -1;
247 : }
248 :
249 3 : static inline int pk_to_key_type(gnutls_pk_algorithm_t pk)
250 : {
251 3 : if (pk == GNUTLS_PK_DSA)
252 : return CKK_DSA;
253 3 : else if (pk == GNUTLS_PK_EC)
254 : return CKK_ECDSA;
255 2 : else if (pk == GNUTLS_PK_RSA_PSS || pk == GNUTLS_PK_RSA)
256 : return CKK_RSA;
257 : #ifdef HAVE_CKM_EDDSA
258 1 : else if (pk == GNUTLS_PK_EDDSA_ED25519)
259 : return CKK_EC_EDWARDS;
260 : #endif
261 : else
262 0 : return -1;
263 : }
264 :
265 149 : static inline gnutls_pk_algorithm_t key_type_to_pk(ck_key_type_t m)
266 : {
267 149 : if (m == CKK_RSA)
268 : return GNUTLS_PK_RSA;
269 51 : else if (m == CKK_DSA)
270 : return GNUTLS_PK_DSA;
271 42 : else if (m == CKK_ECDSA)
272 : return GNUTLS_PK_EC;
273 : #ifdef HAVE_CKM_EDDSA
274 6 : else if (m == CKK_EC_EDWARDS)
275 : return GNUTLS_PK_EDDSA_ED25519;
276 : #endif
277 : else
278 0 : return GNUTLS_PK_UNKNOWN;
279 : }
280 :
281 36 : static inline int pk_to_genmech(gnutls_pk_algorithm_t pk, ck_key_type_t *type)
282 : {
283 36 : if (pk == GNUTLS_PK_DSA) {
284 : *type = CKK_DSA;
285 : return CKM_DSA_KEY_PAIR_GEN;
286 35 : } else if (pk == GNUTLS_PK_EC) {
287 : *type = CKK_ECDSA;
288 : return CKM_ECDSA_KEY_PAIR_GEN;
289 29 : } 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 1 : } else if (pk == GNUTLS_PK_EDDSA_ED25519) {
294 : *type = CKK_EC_EDWARDS;
295 : return CKM_EDDSA;
296 : #endif
297 : } else {
298 0 : *type = -1;
299 0 : 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. */
456 92 : inline static bool is_pkcs11_url_object(const char *url)
457 : {
458 92 : if (strstr(url, "id=") != 0 || strstr(url, "object=") != 0)
459 3 : 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 */
|