Line data Source code
1 : /*
2 : * GnuTLS PKCS#11 support
3 : * Copyright (C) 2010-2014 Free Software Foundation, Inc.
4 : * Copyright (C) 2012-2015 Nikos Mavrogiannopoulos
5 : * Copyright (C) 2016-2017 Red Hat, Inc.
6 : *
7 : * Author: Nikos Mavrogiannopoulos
8 : *
9 : * The GnuTLS is free software; you can redistribute it and/or
10 : * modify it under the terms of the GNU Lesser General Public License
11 : * as published by the Free Software Foundation; either version 2.1 of
12 : * the License, or (at your option) any later version.
13 : *
14 : * This library is distributed in the hope that it will be useful, but
15 : * WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : * Lesser General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU Lesser General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>
21 : */
22 :
23 : #include "gnutls_int.h"
24 : #include <gnutls/pkcs11.h>
25 : #include <stdio.h>
26 : #include <string.h>
27 : #include "errors.h"
28 : #include <datum.h>
29 : #include <pkcs11_int.h>
30 : #include <gnutls/abstract.h>
31 : #include <pk.h>
32 : #include <x509_int.h>
33 : #include <tls-sig.h>
34 : #include <algorithms.h>
35 : #include <fips.h>
36 : #include <system-keys.h>
37 : #include "urls.h"
38 : #include "pkcs11_int.h"
39 : #include <abstract_int.h>
40 :
41 : static int
42 : privkey_sign_prehashed(gnutls_privkey_t signer,
43 : const gnutls_sign_entry_st *se,
44 : const gnutls_datum_t * hash_data,
45 : gnutls_datum_t * signature,
46 : gnutls_x509_spki_st * params);
47 :
48 : /**
49 : * gnutls_privkey_get_type:
50 : * @key: should contain a #gnutls_privkey_t type
51 : *
52 : * This function will return the type of the private key. This is
53 : * actually the type of the subsystem used to set this private key.
54 : *
55 : * Returns: a member of the #gnutls_privkey_type_t enumeration on
56 : * success, or a negative error code on error.
57 : *
58 : * Since: 2.12.0
59 : **/
60 0 : gnutls_privkey_type_t gnutls_privkey_get_type(gnutls_privkey_t key)
61 : {
62 0 : return key->type;
63 : }
64 :
65 : /**
66 : * gnutls_privkey_get_seed:
67 : * @key: should contain a #gnutls_privkey_t type
68 : * @digest: if non-NULL it will contain the digest algorithm used for key generation (if applicable)
69 : * @seed: where seed will be copied to
70 : * @seed_size: originally holds the size of @seed, will be updated with actual size
71 : *
72 : * This function will return the seed that was used to generate the
73 : * given private key. That function will succeed only if the key was generated
74 : * as a provable key.
75 : *
76 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
77 : * negative error value.
78 : *
79 : * Since: 3.5.0
80 : **/
81 0 : int gnutls_privkey_get_seed(gnutls_privkey_t key, gnutls_digest_algorithm_t *digest, void *seed, size_t *seed_size)
82 : {
83 0 : if (key->type != GNUTLS_PRIVKEY_X509)
84 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
85 0 : return gnutls_x509_privkey_get_seed(key->key.x509, digest, seed, seed_size);
86 : }
87 :
88 : /**
89 : * gnutls_privkey_verify_seed:
90 : * @key: should contain a #gnutls_privkey_t type
91 : * @digest: it contains the digest algorithm used for key generation (if applicable)
92 : * @seed: the seed of the key to be checked with
93 : * @seed_size: holds the size of @seed
94 : *
95 : * This function will verify that the given private key was generated from
96 : * the provided seed.
97 : *
98 : * Returns: In case of a verification failure %GNUTLS_E_PRIVKEY_VERIFICATION_ERROR
99 : * is returned, and zero or positive code on success.
100 : *
101 : * Since: 3.5.0
102 : **/
103 13 : int gnutls_privkey_verify_seed(gnutls_privkey_t key, gnutls_digest_algorithm_t digest, const void *seed, size_t seed_size)
104 : {
105 13 : if (key->type != GNUTLS_PRIVKEY_X509)
106 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
107 13 : return gnutls_x509_privkey_verify_seed(key->key.x509, digest, seed, seed_size);
108 : }
109 :
110 : /**
111 : * gnutls_privkey_get_pk_algorithm:
112 : * @key: should contain a #gnutls_privkey_t type
113 : * @bits: If set will return the number of bits of the parameters (may be NULL)
114 : *
115 : * This function will return the public key algorithm of a private
116 : * key and if possible will return a number of bits that indicates
117 : * the security parameter of the key.
118 : *
119 : * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
120 : * success, or a negative error code on error.
121 : *
122 : * Since: 2.12.0
123 : **/
124 30965 : int gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key, unsigned int *bits)
125 : {
126 30965 : switch (key->type) {
127 : #ifdef ENABLE_PKCS11
128 320 : case GNUTLS_PRIVKEY_PKCS11:
129 320 : return gnutls_pkcs11_privkey_get_pk_algorithm(key->key.pkcs11,
130 : bits);
131 : #endif
132 30544 : case GNUTLS_PRIVKEY_X509:
133 30544 : if (bits) {
134 17718 : *bits = pubkey_to_bits(&key->key.x509->params);
135 : }
136 :
137 30544 : return gnutls_x509_privkey_get_pk_algorithm(key->key.x509);
138 101 : case GNUTLS_PRIVKEY_EXT:
139 101 : if (bits)
140 74 : *bits = key->key.ext.bits;
141 :
142 101 : return key->pk_algorithm;
143 0 : default:
144 0 : gnutls_assert();
145 : return GNUTLS_E_INVALID_REQUEST;
146 : }
147 :
148 : }
149 :
150 : static int
151 1404 : privkey_to_pubkey(gnutls_pk_algorithm_t pk,
152 : const gnutls_pk_params_st * priv, gnutls_pk_params_st * pub)
153 : {
154 1404 : int ret;
155 :
156 1404 : pub->algo = priv->algo;
157 1404 : pub->pkflags = priv->pkflags;
158 1404 : pub->curve = priv->curve;
159 1404 : pub->gost_params = priv->gost_params;
160 1404 : pub->qbits = priv->qbits;
161 1404 : memcpy(&pub->spki, &priv->spki, sizeof(gnutls_x509_spki_st));
162 :
163 1404 : switch (pk) {
164 424 : case GNUTLS_PK_RSA_PSS:
165 : case GNUTLS_PK_RSA:
166 424 : pub->params[0] = _gnutls_mpi_copy(priv->params[0]);
167 424 : pub->params[1] = _gnutls_mpi_copy(priv->params[1]);
168 :
169 424 : pub->params_nr = RSA_PUBLIC_PARAMS;
170 :
171 424 : if (pub->params[0] == NULL || pub->params[1] == NULL) {
172 0 : gnutls_assert();
173 0 : ret = GNUTLS_E_MEMORY_ERROR;
174 0 : goto cleanup;
175 : }
176 :
177 : break;
178 13 : case GNUTLS_PK_DSA:
179 13 : pub->params[0] = _gnutls_mpi_copy(priv->params[0]);
180 13 : pub->params[1] = _gnutls_mpi_copy(priv->params[1]);
181 13 : pub->params[2] = _gnutls_mpi_copy(priv->params[2]);
182 13 : pub->params[3] = _gnutls_mpi_copy(priv->params[3]);
183 :
184 13 : pub->params_nr = DSA_PUBLIC_PARAMS;
185 :
186 13 : if (pub->params[0] == NULL || pub->params[1] == NULL ||
187 13 : pub->params[2] == NULL || pub->params[3] == NULL) {
188 0 : gnutls_assert();
189 0 : ret = GNUTLS_E_MEMORY_ERROR;
190 0 : goto cleanup;
191 : }
192 :
193 : break;
194 429 : case GNUTLS_PK_ECDSA:
195 429 : pub->params[ECC_X] = _gnutls_mpi_copy(priv->params[ECC_X]);
196 429 : pub->params[ECC_Y] = _gnutls_mpi_copy(priv->params[ECC_Y]);
197 :
198 429 : pub->params_nr = ECC_PUBLIC_PARAMS;
199 :
200 429 : if (pub->params[ECC_X] == NULL || pub->params[ECC_Y] == NULL) {
201 0 : gnutls_assert();
202 0 : ret = GNUTLS_E_MEMORY_ERROR;
203 0 : goto cleanup;
204 : }
205 :
206 : break;
207 15 : case GNUTLS_PK_EDDSA_ED25519:
208 : case GNUTLS_PK_EDDSA_ED448:
209 15 : ret = _gnutls_set_datum(&pub->raw_pub, priv->raw_pub.data, priv->raw_pub.size);
210 15 : if (ret < 0)
211 0 : return gnutls_assert_val(ret);
212 :
213 : break;
214 523 : case GNUTLS_PK_GOST_01:
215 : case GNUTLS_PK_GOST_12_256:
216 : case GNUTLS_PK_GOST_12_512:
217 523 : pub->params[GOST_X] = _gnutls_mpi_copy(priv->params[GOST_X]);
218 523 : pub->params[GOST_Y] = _gnutls_mpi_copy(priv->params[GOST_Y]);
219 :
220 523 : pub->params_nr = GOST_PUBLIC_PARAMS;
221 :
222 523 : if (pub->params[GOST_X] == NULL || pub->params[GOST_Y] == NULL) {
223 0 : gnutls_assert();
224 0 : ret = GNUTLS_E_MEMORY_ERROR;
225 0 : goto cleanup;
226 : }
227 :
228 : break;
229 0 : default:
230 0 : gnutls_assert();
231 : return GNUTLS_E_INVALID_REQUEST;
232 : }
233 :
234 : return 0;
235 0 : cleanup:
236 0 : gnutls_pk_params_release(pub);
237 0 : return ret;
238 : }
239 :
240 : /* Returns the public key of the private key (if possible)
241 : */
242 : int
243 1427 : _gnutls_privkey_get_mpis(gnutls_privkey_t key, gnutls_pk_params_st * params)
244 : {
245 1427 : int ret;
246 :
247 1427 : switch (key->type) {
248 1398 : case GNUTLS_PRIVKEY_X509:
249 1398 : ret = _gnutls_pk_params_copy(params, &key->key.x509->params);
250 1398 : break;
251 : #ifdef ENABLE_PKCS11
252 26 : case GNUTLS_PRIVKEY_PKCS11: {
253 26 : gnutls_pubkey_t pubkey;
254 :
255 26 : ret = _pkcs11_privkey_get_pubkey(key->key.pkcs11, &pubkey, 0);
256 26 : if (ret < 0)
257 1 : return gnutls_assert_val(ret);
258 :
259 25 : ret = _gnutls_pubkey_get_mpis(pubkey, params);
260 25 : gnutls_pubkey_deinit(pubkey);
261 :
262 25 : break;
263 : }
264 : #endif
265 3 : default:
266 3 : gnutls_assert();
267 : return GNUTLS_E_INVALID_REQUEST;
268 : }
269 :
270 : return ret;
271 : }
272 :
273 : int
274 1407 : _gnutls_privkey_get_public_mpis(gnutls_privkey_t key,
275 : gnutls_pk_params_st * params)
276 : {
277 1407 : int ret;
278 1407 : gnutls_pk_params_st tmp1;
279 :
280 1407 : gnutls_pk_params_init(&tmp1);
281 :
282 1407 : ret = _gnutls_privkey_get_mpis(key, &tmp1);
283 1407 : if (ret < 0)
284 3 : return gnutls_assert_val(ret);
285 :
286 1404 : ret = privkey_to_pubkey(key->pk_algorithm, &tmp1, params);
287 :
288 1404 : gnutls_pk_params_release(&tmp1);
289 :
290 1404 : if (ret < 0)
291 0 : gnutls_assert();
292 :
293 : return ret;
294 : }
295 :
296 : /* This function retrieves default sign parameters from KEY. */
297 : int
298 16635 : _gnutls_privkey_get_spki_params(gnutls_privkey_t key,
299 : gnutls_x509_spki_st * params)
300 : {
301 16635 : switch (key->type) {
302 : #ifdef ENABLE_PKCS11
303 : case GNUTLS_PRIVKEY_PKCS11:
304 : break;
305 : #endif
306 : case GNUTLS_PRIVKEY_EXT:
307 : break;
308 16315 : case GNUTLS_PRIVKEY_X509:
309 16315 : _gnutls_x509_privkey_get_spki_params(key->key.x509, params);
310 16315 : return 0;
311 0 : default:
312 0 : gnutls_assert();
313 : return GNUTLS_E_INVALID_REQUEST;
314 : }
315 :
316 320 : memset(params, 0, sizeof(gnutls_x509_spki_st));
317 :
318 320 : return 0;
319 : }
320 :
321 : /* This function fills in PARAMS with the necessary parameters to sign
322 : * with PK and DIG. PARAMS must be initialized with
323 : * _gnutls_privkey_get_spki_params in advance.
324 : *
325 : * After calling this function the params structure will
326 : * be initialized even if the original SubjectPublicKeyInfo was empty.
327 : */
328 : int
329 16635 : _gnutls_privkey_update_spki_params(gnutls_privkey_t key,
330 : gnutls_pk_algorithm_t pk,
331 : gnutls_digest_algorithm_t dig,
332 : unsigned flags,
333 : gnutls_x509_spki_st *params)
334 : {
335 16635 : unsigned salt_size = 0;
336 16635 : unsigned bits = 0;
337 16635 : gnutls_pk_algorithm_t key_pk;
338 :
339 16635 : if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS) {
340 10 : if (!GNUTLS_PK_IS_RSA(pk))
341 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
342 : pk = GNUTLS_PK_RSA_PSS;
343 : }
344 :
345 16635 : key_pk = gnutls_privkey_get_pk_algorithm(key, &bits);
346 16635 : if ((key_pk != pk) &&
347 961 : !(key_pk == GNUTLS_PK_RSA && pk == GNUTLS_PK_RSA_PSS)) {
348 2 : gnutls_assert();
349 2 : return GNUTLS_E_CONSTRAINT_ERROR;
350 : }
351 :
352 16633 : if (pk == GNUTLS_PK_RSA_PSS) {
353 4261 : const mac_entry_st *me;
354 4261 : int ret;
355 :
356 4261 : me = hash_to_entry(dig);
357 4261 : if (unlikely(me == NULL))
358 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
359 :
360 4261 : if (params->pk == GNUTLS_PK_RSA)
361 : salt_size = 0;
362 4261 : else if (params->pk == GNUTLS_PK_RSA_PSS) {
363 43 : if (params->rsa_pss_dig != GNUTLS_DIG_UNKNOWN && dig != params->rsa_pss_dig) {
364 4 : return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
365 : }
366 :
367 39 : salt_size = params->salt_size;
368 : }
369 :
370 4257 : if (flags & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE)
371 0 : params->salt_size = 0;
372 : else {
373 4257 : ret = _gnutls_find_rsa_pss_salt_size(bits, me, salt_size);
374 4257 : if (ret < 0)
375 1 : return gnutls_assert_val(ret);
376 4256 : params->salt_size = ret;
377 : }
378 4256 : params->rsa_pss_dig = dig;
379 : }
380 :
381 16628 : params->pk = pk;
382 :
383 16628 : return 0;
384 : }
385 :
386 : /**
387 : * gnutls_privkey_init:
388 : * @key: A pointer to the type to be initialized
389 : *
390 : * This function will initialize a private key object. The object can
391 : * be used to generate, import, and perform cryptographic operations
392 : * on the associated private key.
393 : *
394 : * Note that when the underlying private key is a PKCS#11 key (i.e.,
395 : * when imported with a PKCS#11 URI), the limitations of gnutls_pkcs11_privkey_init()
396 : * apply to this object as well. In versions of GnuTLS later than 3.5.11 the object
397 : * is protected using locks and a single %gnutls_privkey_t can be re-used
398 : * by many threads. However, for performance it is recommended to utilize
399 : * one object per key per thread.
400 : *
401 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
402 : * negative error value.
403 : *
404 : * Since: 2.12.0
405 : **/
406 13052 : int gnutls_privkey_init(gnutls_privkey_t * key)
407 : {
408 13052 : FAIL_IF_LIB_ERROR;
409 :
410 13052 : *key = gnutls_calloc(1, sizeof(struct gnutls_privkey_st));
411 13052 : if (*key == NULL) {
412 0 : gnutls_assert();
413 0 : return GNUTLS_E_MEMORY_ERROR;
414 : }
415 :
416 : return 0;
417 : }
418 :
419 : /**
420 : * gnutls_privkey_deinit:
421 : * @key: The key to be deinitialized
422 : *
423 : * This function will deinitialize a private key structure.
424 : *
425 : * Since: 2.12.0
426 : **/
427 12568 : void gnutls_privkey_deinit(gnutls_privkey_t key)
428 : {
429 12568 : if (key == NULL)
430 : return;
431 :
432 12562 : if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
433 12562 : || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY)
434 12475 : switch (key->type) {
435 : #ifdef ENABLE_PKCS11
436 58 : case GNUTLS_PRIVKEY_PKCS11:
437 58 : gnutls_pkcs11_privkey_deinit(key->key.pkcs11);
438 58 : break;
439 : #endif
440 12379 : case GNUTLS_PRIVKEY_X509:
441 12379 : gnutls_x509_privkey_deinit(key->key.x509);
442 12379 : break;
443 38 : case GNUTLS_PRIVKEY_EXT:
444 38 : if (key->key.ext.deinit_func != NULL)
445 38 : key->key.ext.deinit_func(key,
446 : key->key.ext.userdata);
447 : break;
448 : default:
449 : break;
450 : }
451 12562 : gnutls_free(key);
452 : }
453 :
454 : /* Will erase all private key information, except PIN */
455 3 : void _gnutls_privkey_cleanup(gnutls_privkey_t key)
456 : {
457 3 : memset(&key->key, 0, sizeof(key->key));
458 3 : key->type = 0;
459 3 : key->pk_algorithm = 0;
460 3 : key->flags = 0;
461 3 : }
462 :
463 : /* will fail if the private key contains an actual key.
464 : */
465 11848 : static int check_if_clean(gnutls_privkey_t key)
466 : {
467 11848 : if (key->type != 0)
468 0 : return GNUTLS_E_INVALID_REQUEST;
469 :
470 : return 0;
471 : }
472 :
473 : #ifdef ENABLE_PKCS11
474 :
475 : /**
476 : * gnutls_privkey_import_pkcs11:
477 : * @pkey: The private key
478 : * @key: The private key to be imported
479 : * @flags: Flags for the import
480 : *
481 : * This function will import the given private key to the abstract
482 : * #gnutls_privkey_t type.
483 : *
484 : * The #gnutls_pkcs11_privkey_t object must not be deallocated
485 : * during the lifetime of this structure.
486 : *
487 : * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
488 : * and %GNUTLS_PRIVKEY_IMPORT_COPY.
489 : *
490 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
491 : * negative error value.
492 : *
493 : * Since: 2.12.0
494 : **/
495 : int
496 69 : gnutls_privkey_import_pkcs11(gnutls_privkey_t pkey,
497 : gnutls_pkcs11_privkey_t key, unsigned int flags)
498 : {
499 69 : int ret;
500 :
501 69 : ret = check_if_clean(pkey);
502 69 : if (ret < 0) {
503 0 : gnutls_assert();
504 0 : return ret;
505 : }
506 :
507 69 : if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
508 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
509 :
510 69 : pkey->key.pkcs11 = key;
511 69 : pkey->type = GNUTLS_PRIVKEY_PKCS11;
512 69 : pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm(key, NULL);
513 69 : pkey->flags = flags;
514 :
515 69 : if (pkey->pin.data)
516 1 : gnutls_pkcs11_privkey_set_pin_function(key, pkey->pin.cb,
517 : pkey->pin.data);
518 :
519 : return 0;
520 : }
521 :
522 : #if 0
523 : /**
524 : * gnutls_privkey_import_pkcs11_url:
525 : * @key: A key of type #gnutls_pubkey_t
526 : * @url: A PKCS 11 url
527 : *
528 : * This function will import a PKCS 11 private key to a #gnutls_private_key_t
529 : * type.
530 : *
531 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
532 : * negative error value.
533 : *
534 : * Since: 3.1.0
535 : **/
536 :
537 : int gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key, const char *url)
538 : {
539 : int x;
540 : }
541 : #endif
542 :
543 : static
544 71 : int _gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key, const char *url, unsigned flags)
545 : {
546 71 : gnutls_pkcs11_privkey_t pkey;
547 71 : int ret;
548 :
549 71 : ret = gnutls_pkcs11_privkey_init(&pkey);
550 71 : if (ret < 0) {
551 0 : gnutls_assert();
552 0 : return ret;
553 : }
554 :
555 71 : if (key->pin.cb)
556 12 : gnutls_pkcs11_privkey_set_pin_function(pkey, key->pin.cb,
557 : key->pin.data);
558 :
559 71 : ret = gnutls_pkcs11_privkey_import_url(pkey, url, flags);
560 71 : if (ret < 0) {
561 2 : gnutls_assert();
562 2 : goto cleanup;
563 : }
564 :
565 69 : ret =
566 69 : gnutls_privkey_import_pkcs11(key, pkey,
567 : GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
568 69 : if (ret < 0) {
569 0 : gnutls_assert();
570 0 : goto cleanup;
571 : }
572 :
573 : return 0;
574 :
575 2 : cleanup:
576 2 : gnutls_pkcs11_privkey_deinit(pkey);
577 :
578 2 : return ret;
579 : }
580 :
581 : /**
582 : * gnutls_privkey_export_pkcs11:
583 : * @pkey: The private key
584 : * @key: Location for the key to be exported.
585 : *
586 : * Converts the given abstract private key to a #gnutls_pkcs11_privkey_t
587 : * type. The key must be of type %GNUTLS_PRIVKEY_PKCS11. The key
588 : * returned in @key must be deinitialized with
589 : * gnutls_pkcs11_privkey_deinit().
590 : *
591 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
592 : * negative error value.
593 : *
594 : * Since: 3.4.0
595 : */
596 : int
597 0 : gnutls_privkey_export_pkcs11(gnutls_privkey_t pkey,
598 : gnutls_pkcs11_privkey_t *key)
599 : {
600 0 : int ret;
601 :
602 0 : if (pkey->type != GNUTLS_PRIVKEY_PKCS11) {
603 0 : gnutls_assert();
604 0 : return GNUTLS_E_INVALID_REQUEST;
605 : }
606 :
607 0 : ret = gnutls_pkcs11_privkey_init(key);
608 0 : if (ret < 0)
609 0 : return gnutls_assert_val(ret);
610 :
611 0 : ret = gnutls_pkcs11_privkey_cpy(*key, pkey->key.pkcs11);
612 0 : if (ret < 0) {
613 0 : gnutls_pkcs11_privkey_deinit(*key);
614 0 : *key = NULL;
615 :
616 0 : return gnutls_assert_val(ret);
617 : }
618 :
619 : return 0;
620 : }
621 : #endif /* ENABLE_PKCS11 */
622 :
623 : /**
624 : * gnutls_privkey_import_ext:
625 : * @pkey: The private key
626 : * @pk: The public key algorithm
627 : * @userdata: private data to be provided to the callbacks
628 : * @sign_func: callback for signature operations
629 : * @decrypt_func: callback for decryption operations
630 : * @flags: Flags for the import
631 : *
632 : * This function will associate the given callbacks with the
633 : * #gnutls_privkey_t type. At least one of the two callbacks
634 : * must be non-null.
635 : *
636 : * Note that the signing function is supposed to "raw" sign data, i.e.,
637 : * without any hashing or preprocessing. In case of RSA the DigestInfo
638 : * will be provided, and the signing function is expected to do the PKCS #1
639 : * 1.5 padding and the exponentiation.
640 : *
641 : * See also gnutls_privkey_import_ext3().
642 : *
643 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
644 : * negative error value.
645 : *
646 : * Since: 3.0
647 : **/
648 : int
649 0 : gnutls_privkey_import_ext(gnutls_privkey_t pkey,
650 : gnutls_pk_algorithm_t pk,
651 : void *userdata,
652 : gnutls_privkey_sign_func sign_func,
653 : gnutls_privkey_decrypt_func decrypt_func,
654 : unsigned int flags)
655 : {
656 0 : return gnutls_privkey_import_ext2(pkey, pk, userdata, sign_func,
657 : decrypt_func, NULL, flags);
658 : }
659 :
660 : #define PK_IS_OK_FOR_EXT2(pk) \
661 : ((pk == GNUTLS_PK_RSA) || (pk == GNUTLS_PK_ECDSA) || (pk == GNUTLS_PK_DSA))
662 :
663 : /**
664 : * gnutls_privkey_import_ext2:
665 : * @pkey: The private key
666 : * @pk: The public key algorithm
667 : * @userdata: private data to be provided to the callbacks
668 : * @sign_fn: callback for signature operations
669 : * @decrypt_fn: callback for decryption operations
670 : * @deinit_fn: a deinitialization function
671 : * @flags: Flags for the import
672 : *
673 : * This function will associate the given callbacks with the
674 : * #gnutls_privkey_t type. At least one of the two callbacks
675 : * must be non-null. If a deinitialization function is provided
676 : * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
677 : *
678 : * Note that the signing function is supposed to "raw" sign data, i.e.,
679 : * without any hashing or preprocessing. In case of RSA the DigestInfo
680 : * will be provided, and the signing function is expected to do the PKCS #1
681 : * 1.5 padding and the exponentiation.
682 : *
683 : * See also gnutls_privkey_import_ext3().
684 : *
685 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
686 : * negative error value.
687 : *
688 : * Since: 3.1
689 : **/
690 : int
691 17 : gnutls_privkey_import_ext2(gnutls_privkey_t pkey,
692 : gnutls_pk_algorithm_t pk,
693 : void *userdata,
694 : gnutls_privkey_sign_func sign_fn,
695 : gnutls_privkey_decrypt_func decrypt_fn,
696 : gnutls_privkey_deinit_func deinit_fn,
697 : unsigned int flags)
698 : {
699 17 : int ret;
700 :
701 17 : ret = check_if_clean(pkey);
702 17 : if (ret < 0) {
703 0 : gnutls_assert();
704 0 : return ret;
705 : }
706 :
707 17 : if (!PK_IS_OK_FOR_EXT2(pk))
708 3 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
709 :
710 14 : if (sign_fn == NULL && decrypt_fn == NULL)
711 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
712 :
713 14 : pkey->key.ext.sign_func = sign_fn;
714 14 : pkey->key.ext.decrypt_func = decrypt_fn;
715 14 : pkey->key.ext.deinit_func = deinit_fn;
716 14 : pkey->key.ext.userdata = userdata;
717 14 : pkey->type = GNUTLS_PRIVKEY_EXT;
718 14 : pkey->pk_algorithm = pk;
719 14 : pkey->flags = flags;
720 :
721 : /* Ensure gnutls_privkey_deinit() calls the deinit_func */
722 14 : if (deinit_fn)
723 14 : pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
724 :
725 : return 0;
726 : }
727 :
728 : /**
729 : * gnutls_privkey_import_ext3:
730 : * @pkey: The private key
731 : * @userdata: private data to be provided to the callbacks
732 : * @sign_fn: callback for signature operations
733 : * @decrypt_fn: callback for decryption operations
734 : * @deinit_fn: a deinitialization function
735 : * @info_fn: returns info about the public key algorithm (should not be %NULL)
736 : * @flags: Flags for the import
737 : *
738 : * This function will associate the given callbacks with the
739 : * #gnutls_privkey_t type. At least one of the two callbacks
740 : * must be non-null. If a deinitialization function is provided
741 : * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
742 : *
743 : * Note that the signing function is supposed to "raw" sign data, i.e.,
744 : * without any hashing or preprocessing. In case of RSA the DigestInfo
745 : * will be provided, and the signing function is expected to do the PKCS #1
746 : * 1.5 padding and the exponentiation.
747 : *
748 : * The @info_fn must provide information on the algorithms supported by
749 : * this private key, and should support the flags %GNUTLS_PRIVKEY_INFO_PK_ALGO and
750 : * %GNUTLS_PRIVKEY_INFO_SIGN_ALGO. It must return -1 on unknown flags.
751 : *
752 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
753 : * negative error value.
754 : *
755 : * Since: 3.4.0
756 : **/
757 : int
758 0 : gnutls_privkey_import_ext3(gnutls_privkey_t pkey,
759 : void *userdata,
760 : gnutls_privkey_sign_func sign_fn,
761 : gnutls_privkey_decrypt_func decrypt_fn,
762 : gnutls_privkey_deinit_func deinit_fn,
763 : gnutls_privkey_info_func info_fn,
764 : unsigned int flags)
765 : {
766 0 : int ret;
767 :
768 0 : ret = check_if_clean(pkey);
769 0 : if (ret < 0) {
770 0 : gnutls_assert();
771 0 : return ret;
772 : }
773 :
774 0 : if (sign_fn == NULL && decrypt_fn == NULL)
775 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
776 :
777 0 : if (info_fn == NULL)
778 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
779 :
780 0 : pkey->key.ext.sign_func = sign_fn;
781 0 : pkey->key.ext.decrypt_func = decrypt_fn;
782 0 : pkey->key.ext.deinit_func = deinit_fn;
783 0 : pkey->key.ext.info_func = info_fn;
784 0 : pkey->key.ext.userdata = userdata;
785 0 : pkey->type = GNUTLS_PRIVKEY_EXT;
786 0 : pkey->flags = flags;
787 :
788 0 : pkey->pk_algorithm = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata);
789 :
790 0 : if (!PK_IS_OK_FOR_EXT2(pkey->pk_algorithm))
791 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
792 :
793 : /* Ensure gnutls_privkey_deinit() calls the deinit_func */
794 0 : if (deinit_fn)
795 0 : pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
796 :
797 : return 0;
798 : }
799 :
800 : /**
801 : * gnutls_privkey_import_ext4:
802 : * @pkey: The private key
803 : * @userdata: private data to be provided to the callbacks
804 : * @sign_data_fn: callback for signature operations (may be %NULL)
805 : * @sign_hash_fn: callback for signature operations (may be %NULL)
806 : * @decrypt_fn: callback for decryption operations (may be %NULL)
807 : * @deinit_fn: a deinitialization function
808 : * @info_fn: returns info about the public key algorithm (should not be %NULL)
809 : * @flags: Flags for the import
810 : *
811 : * This function will associate the given callbacks with the
812 : * #gnutls_privkey_t type. At least one of the callbacks
813 : * must be non-null. If a deinitialization function is provided
814 : * then flags is assumed to contain %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE.
815 : *
816 : * Note that in contrast with the signing function of
817 : * gnutls_privkey_import_ext3(), the signing functions provided to this
818 : * function take explicitly the signature algorithm as parameter and
819 : * different functions are provided to sign the data and hashes.
820 : *
821 : * The @sign_hash_fn is to be called to sign pre-hashed data. The input
822 : * to the callback is the output of the hash (such as SHA256) corresponding
823 : * to the signature algorithm. For RSA PKCS#1 signatures, the signature
824 : * algorithm can be set to %GNUTLS_SIGN_RSA_RAW, and in that case the data
825 : * should be handled as if they were an RSA PKCS#1 DigestInfo structure.
826 : *
827 : * The @sign_data_fn is to be called to sign data. The input data will be
828 : * he data to be signed (and hashed), with the provided signature
829 : * algorithm. This function is to be used for signature algorithms like
830 : * Ed25519 which cannot take pre-hashed data as input.
831 : *
832 : * When both @sign_data_fn and @sign_hash_fn functions are provided they
833 : * must be able to operate on all the supported signature algorithms,
834 : * unless prohibited by the type of the algorithm (e.g., as with Ed25519).
835 : *
836 : * The @info_fn must provide information on the signature algorithms supported by
837 : * this private key, and should support the flags %GNUTLS_PRIVKEY_INFO_PK_ALGO,
838 : * %GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO and %GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS.
839 : * It must return -1 on unknown flags.
840 : *
841 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
842 : * negative error value.
843 : *
844 : * Since: 3.6.0
845 : **/
846 : int
847 24 : gnutls_privkey_import_ext4(gnutls_privkey_t pkey,
848 : void *userdata,
849 : gnutls_privkey_sign_data_func sign_data_fn,
850 : gnutls_privkey_sign_hash_func sign_hash_fn,
851 : gnutls_privkey_decrypt_func decrypt_fn,
852 : gnutls_privkey_deinit_func deinit_fn,
853 : gnutls_privkey_info_func info_fn,
854 : unsigned int flags)
855 : {
856 24 : int ret;
857 :
858 24 : ret = check_if_clean(pkey);
859 24 : if (ret < 0) {
860 0 : gnutls_assert();
861 0 : return ret;
862 : }
863 :
864 24 : if (sign_data_fn == NULL && sign_hash_fn == NULL && decrypt_fn == NULL)
865 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
866 :
867 24 : if (info_fn == NULL)
868 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
869 :
870 24 : pkey->key.ext.sign_data_func = sign_data_fn;
871 24 : pkey->key.ext.sign_hash_func = sign_hash_fn;
872 24 : pkey->key.ext.decrypt_func = decrypt_fn;
873 24 : pkey->key.ext.deinit_func = deinit_fn;
874 24 : pkey->key.ext.info_func = info_fn;
875 24 : pkey->key.ext.userdata = userdata;
876 24 : pkey->type = GNUTLS_PRIVKEY_EXT;
877 24 : pkey->flags = flags;
878 :
879 24 : pkey->pk_algorithm = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata);
880 :
881 24 : ret = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS, pkey->key.ext.userdata);
882 24 : if (ret >= 0)
883 24 : pkey->key.ext.bits = ret;
884 :
885 : /* Ensure gnutls_privkey_deinit() calls the deinit_func */
886 24 : if (deinit_fn)
887 24 : pkey->flags |= GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
888 :
889 : return 0;
890 : }
891 :
892 : /**
893 : * gnutls_privkey_import_x509:
894 : * @pkey: The private key
895 : * @key: The private key to be imported
896 : * @flags: Flags for the import
897 : *
898 : * This function will import the given private key to the abstract
899 : * #gnutls_privkey_t type.
900 : *
901 : * The #gnutls_x509_privkey_t object must not be deallocated
902 : * during the lifetime of this structure.
903 : *
904 : * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
905 : * and %GNUTLS_PRIVKEY_IMPORT_COPY.
906 : *
907 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
908 : * negative error value.
909 : *
910 : * Since: 2.12.0
911 : **/
912 : int
913 11738 : gnutls_privkey_import_x509(gnutls_privkey_t pkey,
914 : gnutls_x509_privkey_t key, unsigned int flags)
915 : {
916 11738 : int ret;
917 :
918 11738 : ret = check_if_clean(pkey);
919 11738 : if (ret < 0) {
920 0 : gnutls_assert();
921 0 : return ret;
922 : }
923 :
924 11738 : if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) {
925 33 : ret = gnutls_x509_privkey_init(&pkey->key.x509);
926 33 : if (ret < 0)
927 0 : return gnutls_assert_val(ret);
928 :
929 33 : ret = gnutls_x509_privkey_cpy(pkey->key.x509, key);
930 33 : if (ret < 0) {
931 0 : gnutls_x509_privkey_deinit(pkey->key.x509);
932 0 : return gnutls_assert_val(ret);
933 : }
934 : } else
935 11705 : pkey->key.x509 = key;
936 :
937 11738 : pkey->type = GNUTLS_PRIVKEY_X509;
938 11738 : pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm(key);
939 11738 : pkey->flags = flags;
940 :
941 11738 : return 0;
942 : }
943 :
944 : /**
945 : * gnutls_privkey_export_x509:
946 : * @pkey: The private key
947 : * @key: Location for the key to be exported.
948 : *
949 : * Converts the given abstract private key to a #gnutls_x509_privkey_t
950 : * type. The abstract key must be of type %GNUTLS_PRIVKEY_X509. The input
951 : * @key must not be initialized. The key returned in @key should be deinitialized
952 : * using gnutls_x509_privkey_deinit().
953 : *
954 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
955 : * negative error value.
956 : *
957 : * Since: 3.4.0
958 : */
959 : int
960 7 : gnutls_privkey_export_x509(gnutls_privkey_t pkey,
961 : gnutls_x509_privkey_t *key)
962 : {
963 7 : int ret;
964 :
965 7 : if (pkey->type != GNUTLS_PRIVKEY_X509) {
966 0 : gnutls_assert();
967 0 : return GNUTLS_E_INVALID_REQUEST;
968 : }
969 :
970 7 : ret = gnutls_x509_privkey_init(key);
971 7 : if (ret < 0)
972 0 : return gnutls_assert_val(ret);
973 :
974 7 : ret = gnutls_x509_privkey_cpy(*key, pkey->key.x509);
975 7 : if (ret < 0) {
976 0 : gnutls_x509_privkey_deinit(*key);
977 0 : *key = NULL;
978 :
979 0 : return gnutls_assert_val(ret);
980 : }
981 :
982 : return 0;
983 : }
984 :
985 : /**
986 : * gnutls_privkey_generate:
987 : * @pkey: An initialized private key
988 : * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
989 : * @bits: the size of the parameters to generate
990 : * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
991 : *
992 : * This function will generate a random private key. Note that this
993 : * function must be called on an initialized private key.
994 : *
995 : * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
996 : * instructs the key generation process to use algorithms like Shawe-Taylor
997 : * (from FIPS PUB186-4) which generate provable parameters out of a seed
998 : * for RSA and DSA keys. See gnutls_privkey_generate2() for more
999 : * information.
1000 : *
1001 : * Note that when generating an elliptic curve key, the curve
1002 : * can be substituted in the place of the bits parameter using the
1003 : * GNUTLS_CURVE_TO_BITS() macro. The input to the macro is any curve from
1004 : * %gnutls_ecc_curve_t.
1005 : *
1006 : * For DSA keys, if the subgroup size needs to be specified check
1007 : * the GNUTLS_SUBGROUP_TO_BITS() macro.
1008 : *
1009 : * It is recommended to do not set the number of @bits directly, use gnutls_sec_param_to_pk_bits() instead .
1010 : *
1011 : * See also gnutls_privkey_generate2().
1012 : *
1013 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1014 : * negative error value.
1015 : *
1016 : * Since: 3.3.0
1017 : **/
1018 : int
1019 1201 : gnutls_privkey_generate(gnutls_privkey_t pkey,
1020 : gnutls_pk_algorithm_t algo, unsigned int bits,
1021 : unsigned int flags)
1022 : {
1023 1201 : return gnutls_privkey_generate2(pkey, algo, bits, flags, NULL, 0);
1024 : }
1025 :
1026 : /**
1027 : * gnutls_privkey_generate2:
1028 : * @pkey: The private key
1029 : * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
1030 : * @bits: the size of the modulus
1031 : * @flags: Must be zero or flags from #gnutls_privkey_flags_t.
1032 : * @data: Allow specifying %gnutls_keygen_data_st types such as the seed to be used.
1033 : * @data_size: The number of @data available.
1034 : *
1035 : * This function will generate a random private key. Note that this
1036 : * function must be called on an initialized private key.
1037 : *
1038 : * The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE
1039 : * instructs the key generation process to use algorithms like Shawe-Taylor
1040 : * (from FIPS PUB186-4) which generate provable parameters out of a seed
1041 : * for RSA and DSA keys. On DSA keys the PQG parameters are generated using the
1042 : * seed, while on RSA the two primes. To specify an explicit seed
1043 : * (by default a random seed is used), use the @data with a %GNUTLS_KEYGEN_SEED
1044 : * type.
1045 : *
1046 : * Note that when generating an elliptic curve key, the curve
1047 : * can be substituted in the place of the bits parameter using the
1048 : * GNUTLS_CURVE_TO_BITS() macro.
1049 : *
1050 : * To export the generated keys in memory or in files it is recommended to use the
1051 : * PKCS#8 form as it can handle all key types, and can store additional parameters
1052 : * such as the seed, in case of provable RSA or DSA keys.
1053 : * Generated keys can be exported in memory using gnutls_privkey_export_x509(),
1054 : * and then with gnutls_x509_privkey_export2_pkcs8().
1055 : *
1056 : * If key generation is part of your application, avoid setting the number
1057 : * of bits directly, and instead use gnutls_sec_param_to_pk_bits().
1058 : * That way the generated keys will adapt to the security levels
1059 : * of the underlying GnuTLS library.
1060 : *
1061 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1062 : * negative error value.
1063 : *
1064 : * Since: 3.5.0
1065 : **/
1066 : int
1067 1201 : gnutls_privkey_generate2(gnutls_privkey_t pkey,
1068 : gnutls_pk_algorithm_t algo, unsigned int bits,
1069 : unsigned int flags, const gnutls_keygen_data_st *data, unsigned data_size)
1070 : {
1071 1201 : int ret;
1072 :
1073 1201 : ret = gnutls_x509_privkey_init(&pkey->key.x509);
1074 1201 : if (ret < 0)
1075 0 : return gnutls_assert_val(ret);
1076 :
1077 1201 : ret = gnutls_x509_privkey_generate2(pkey->key.x509, algo, bits, flags, data, data_size);
1078 1201 : if (ret < 0) {
1079 0 : gnutls_x509_privkey_deinit(pkey->key.x509);
1080 0 : pkey->key.x509 = NULL;
1081 0 : return gnutls_assert_val(ret);
1082 : }
1083 :
1084 1201 : pkey->type = GNUTLS_PRIVKEY_X509;
1085 1201 : pkey->pk_algorithm = algo;
1086 1201 : pkey->flags = flags | GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
1087 :
1088 1201 : return 0;
1089 : }
1090 :
1091 : /**
1092 : * gnutls_privkey_sign_data:
1093 : * @signer: Holds the key
1094 : * @hash: should be a digest algorithm
1095 : * @flags: Zero or one of %gnutls_privkey_flags_t
1096 : * @data: holds the data to be signed
1097 : * @signature: will contain the signature allocated with gnutls_malloc()
1098 : *
1099 : * This function will sign the given data using a signature algorithm
1100 : * supported by the private key. Signature algorithms are always used
1101 : * together with a hash functions. Different hash functions may be
1102 : * used for the RSA algorithm, but only the SHA family for the DSA keys.
1103 : *
1104 : * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
1105 : * the hash algorithm.
1106 : *
1107 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1108 : * negative error value.
1109 : *
1110 : * Since: 2.12.0
1111 : **/
1112 : int
1113 237 : gnutls_privkey_sign_data(gnutls_privkey_t signer,
1114 : gnutls_digest_algorithm_t hash,
1115 : unsigned int flags,
1116 : const gnutls_datum_t * data,
1117 : gnutls_datum_t * signature)
1118 : {
1119 237 : int ret;
1120 237 : gnutls_x509_spki_st params;
1121 :
1122 237 : if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
1123 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1124 :
1125 237 : ret = _gnutls_privkey_get_spki_params(signer, ¶ms);
1126 237 : if (ret < 0) {
1127 0 : gnutls_assert();
1128 0 : return ret;
1129 : }
1130 :
1131 237 : ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm,
1132 : hash, flags, ¶ms);
1133 237 : if (ret < 0) {
1134 0 : gnutls_assert();
1135 0 : return ret;
1136 : }
1137 :
1138 237 : FIX_SIGN_PARAMS(params, flags, hash);
1139 :
1140 237 : return privkey_sign_and_hash_data(signer, _gnutls_pk_to_sign_entry(params.pk, hash), data, signature, ¶ms);
1141 : }
1142 :
1143 : /**
1144 : * gnutls_privkey_sign_data2:
1145 : * @signer: Holds the key
1146 : * @algo: The signature algorithm used
1147 : * @flags: Zero or one of %gnutls_privkey_flags_t
1148 : * @data: holds the data to be signed
1149 : * @signature: will contain the signature allocated with gnutls_malloc()
1150 : *
1151 : * This function will sign the given data using the specified signature
1152 : * algorithm. This function is an enhancement of gnutls_privkey_sign_data(),
1153 : * as it allows utilizing a alternative signature algorithm where possible
1154 : * (e.g, use an RSA key with RSA-PSS).
1155 : *
1156 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1157 : * negative error value.
1158 : *
1159 : * Since: 3.6.0
1160 : **/
1161 : int
1162 17341 : gnutls_privkey_sign_data2(gnutls_privkey_t signer,
1163 : gnutls_sign_algorithm_t algo,
1164 : unsigned int flags,
1165 : const gnutls_datum_t * data,
1166 : gnutls_datum_t * signature)
1167 : {
1168 17341 : int ret;
1169 17341 : gnutls_x509_spki_st params;
1170 17341 : const gnutls_sign_entry_st *se;
1171 :
1172 17341 : if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
1173 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1174 :
1175 17341 : se = _gnutls_sign_to_entry(algo);
1176 17341 : if (se == NULL)
1177 4071 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1178 :
1179 13270 : ret = _gnutls_privkey_get_spki_params(signer, ¶ms);
1180 13270 : if (ret < 0) {
1181 0 : gnutls_assert();
1182 0 : return ret;
1183 : }
1184 :
1185 13270 : ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash,
1186 : flags, ¶ms);
1187 13270 : if (ret < 0) {
1188 7 : gnutls_assert();
1189 7 : return ret;
1190 : }
1191 :
1192 13263 : FIX_SIGN_PARAMS(params, flags, se->hash);
1193 :
1194 13263 : return privkey_sign_and_hash_data(signer, se, data, signature, ¶ms);
1195 : }
1196 :
1197 : /**
1198 : * gnutls_privkey_sign_hash2:
1199 : * @signer: Holds the signer's key
1200 : * @algo: The signature algorithm used
1201 : * @flags: Zero or one of %gnutls_privkey_flags_t
1202 : * @hash_data: holds the data to be signed
1203 : * @signature: will contain newly allocated signature
1204 : *
1205 : * This function will sign the given hashed data using the specified signature
1206 : * algorithm. This function is an enhancement of gnutls_privkey_sign_hash(),
1207 : * as it allows utilizing a alternative signature algorithm where possible
1208 : * (e.g, use an RSA key with RSA-PSS).
1209 : *
1210 : * The flags may be %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA.
1211 : * In that case this function will ignore @hash_algo and perform a raw PKCS1 signature.
1212 : * Note that this flag is supported since 3.6.9.
1213 : *
1214 : * Note also that, not all algorithm support signing already hashed data. When
1215 : * signing with Ed25519, gnutls_privkey_sign_data2() should be used instead.
1216 : *
1217 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1218 : * negative error value.
1219 : *
1220 : * Since: 3.6.0
1221 : **/
1222 : int
1223 30 : gnutls_privkey_sign_hash2(gnutls_privkey_t signer,
1224 : gnutls_sign_algorithm_t algo,
1225 : unsigned int flags,
1226 : const gnutls_datum_t * hash_data,
1227 : gnutls_datum_t * signature)
1228 : {
1229 30 : int ret;
1230 30 : gnutls_x509_spki_st params;
1231 30 : const gnutls_sign_entry_st *se;
1232 :
1233 30 : if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA) {
1234 : /* the corresponding signature algorithm is SIGN_RSA_RAW,
1235 : * irrespective of hash algorithm. */
1236 1 : se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
1237 : } else {
1238 29 : se = _gnutls_sign_to_entry(algo);
1239 29 : if (unlikely(se == NULL))
1240 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1241 :
1242 : }
1243 :
1244 30 : ret = _gnutls_privkey_get_spki_params(signer, ¶ms);
1245 30 : if (ret < 0) {
1246 0 : gnutls_assert();
1247 0 : return ret;
1248 : }
1249 :
1250 30 : ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash,
1251 : flags, ¶ms);
1252 30 : if (ret < 0) {
1253 0 : gnutls_assert();
1254 0 : return ret;
1255 : }
1256 :
1257 30 : FIX_SIGN_PARAMS(params, flags, se->hash);
1258 :
1259 30 : return privkey_sign_prehashed(signer, se, hash_data, signature, ¶ms);
1260 : }
1261 :
1262 : int
1263 13621 : privkey_sign_and_hash_data(gnutls_privkey_t signer,
1264 : const gnutls_sign_entry_st *se,
1265 : const gnutls_datum_t * data,
1266 : gnutls_datum_t * signature,
1267 : gnutls_x509_spki_st * params)
1268 : {
1269 13621 : int ret;
1270 13621 : gnutls_datum_t digest;
1271 13621 : const mac_entry_st *me;
1272 :
1273 13621 : if (unlikely(se == NULL))
1274 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1275 :
1276 13621 : if (_gnutls_pk_is_not_prehashed(se->pk)) {
1277 55 : return privkey_sign_raw_data(signer, se, data, signature, params);
1278 : }
1279 :
1280 13566 : me = hash_to_entry(se->hash);
1281 13566 : if (me == NULL)
1282 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1283 :
1284 13566 : ret = pk_hash_data(se->pk, me, NULL, data, &digest);
1285 13566 : if (ret < 0) {
1286 0 : gnutls_assert();
1287 0 : return ret;
1288 : }
1289 :
1290 13566 : ret = pk_prepare_hash(se->pk, me, &digest);
1291 13566 : if (ret < 0) {
1292 0 : gnutls_assert();
1293 0 : goto cleanup;
1294 : }
1295 :
1296 13566 : ret = privkey_sign_raw_data(signer, se, &digest, signature, params);
1297 13566 : _gnutls_free_datum(&digest);
1298 :
1299 13566 : if (ret < 0) {
1300 2 : gnutls_assert();
1301 2 : return ret;
1302 : }
1303 :
1304 : return 0;
1305 :
1306 0 : cleanup:
1307 0 : _gnutls_free_datum(&digest);
1308 0 : return ret;
1309 : }
1310 :
1311 :
1312 : /**
1313 : * gnutls_privkey_sign_hash:
1314 : * @signer: Holds the signer's key
1315 : * @hash_algo: The hash algorithm used
1316 : * @flags: Zero or one of %gnutls_privkey_flags_t
1317 : * @hash_data: holds the data to be signed
1318 : * @signature: will contain newly allocated signature
1319 : *
1320 : * This function will sign the given hashed data using a signature algorithm
1321 : * supported by the private key. Signature algorithms are always used
1322 : * together with a hash functions. Different hash functions may be
1323 : * used for the RSA algorithm, but only SHA-XXX for the DSA keys.
1324 : *
1325 : * You may use gnutls_pubkey_get_preferred_hash_algorithm() to determine
1326 : * the hash algorithm.
1327 : *
1328 : * The flags may be %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA or %GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS.
1329 : * In the former case this function will ignore @hash_algo and perform a raw PKCS1 signature,
1330 : * and in the latter an RSA-PSS signature will be generated.
1331 : *
1332 : * Note that, not all algorithm support signing already hashed data. When
1333 : * signing with Ed25519, gnutls_privkey_sign_data() should be used.
1334 : *
1335 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1336 : * negative error value.
1337 : *
1338 : * Since: 2.12.0
1339 : **/
1340 : int
1341 2976 : gnutls_privkey_sign_hash(gnutls_privkey_t signer,
1342 : gnutls_digest_algorithm_t hash_algo,
1343 : unsigned int flags,
1344 : const gnutls_datum_t * hash_data,
1345 : gnutls_datum_t * signature)
1346 : {
1347 2976 : int ret;
1348 2976 : gnutls_x509_spki_st params;
1349 2976 : const gnutls_sign_entry_st *se;
1350 :
1351 2976 : ret = _gnutls_privkey_get_spki_params(signer, ¶ms);
1352 2976 : if (ret < 0) {
1353 0 : gnutls_assert();
1354 0 : return ret;
1355 : }
1356 :
1357 2976 : ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm,
1358 : hash_algo, flags, ¶ms);
1359 2976 : if (ret < 0) {
1360 0 : gnutls_assert();
1361 0 : return ret;
1362 : }
1363 :
1364 : /* legacy callers of this API could use a hash algorithm of 0 (unknown)
1365 : * to indicate raw hashing. As we now always want to know the signing
1366 : * algorithm involved, we try discovering the hash algorithm. */
1367 2976 : if (hash_algo == 0 && (params.pk == GNUTLS_PK_DSA || params.pk == GNUTLS_PK_ECDSA)) {
1368 10 : hash_algo = _gnutls_hash_size_to_sha_hash(hash_data->size);
1369 : }
1370 :
1371 2976 : if (params.pk == GNUTLS_PK_RSA && (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)) {
1372 : /* the corresponding signature algorithm is SIGN_RSA_RAW,
1373 : * irrespective of hash algorithm. */
1374 1641 : se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
1375 : } else {
1376 1335 : se = _gnutls_pk_to_sign_entry(params.pk, hash_algo);
1377 : }
1378 :
1379 2976 : if (unlikely(se == NULL))
1380 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1381 :
1382 2976 : FIX_SIGN_PARAMS(params, flags, hash_algo);
1383 :
1384 2976 : return privkey_sign_prehashed(signer, se,
1385 : hash_data, signature, ¶ms);
1386 : }
1387 :
1388 : static int
1389 3006 : privkey_sign_prehashed(gnutls_privkey_t signer,
1390 : const gnutls_sign_entry_st *se,
1391 : const gnutls_datum_t * hash_data,
1392 : gnutls_datum_t * signature,
1393 : gnutls_x509_spki_st * params)
1394 : {
1395 3006 : int ret;
1396 3006 : gnutls_datum_t digest;
1397 :
1398 3006 : if (unlikely(se == NULL))
1399 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1400 :
1401 3006 : if (se->id == GNUTLS_SIGN_RSA_RAW) {
1402 1642 : return privkey_sign_raw_data(signer,
1403 : se,
1404 : hash_data, signature,
1405 : params);
1406 : }
1407 :
1408 1364 : if (_gnutls_pk_is_not_prehashed(signer->pk_algorithm)) {
1409 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1410 : }
1411 :
1412 1364 : digest.data = gnutls_malloc(hash_data->size);
1413 1364 : if (digest.data == NULL) {
1414 0 : gnutls_assert();
1415 0 : return GNUTLS_E_MEMORY_ERROR;
1416 : }
1417 1364 : digest.size = hash_data->size;
1418 1364 : memcpy(digest.data, hash_data->data, digest.size);
1419 :
1420 1364 : ret = pk_prepare_hash(se->pk, hash_to_entry(se->hash), &digest);
1421 1364 : if (ret < 0) {
1422 0 : gnutls_assert();
1423 0 : goto cleanup;
1424 : }
1425 :
1426 1364 : ret = privkey_sign_raw_data(signer,
1427 : se,
1428 : &digest, signature,
1429 : params);
1430 1364 : if (ret < 0) {
1431 2 : gnutls_assert();
1432 2 : goto cleanup;
1433 : }
1434 :
1435 : ret = 0;
1436 :
1437 1364 : cleanup:
1438 1364 : _gnutls_free_datum(&digest);
1439 1364 : return ret;
1440 : }
1441 :
1442 : /*-
1443 : * privkey_sign_raw_data:
1444 : * @key: Holds the key
1445 : * @data: holds the data to be signed
1446 : * @signature: will contain the signature allocated with gnutls_malloc()
1447 : * @params: holds the signing parameters
1448 : *
1449 : * This function will sign the given data using a signature algorithm
1450 : * supported by the private key. Note that this is a low-level function
1451 : * and does not apply any preprocessing or hash on the signed data.
1452 : * For example on an RSA key the input @data should be of the DigestInfo
1453 : * PKCS #1 1.5 format, on RSA-PSS, DSA or ECDSA the input should be a hash output
1454 : * and on Ed25519 the raw data to be signed.
1455 : *
1456 : * Note this function is equivalent to using the %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA
1457 : * flag with gnutls_privkey_sign_hash().
1458 : *
1459 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1460 : * negative error value.
1461 : *
1462 : * Since: 3.1.10
1463 : -*/
1464 : int
1465 16628 : privkey_sign_raw_data(gnutls_privkey_t key,
1466 : const gnutls_sign_entry_st *se,
1467 : const gnutls_datum_t * data,
1468 : gnutls_datum_t * signature,
1469 : gnutls_x509_spki_st * params)
1470 : {
1471 16628 : if (unlikely(se == NULL))
1472 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1473 :
1474 16628 : switch (key->type) {
1475 : #ifdef ENABLE_PKCS11
1476 249 : case GNUTLS_PRIVKEY_PKCS11:
1477 249 : return _gnutls_pkcs11_privkey_sign(key->key.pkcs11, se,
1478 : data, signature,
1479 : params);
1480 : #endif
1481 16309 : case GNUTLS_PRIVKEY_X509:
1482 16309 : return _gnutls_pk_sign(se->pk, signature, data,
1483 : &key->key.x509->params, params);
1484 70 : case GNUTLS_PRIVKEY_EXT:
1485 70 : if (unlikely(key->key.ext.sign_data_func == NULL &&
1486 : key->key.ext.sign_hash_func == NULL &&
1487 : key->key.ext.sign_func == NULL))
1488 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1489 :
1490 70 : if (_gnutls_pk_is_not_prehashed(se->pk)) {
1491 3 : if (!key->key.ext.sign_data_func)
1492 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1493 :
1494 3 : return key->key.ext.sign_data_func(key, se->id,
1495 : key->key.ext.userdata,
1496 : 0,
1497 : data, signature);
1498 67 : } else if (key->key.ext.sign_hash_func) {
1499 39 : if (se->pk == GNUTLS_PK_RSA) {
1500 15 : se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
1501 15 : assert(se != NULL);
1502 : }
1503 :
1504 : /* se may not be set here if we are doing legacy RSA */
1505 39 : return key->key.ext.sign_hash_func(key, se->id,
1506 : key->key.ext.userdata,
1507 : 0,
1508 : data, signature);
1509 : } else {
1510 28 : if (!PK_IS_OK_FOR_EXT2(se->pk))
1511 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1512 :
1513 28 : return key->key.ext.sign_func(key, key->key.ext.userdata,
1514 : data, signature);
1515 : }
1516 0 : default:
1517 0 : gnutls_assert();
1518 : return GNUTLS_E_INVALID_REQUEST;
1519 : }
1520 : }
1521 :
1522 : /**
1523 : * gnutls_privkey_decrypt_data:
1524 : * @key: Holds the key
1525 : * @flags: zero for now
1526 : * @ciphertext: holds the data to be decrypted
1527 : * @plaintext: will contain the decrypted data, allocated with gnutls_malloc()
1528 : *
1529 : * This function will decrypt the given data using the algorithm
1530 : * supported by the private key.
1531 : *
1532 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1533 : * negative error value.
1534 : *
1535 : * Since: 2.12.0
1536 : **/
1537 : int
1538 29 : gnutls_privkey_decrypt_data(gnutls_privkey_t key,
1539 : unsigned int flags,
1540 : const gnutls_datum_t * ciphertext,
1541 : gnutls_datum_t * plaintext)
1542 : {
1543 29 : switch (key->type) {
1544 29 : case GNUTLS_PRIVKEY_X509:
1545 29 : return _gnutls_pk_decrypt(key->pk_algorithm, plaintext,
1546 : ciphertext, &key->key.x509->params);
1547 : #ifdef ENABLE_PKCS11
1548 0 : case GNUTLS_PRIVKEY_PKCS11:
1549 0 : return _gnutls_pkcs11_privkey_decrypt_data(key->key.pkcs11,
1550 : flags,
1551 : ciphertext,
1552 : plaintext);
1553 : #endif
1554 0 : case GNUTLS_PRIVKEY_EXT:
1555 0 : if (key->key.ext.decrypt_func == NULL)
1556 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1557 :
1558 0 : return key->key.ext.decrypt_func(key,
1559 : key->key.ext.userdata,
1560 : ciphertext, plaintext);
1561 0 : default:
1562 0 : gnutls_assert();
1563 : return GNUTLS_E_INVALID_REQUEST;
1564 : }
1565 : }
1566 :
1567 : /**
1568 : * gnutls_privkey_decrypt_data2:
1569 : * @key: Holds the key
1570 : * @flags: zero for now
1571 : * @ciphertext: holds the data to be decrypted
1572 : * @plaintext: a preallocated buffer that will be filled with the plaintext
1573 : * @plaintext_size: in/out size of the plaintext
1574 : *
1575 : * This function will decrypt the given data using the algorithm
1576 : * supported by the private key. Unlike with gnutls_privkey_decrypt_data()
1577 : * this function operates in constant time and constant memory access.
1578 : *
1579 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1580 : * negative error value.
1581 : *
1582 : * Since: 3.6.5
1583 : **/
1584 :
1585 : int
1586 1859 : gnutls_privkey_decrypt_data2(gnutls_privkey_t key,
1587 : unsigned int flags,
1588 : const gnutls_datum_t * ciphertext,
1589 : unsigned char * plaintext,
1590 : size_t plaintext_size)
1591 : {
1592 : /* Note: except for the backwards compatibility function, no
1593 : * conditional code should be called after the decryption
1594 : * function call, to avoid creating oracle attacks based
1595 : * on cache/timing side channels */
1596 :
1597 : /* backwards compatibility */
1598 1859 : if (key->type == GNUTLS_PRIVKEY_EXT &&
1599 2 : key->key.ext.decrypt_func2 == NULL &&
1600 2 : key->key.ext.decrypt_func != NULL) {
1601 2 : gnutls_datum_t plain;
1602 2 : int ret;
1603 2 : ret = key->key.ext.decrypt_func(key,
1604 : key->key.ext.userdata,
1605 : ciphertext,
1606 : &plain);
1607 2 : if (plain.size != plaintext_size) {
1608 0 : ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1609 : } else {
1610 2 : memcpy(plaintext, plain.data, plain.size);
1611 : }
1612 2 : gnutls_free(plain.data);
1613 2 : return ret;
1614 : }
1615 :
1616 1857 : switch (key->type) {
1617 1855 : case GNUTLS_PRIVKEY_X509:
1618 1855 : return _gnutls_pk_decrypt2(key->pk_algorithm, ciphertext,
1619 : plaintext, plaintext_size,
1620 : &key->key.x509->params);
1621 : #ifdef ENABLE_PKCS11
1622 2 : case GNUTLS_PRIVKEY_PKCS11:
1623 2 : return _gnutls_pkcs11_privkey_decrypt_data2(key->key.pkcs11,
1624 : flags,
1625 : ciphertext,
1626 : plaintext,
1627 : plaintext_size);
1628 : #endif
1629 0 : case GNUTLS_PRIVKEY_EXT:
1630 0 : if (key->key.ext.decrypt_func2 == NULL)
1631 0 : return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1632 :
1633 0 : return key->key.ext.decrypt_func2(key,
1634 : key->key.ext.userdata,
1635 : ciphertext, plaintext,
1636 : plaintext_size);
1637 0 : default:
1638 0 : gnutls_assert();
1639 : return GNUTLS_E_INVALID_REQUEST;
1640 : }
1641 : }
1642 :
1643 : /**
1644 : * gnutls_privkey_import_x509_raw:
1645 : * @pkey: The private key
1646 : * @data: The private key data to be imported
1647 : * @format: The format of the private key
1648 : * @password: A password (optional)
1649 : * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
1650 : *
1651 : * This function will import the given private key to the abstract
1652 : * #gnutls_privkey_t type.
1653 : *
1654 : * The supported formats are basic unencrypted key, PKCS8, PKCS12,
1655 : * and the openssl format.
1656 : *
1657 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1658 : * negative error value.
1659 : *
1660 : * Since: 3.1.0
1661 : **/
1662 11602 : int gnutls_privkey_import_x509_raw(gnutls_privkey_t pkey,
1663 : const gnutls_datum_t * data,
1664 : gnutls_x509_crt_fmt_t format,
1665 : const char *password, unsigned int flags)
1666 : {
1667 11602 : gnutls_x509_privkey_t xpriv;
1668 11602 : int ret;
1669 :
1670 11602 : ret = gnutls_x509_privkey_init(&xpriv);
1671 11602 : if (ret < 0)
1672 0 : return gnutls_assert_val(ret);
1673 :
1674 11602 : if (pkey->pin.cb) {
1675 85 : gnutls_x509_privkey_set_pin_function(xpriv, pkey->pin.cb,
1676 : pkey->pin.data);
1677 : }
1678 :
1679 11602 : ret = gnutls_x509_privkey_import2(xpriv, data, format, password, flags);
1680 11602 : if (ret < 0) {
1681 1 : gnutls_assert();
1682 1 : goto cleanup;
1683 : }
1684 :
1685 11601 : ret =
1686 11601 : gnutls_privkey_import_x509(pkey, xpriv,
1687 : GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1688 11601 : if (ret < 0) {
1689 0 : gnutls_assert();
1690 0 : goto cleanup;
1691 : }
1692 :
1693 : return 0;
1694 :
1695 1 : cleanup:
1696 1 : gnutls_x509_privkey_deinit(xpriv);
1697 :
1698 1 : return ret;
1699 : }
1700 :
1701 : /**
1702 : * gnutls_privkey_import_url:
1703 : * @key: A key of type #gnutls_privkey_t
1704 : * @url: A PKCS 11 url
1705 : * @flags: should be zero
1706 : *
1707 : * This function will import a PKCS11 or TPM URL as a
1708 : * private key. The supported URL types can be checked
1709 : * using gnutls_url_is_supported().
1710 : *
1711 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1712 : * negative error value.
1713 : *
1714 : * Since: 3.1.0
1715 : **/
1716 : int
1717 76 : gnutls_privkey_import_url(gnutls_privkey_t key, const char *url,
1718 : unsigned int flags)
1719 : {
1720 76 : unsigned i;
1721 76 : int ret;
1722 :
1723 76 : for (i=0;i<_gnutls_custom_urls_size;i++) {
1724 0 : if (strncmp(url, _gnutls_custom_urls[i].name, _gnutls_custom_urls[i].name_size) == 0) {
1725 0 : if (_gnutls_custom_urls[i].import_key) {
1726 0 : ret = _gnutls_custom_urls[i].import_key(key, url, flags);
1727 0 : goto cleanup;
1728 : }
1729 : break;
1730 : }
1731 : }
1732 :
1733 76 : if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
1734 : #ifdef ENABLE_PKCS11
1735 71 : ret = _gnutls_privkey_import_pkcs11_url(key, url, flags);
1736 : #else
1737 : ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1738 : #endif
1739 71 : goto cleanup;
1740 : }
1741 :
1742 5 : if (strncmp(url, TPMKEY_URL, TPMKEY_URL_SIZE) == 0) {
1743 : #ifdef HAVE_TROUSERS
1744 5 : ret = gnutls_privkey_import_tpm_url(key, url, NULL, NULL, 0);
1745 : #else
1746 : ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1747 : #endif
1748 5 : goto cleanup;
1749 : }
1750 :
1751 0 : if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
1752 0 : ret = _gnutls_privkey_import_system_url(key, url);
1753 0 : goto cleanup;
1754 : }
1755 :
1756 0 : ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1757 76 : cleanup:
1758 76 : return ret;
1759 : }
1760 :
1761 : /**
1762 : * gnutls_privkey_set_pin_function:
1763 : * @key: A key of type #gnutls_privkey_t
1764 : * @fn: the callback
1765 : * @userdata: data associated with the callback
1766 : *
1767 : * This function will set a callback function to be used when
1768 : * required to access the object. This function overrides any other
1769 : * global PIN functions.
1770 : *
1771 : * Note that this function must be called right after initialization
1772 : * to have effect.
1773 : *
1774 : * Since: 3.1.0
1775 : *
1776 : **/
1777 97 : void gnutls_privkey_set_pin_function(gnutls_privkey_t key,
1778 : gnutls_pin_callback_t fn, void *userdata)
1779 : {
1780 97 : key->pin.cb = fn;
1781 97 : key->pin.data = userdata;
1782 97 : }
1783 :
1784 : /**
1785 : * gnutls_privkey_set_flags:
1786 : * @key: A key of type #gnutls_privkey_t
1787 : * @flags: flags from the %gnutls_privkey_flags
1788 : *
1789 : * This function will set flags for the specified private key, after
1790 : * it is generated. Currently this is useful for the %GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT
1791 : * to allow exporting a "provable" private key in backwards compatible way.
1792 : *
1793 : * Since: 3.5.0
1794 : *
1795 : **/
1796 0 : void gnutls_privkey_set_flags(gnutls_privkey_t key,
1797 : unsigned int flags)
1798 : {
1799 0 : key->flags |= flags;
1800 0 : if (key->type == GNUTLS_PRIVKEY_X509)
1801 0 : gnutls_x509_privkey_set_flags(key->key.x509, flags);
1802 0 : }
1803 :
1804 : /**
1805 : * gnutls_privkey_status:
1806 : * @key: Holds the key
1807 : *
1808 : * Checks the status of the private key token. This function
1809 : * is an actual wrapper over gnutls_pkcs11_privkey_status(), and
1810 : * if the private key is a PKCS #11 token it will check whether
1811 : * it is inserted or not.
1812 : *
1813 : * Returns: this function will return non-zero if the token
1814 : * holding the private key is still available (inserted), and zero otherwise.
1815 : *
1816 : * Since: 3.1.10
1817 : *
1818 : **/
1819 0 : int gnutls_privkey_status(gnutls_privkey_t key)
1820 : {
1821 0 : switch (key->type) {
1822 : #ifdef ENABLE_PKCS11
1823 0 : case GNUTLS_PRIVKEY_PKCS11:
1824 0 : return gnutls_pkcs11_privkey_status(key->key.pkcs11);
1825 : #endif
1826 : default:
1827 : return 1;
1828 : }
1829 : }
1830 :
1831 : /**
1832 : * gnutls_privkey_verify_params:
1833 : * @key: should contain a #gnutls_privkey_t type
1834 : *
1835 : * This function will verify the private key parameters.
1836 : *
1837 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1838 : * negative error value.
1839 : *
1840 : * Since: 3.3.0
1841 : **/
1842 3 : int gnutls_privkey_verify_params(gnutls_privkey_t key)
1843 : {
1844 3 : gnutls_pk_params_st params;
1845 3 : int ret;
1846 :
1847 3 : gnutls_pk_params_init(¶ms);
1848 :
1849 3 : ret = _gnutls_privkey_get_mpis(key, ¶ms);
1850 3 : if (ret < 0)
1851 0 : return gnutls_assert_val(ret);
1852 :
1853 3 : ret = _gnutls_pk_verify_priv_params(key->pk_algorithm, ¶ms);
1854 :
1855 3 : gnutls_pk_params_release(¶ms);
1856 :
1857 3 : if (ret < 0) {
1858 1 : gnutls_assert();
1859 1 : return ret;
1860 : }
1861 :
1862 : return 0;
1863 : }
1864 :
1865 : /**
1866 : * gnutls_privkey_get_spki:
1867 : * @privkey: a public key of type #gnutls_privkey_t
1868 : * @spki: a SubjectPublicKeyInfo structure of type #gnutls_privkey_spki_t
1869 : * @flags: must be zero
1870 : *
1871 : * This function will return the public key information if available.
1872 : * The provided @spki must be initialized.
1873 : *
1874 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1875 : * negative error value.
1876 : *
1877 : * Since: 3.6.0
1878 : **/
1879 : int
1880 13 : gnutls_privkey_get_spki(gnutls_privkey_t privkey, gnutls_x509_spki_t spki, unsigned int flags)
1881 : {
1882 13 : gnutls_x509_spki_t p = &privkey->key.x509->params.spki;
1883 :
1884 13 : if (privkey == NULL || privkey->type != GNUTLS_PRIVKEY_X509) {
1885 0 : gnutls_assert();
1886 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1887 : }
1888 :
1889 13 : if (p->pk == GNUTLS_PK_UNKNOWN)
1890 0 : return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1891 :
1892 13 : memcpy(spki, p, sizeof(gnutls_x509_spki_st));
1893 :
1894 13 : return 0;
1895 : }
1896 :
1897 : /**
1898 : * gnutls_privkey_set_spki:
1899 : * @privkey: a public key of type #gnutls_privkey_t
1900 : * @spki: a SubjectPublicKeyInfo structure of type #gnutls_privkey_spki_t
1901 : * @flags: must be zero
1902 : *
1903 : * This function will set the public key information.
1904 : * The provided @spki must be initialized.
1905 : *
1906 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1907 : * negative error value.
1908 : *
1909 : * Since: 3.6.0
1910 : **/
1911 : int
1912 1 : gnutls_privkey_set_spki(gnutls_privkey_t privkey, const gnutls_x509_spki_t spki, unsigned int flags)
1913 : {
1914 1 : if (privkey == NULL || privkey->type != GNUTLS_PRIVKEY_X509) {
1915 0 : gnutls_assert();
1916 0 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1917 : }
1918 :
1919 1 : return gnutls_x509_privkey_set_spki(privkey->key.x509, spki, flags);
1920 : }
1921 :
1922 : /* Checks whether the public key given is compatible with the
1923 : * signature algorithm used. The session is only used for audit logging, and
1924 : * it may be null.
1925 : */
1926 87402 : unsigned _gnutls_privkey_compatible_with_sig(gnutls_privkey_t privkey,
1927 : gnutls_sign_algorithm_t sign)
1928 : {
1929 87402 : const gnutls_sign_entry_st *se;
1930 :
1931 87402 : se = _gnutls_sign_to_entry(sign);
1932 87402 : if (unlikely(se == NULL))
1933 0 : return gnutls_assert_val(0);
1934 :
1935 : /* Prevent RSA-PSS private keys from negotiating an RSA signature,
1936 : * and RSA keys which cannot do RSA-PSS (e.g., smart card) from
1937 : * negotiating RSA-PSS sig.
1938 : */
1939 :
1940 87402 : if (se->pk != privkey->pk_algorithm) { /* if the PK algorithm of the signature differs to the one on the pubkey */
1941 65317 : if (!sign_supports_priv_pk_algorithm(se, privkey->pk_algorithm)) {
1942 57862 : _gnutls_handshake_log("cannot use privkey of %s with %s\n",
1943 : gnutls_pk_get_name(privkey->pk_algorithm), se->name);
1944 57862 : return 0;
1945 : }
1946 : }
1947 :
1948 29540 : if (privkey->type == GNUTLS_PRIVKEY_EXT) {
1949 430 : if (privkey->key.ext.info_func) {
1950 330 : int ret;
1951 :
1952 660 : ret = privkey->key.ext.info_func(privkey,
1953 330 : GNUTLS_SIGN_ALGO_TO_FLAGS(sign)|GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO,
1954 : privkey->key.ext.userdata);
1955 330 : if (ret != -1)
1956 330 : return ret;
1957 :
1958 : /* use the old flag */
1959 0 : ret = privkey->key.ext.info_func(privkey, GNUTLS_PRIVKEY_INFO_SIGN_ALGO,
1960 : privkey->key.ext.userdata);
1961 0 : if (ret == (int)sign)
1962 : return 1;
1963 : }
1964 :
1965 : /* This key type is very limited on what it can handle */
1966 100 : if (!PK_IS_OK_FOR_EXT2(se->pk))
1967 57 : return gnutls_assert_val(0);
1968 : }
1969 : #ifdef ENABLE_PKCS11
1970 29110 : else if (privkey->type == GNUTLS_PRIVKEY_PKCS11) {
1971 191 : if (privkey->pk_algorithm == GNUTLS_PK_RSA && se->pk == GNUTLS_PK_RSA_PSS) {
1972 89 : if (!privkey->key.pkcs11->rsa_pss_ok)
1973 23 : return 0;
1974 : }
1975 : }
1976 : #endif
1977 :
1978 : return 1;
1979 : }
|