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 **/
gnutls_privkey_get_type(gnutls_privkey_t key)60 gnutls_privkey_type_t gnutls_privkey_get_type(gnutls_privkey_t key)
61 {
62 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 **/
gnutls_privkey_get_seed(gnutls_privkey_t key,gnutls_digest_algorithm_t * digest,void * seed,size_t * seed_size)81 int gnutls_privkey_get_seed(gnutls_privkey_t key, gnutls_digest_algorithm_t *digest, void *seed, size_t *seed_size)
82 {
83 if (key->type != GNUTLS_PRIVKEY_X509)
84 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
85 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 **/
gnutls_privkey_verify_seed(gnutls_privkey_t key,gnutls_digest_algorithm_t digest,const void * seed,size_t seed_size)103 int gnutls_privkey_verify_seed(gnutls_privkey_t key, gnutls_digest_algorithm_t digest, const void *seed, size_t seed_size)
104 {
105 if (key->type != GNUTLS_PRIVKEY_X509)
106 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
107 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 **/
gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key,unsigned int * bits)124 int gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key, unsigned int *bits)
125 {
126 switch (key->type) {
127 #ifdef ENABLE_PKCS11
128 case GNUTLS_PRIVKEY_PKCS11:
129 return gnutls_pkcs11_privkey_get_pk_algorithm(key->key.pkcs11,
130 bits);
131 #endif
132 case GNUTLS_PRIVKEY_X509:
133 if (bits) {
134 *bits = pubkey_to_bits(&key->key.x509->params);
135 }
136
137 return gnutls_x509_privkey_get_pk_algorithm(key->key.x509);
138 case GNUTLS_PRIVKEY_EXT:
139 if (bits)
140 *bits = key->key.ext.bits;
141
142 return key->pk_algorithm;
143 default:
144 gnutls_assert();
145 return GNUTLS_E_INVALID_REQUEST;
146 }
147
148 }
149
150 static int
privkey_to_pubkey(gnutls_pk_algorithm_t pk,const gnutls_pk_params_st * priv,gnutls_pk_params_st * pub)151 privkey_to_pubkey(gnutls_pk_algorithm_t pk,
152 const gnutls_pk_params_st * priv, gnutls_pk_params_st * pub)
153 {
154 int ret;
155
156 pub->algo = priv->algo;
157 pub->pkflags = priv->pkflags;
158 pub->curve = priv->curve;
159 pub->gost_params = priv->gost_params;
160 pub->qbits = priv->qbits;
161 memcpy(&pub->spki, &priv->spki, sizeof(gnutls_x509_spki_st));
162
163 switch (pk) {
164 case GNUTLS_PK_RSA_PSS:
165 case GNUTLS_PK_RSA:
166 pub->params[0] = _gnutls_mpi_copy(priv->params[0]);
167 pub->params[1] = _gnutls_mpi_copy(priv->params[1]);
168
169 pub->params_nr = RSA_PUBLIC_PARAMS;
170
171 if (pub->params[0] == NULL || pub->params[1] == NULL) {
172 gnutls_assert();
173 ret = GNUTLS_E_MEMORY_ERROR;
174 goto cleanup;
175 }
176
177 break;
178 case GNUTLS_PK_DSA:
179 pub->params[0] = _gnutls_mpi_copy(priv->params[0]);
180 pub->params[1] = _gnutls_mpi_copy(priv->params[1]);
181 pub->params[2] = _gnutls_mpi_copy(priv->params[2]);
182 pub->params[3] = _gnutls_mpi_copy(priv->params[3]);
183
184 pub->params_nr = DSA_PUBLIC_PARAMS;
185
186 if (pub->params[0] == NULL || pub->params[1] == NULL ||
187 pub->params[2] == NULL || pub->params[3] == NULL) {
188 gnutls_assert();
189 ret = GNUTLS_E_MEMORY_ERROR;
190 goto cleanup;
191 }
192
193 break;
194 case GNUTLS_PK_ECDSA:
195 pub->params[ECC_X] = _gnutls_mpi_copy(priv->params[ECC_X]);
196 pub->params[ECC_Y] = _gnutls_mpi_copy(priv->params[ECC_Y]);
197
198 pub->params_nr = ECC_PUBLIC_PARAMS;
199
200 if (pub->params[ECC_X] == NULL || pub->params[ECC_Y] == NULL) {
201 gnutls_assert();
202 ret = GNUTLS_E_MEMORY_ERROR;
203 goto cleanup;
204 }
205
206 break;
207 case GNUTLS_PK_EDDSA_ED25519:
208 case GNUTLS_PK_EDDSA_ED448:
209 ret = _gnutls_set_datum(&pub->raw_pub, priv->raw_pub.data, priv->raw_pub.size);
210 if (ret < 0)
211 return gnutls_assert_val(ret);
212
213 break;
214 case GNUTLS_PK_GOST_01:
215 case GNUTLS_PK_GOST_12_256:
216 case GNUTLS_PK_GOST_12_512:
217 pub->params[GOST_X] = _gnutls_mpi_copy(priv->params[GOST_X]);
218 pub->params[GOST_Y] = _gnutls_mpi_copy(priv->params[GOST_Y]);
219
220 pub->params_nr = GOST_PUBLIC_PARAMS;
221
222 if (pub->params[GOST_X] == NULL || pub->params[GOST_Y] == NULL) {
223 gnutls_assert();
224 ret = GNUTLS_E_MEMORY_ERROR;
225 goto cleanup;
226 }
227
228 break;
229 default:
230 gnutls_assert();
231 return GNUTLS_E_INVALID_REQUEST;
232 }
233
234 return 0;
235 cleanup:
236 gnutls_pk_params_release(pub);
237 return ret;
238 }
239
240 /* Returns the public key of the private key (if possible)
241 */
242 int
_gnutls_privkey_get_mpis(gnutls_privkey_t key,gnutls_pk_params_st * params)243 _gnutls_privkey_get_mpis(gnutls_privkey_t key, gnutls_pk_params_st * params)
244 {
245 int ret;
246
247 switch (key->type) {
248 case GNUTLS_PRIVKEY_X509:
249 ret = _gnutls_pk_params_copy(params, &key->key.x509->params);
250 break;
251 #ifdef ENABLE_PKCS11
252 case GNUTLS_PRIVKEY_PKCS11: {
253 gnutls_pubkey_t pubkey;
254
255 ret = _pkcs11_privkey_get_pubkey(key->key.pkcs11, &pubkey, 0);
256 if (ret < 0)
257 return gnutls_assert_val(ret);
258
259 ret = _gnutls_pubkey_get_mpis(pubkey, params);
260 gnutls_pubkey_deinit(pubkey);
261
262 break;
263 }
264 #endif
265 default:
266 gnutls_assert();
267 return GNUTLS_E_INVALID_REQUEST;
268 }
269
270 return ret;
271 }
272
273 int
_gnutls_privkey_get_public_mpis(gnutls_privkey_t key,gnutls_pk_params_st * params)274 _gnutls_privkey_get_public_mpis(gnutls_privkey_t key,
275 gnutls_pk_params_st * params)
276 {
277 int ret;
278 gnutls_pk_params_st tmp1;
279
280 gnutls_pk_params_init(&tmp1);
281
282 ret = _gnutls_privkey_get_mpis(key, &tmp1);
283 if (ret < 0)
284 return gnutls_assert_val(ret);
285
286 ret = privkey_to_pubkey(key->pk_algorithm, &tmp1, params);
287
288 gnutls_pk_params_release(&tmp1);
289
290 if (ret < 0)
291 gnutls_assert();
292
293 return ret;
294 }
295
296 /* This function retrieves default sign parameters from KEY. */
297 int
_gnutls_privkey_get_spki_params(gnutls_privkey_t key,gnutls_x509_spki_st * params)298 _gnutls_privkey_get_spki_params(gnutls_privkey_t key,
299 gnutls_x509_spki_st * params)
300 {
301 switch (key->type) {
302 #ifdef ENABLE_PKCS11
303 case GNUTLS_PRIVKEY_PKCS11:
304 break;
305 #endif
306 case GNUTLS_PRIVKEY_EXT:
307 break;
308 case GNUTLS_PRIVKEY_X509:
309 _gnutls_x509_privkey_get_spki_params(key->key.x509, params);
310 return 0;
311 default:
312 gnutls_assert();
313 return GNUTLS_E_INVALID_REQUEST;
314 }
315
316 memset(params, 0, sizeof(gnutls_x509_spki_st));
317
318 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
_gnutls_privkey_update_spki_params(gnutls_privkey_t key,gnutls_pk_algorithm_t pk,gnutls_digest_algorithm_t dig,unsigned flags,gnutls_x509_spki_st * params)329 _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 unsigned salt_size = 0;
336 unsigned bits = 0;
337 gnutls_pk_algorithm_t key_pk;
338
339 if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS) {
340 if (!GNUTLS_PK_IS_RSA(pk))
341 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
342 pk = GNUTLS_PK_RSA_PSS;
343 }
344
345 key_pk = gnutls_privkey_get_pk_algorithm(key, &bits);
346 if ((key_pk != pk) &&
347 !(key_pk == GNUTLS_PK_RSA && pk == GNUTLS_PK_RSA_PSS)) {
348 gnutls_assert();
349 return GNUTLS_E_CONSTRAINT_ERROR;
350 }
351
352 if (pk == GNUTLS_PK_RSA_PSS) {
353 const mac_entry_st *me;
354 int ret;
355
356 me = hash_to_entry(dig);
357 if (unlikely(me == NULL))
358 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
359
360 if (params->pk == GNUTLS_PK_RSA)
361 salt_size = 0;
362 else if (params->pk == GNUTLS_PK_RSA_PSS) {
363 if (params->rsa_pss_dig != GNUTLS_DIG_UNKNOWN && dig != params->rsa_pss_dig) {
364 return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
365 }
366
367 salt_size = params->salt_size;
368 }
369
370 if (flags & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE)
371 params->salt_size = 0;
372 else {
373 ret = _gnutls_find_rsa_pss_salt_size(bits, me, salt_size);
374 if (ret < 0)
375 return gnutls_assert_val(ret);
376 params->salt_size = ret;
377 }
378 params->rsa_pss_dig = dig;
379 }
380
381 params->pk = pk;
382
383 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 **/
gnutls_privkey_init(gnutls_privkey_t * key)406 int gnutls_privkey_init(gnutls_privkey_t * key)
407 {
408 FAIL_IF_LIB_ERROR;
409
410 *key = gnutls_calloc(1, sizeof(struct gnutls_privkey_st));
411 if (*key == NULL) {
412 gnutls_assert();
413 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 **/
gnutls_privkey_deinit(gnutls_privkey_t key)427 void gnutls_privkey_deinit(gnutls_privkey_t key)
428 {
429 if (key == NULL)
430 return;
431
432 if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE
433 || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY)
434 switch (key->type) {
435 #ifdef ENABLE_PKCS11
436 case GNUTLS_PRIVKEY_PKCS11:
437 gnutls_pkcs11_privkey_deinit(key->key.pkcs11);
438 break;
439 #endif
440 case GNUTLS_PRIVKEY_X509:
441 gnutls_x509_privkey_deinit(key->key.x509);
442 break;
443 case GNUTLS_PRIVKEY_EXT:
444 if (key->key.ext.deinit_func != NULL)
445 key->key.ext.deinit_func(key,
446 key->key.ext.userdata);
447 break;
448 default:
449 break;
450 }
451 gnutls_free(key);
452 }
453
454 /* Will erase all private key information, except PIN */
_gnutls_privkey_cleanup(gnutls_privkey_t key)455 void _gnutls_privkey_cleanup(gnutls_privkey_t key)
456 {
457 memset(&key->key, 0, sizeof(key->key));
458 key->type = 0;
459 key->pk_algorithm = 0;
460 key->flags = 0;
461 }
462
463 /* will fail if the private key contains an actual key.
464 */
check_if_clean(gnutls_privkey_t key)465 static int check_if_clean(gnutls_privkey_t key)
466 {
467 if (key->type != 0)
468 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
gnutls_privkey_import_pkcs11(gnutls_privkey_t pkey,gnutls_pkcs11_privkey_t key,unsigned int flags)496 gnutls_privkey_import_pkcs11(gnutls_privkey_t pkey,
497 gnutls_pkcs11_privkey_t key, unsigned int flags)
498 {
499 int ret;
500
501 ret = check_if_clean(pkey);
502 if (ret < 0) {
503 gnutls_assert();
504 return ret;
505 }
506
507 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY)
508 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
509
510 pkey->key.pkcs11 = key;
511 pkey->type = GNUTLS_PRIVKEY_PKCS11;
512 pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm(key, NULL);
513 pkey->flags = flags;
514
515 if (pkey->pin.data)
516 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
_gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key,const char * url,unsigned flags)544 int _gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key, const char *url, unsigned flags)
545 {
546 gnutls_pkcs11_privkey_t pkey;
547 int ret;
548
549 ret = gnutls_pkcs11_privkey_init(&pkey);
550 if (ret < 0) {
551 gnutls_assert();
552 return ret;
553 }
554
555 if (key->pin.cb)
556 gnutls_pkcs11_privkey_set_pin_function(pkey, key->pin.cb,
557 key->pin.data);
558
559 ret = gnutls_pkcs11_privkey_import_url(pkey, url, flags);
560 if (ret < 0) {
561 gnutls_assert();
562 goto cleanup;
563 }
564
565 ret =
566 gnutls_privkey_import_pkcs11(key, pkey,
567 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
568 if (ret < 0) {
569 gnutls_assert();
570 goto cleanup;
571 }
572
573 return 0;
574
575 cleanup:
576 gnutls_pkcs11_privkey_deinit(pkey);
577
578 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
gnutls_privkey_export_pkcs11(gnutls_privkey_t pkey,gnutls_pkcs11_privkey_t * key)597 gnutls_privkey_export_pkcs11(gnutls_privkey_t pkey,
598 gnutls_pkcs11_privkey_t *key)
599 {
600 int ret;
601
602 if (pkey->type != GNUTLS_PRIVKEY_PKCS11) {
603 gnutls_assert();
604 return GNUTLS_E_INVALID_REQUEST;
605 }
606
607 ret = gnutls_pkcs11_privkey_init(key);
608 if (ret < 0)
609 return gnutls_assert_val(ret);
610
611 ret = gnutls_pkcs11_privkey_cpy(*key, pkey->key.pkcs11);
612 if (ret < 0) {
613 gnutls_pkcs11_privkey_deinit(*key);
614 *key = NULL;
615
616 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
gnutls_privkey_import_ext(gnutls_privkey_t pkey,gnutls_pk_algorithm_t pk,void * userdata,gnutls_privkey_sign_func sign_func,gnutls_privkey_decrypt_func decrypt_func,unsigned int flags)649 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 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
gnutls_privkey_import_ext2(gnutls_privkey_t pkey,gnutls_pk_algorithm_t pk,void * userdata,gnutls_privkey_sign_func sign_fn,gnutls_privkey_decrypt_func decrypt_fn,gnutls_privkey_deinit_func deinit_fn,unsigned int flags)691 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 int ret;
700
701 ret = check_if_clean(pkey);
702 if (ret < 0) {
703 gnutls_assert();
704 return ret;
705 }
706
707 if (!PK_IS_OK_FOR_EXT2(pk))
708 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
709
710 if (sign_fn == NULL && decrypt_fn == NULL)
711 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
712
713 pkey->key.ext.sign_func = sign_fn;
714 pkey->key.ext.decrypt_func = decrypt_fn;
715 pkey->key.ext.deinit_func = deinit_fn;
716 pkey->key.ext.userdata = userdata;
717 pkey->type = GNUTLS_PRIVKEY_EXT;
718 pkey->pk_algorithm = pk;
719 pkey->flags = flags;
720
721 /* Ensure gnutls_privkey_deinit() calls the deinit_func */
722 if (deinit_fn)
723 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
gnutls_privkey_import_ext3(gnutls_privkey_t pkey,void * userdata,gnutls_privkey_sign_func sign_fn,gnutls_privkey_decrypt_func decrypt_fn,gnutls_privkey_deinit_func deinit_fn,gnutls_privkey_info_func info_fn,unsigned int flags)758 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 int ret;
767
768 ret = check_if_clean(pkey);
769 if (ret < 0) {
770 gnutls_assert();
771 return ret;
772 }
773
774 if (sign_fn == NULL && decrypt_fn == NULL)
775 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
776
777 if (info_fn == NULL)
778 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
779
780 pkey->key.ext.sign_func = sign_fn;
781 pkey->key.ext.decrypt_func = decrypt_fn;
782 pkey->key.ext.deinit_func = deinit_fn;
783 pkey->key.ext.info_func = info_fn;
784 pkey->key.ext.userdata = userdata;
785 pkey->type = GNUTLS_PRIVKEY_EXT;
786 pkey->flags = flags;
787
788 pkey->pk_algorithm = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata);
789
790 if (!PK_IS_OK_FOR_EXT2(pkey->pk_algorithm))
791 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
792
793 /* Ensure gnutls_privkey_deinit() calls the deinit_func */
794 if (deinit_fn)
795 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
gnutls_privkey_import_ext4(gnutls_privkey_t pkey,void * userdata,gnutls_privkey_sign_data_func sign_data_fn,gnutls_privkey_sign_hash_func sign_hash_fn,gnutls_privkey_decrypt_func decrypt_fn,gnutls_privkey_deinit_func deinit_fn,gnutls_privkey_info_func info_fn,unsigned int flags)847 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 int ret;
857
858 ret = check_if_clean(pkey);
859 if (ret < 0) {
860 gnutls_assert();
861 return ret;
862 }
863
864 if (sign_data_fn == NULL && sign_hash_fn == NULL && decrypt_fn == NULL)
865 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
866
867 if (info_fn == NULL)
868 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
869
870 pkey->key.ext.sign_data_func = sign_data_fn;
871 pkey->key.ext.sign_hash_func = sign_hash_fn;
872 pkey->key.ext.decrypt_func = decrypt_fn;
873 pkey->key.ext.deinit_func = deinit_fn;
874 pkey->key.ext.info_func = info_fn;
875 pkey->key.ext.userdata = userdata;
876 pkey->type = GNUTLS_PRIVKEY_EXT;
877 pkey->flags = flags;
878
879 pkey->pk_algorithm = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO, pkey->key.ext.userdata);
880
881 ret = pkey->key.ext.info_func(pkey, GNUTLS_PRIVKEY_INFO_PK_ALGO_BITS, pkey->key.ext.userdata);
882 if (ret >= 0)
883 pkey->key.ext.bits = ret;
884
885 /* Ensure gnutls_privkey_deinit() calls the deinit_func */
886 if (deinit_fn)
887 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
gnutls_privkey_import_x509(gnutls_privkey_t pkey,gnutls_x509_privkey_t key,unsigned int flags)913 gnutls_privkey_import_x509(gnutls_privkey_t pkey,
914 gnutls_x509_privkey_t key, unsigned int flags)
915 {
916 int ret;
917
918 ret = check_if_clean(pkey);
919 if (ret < 0) {
920 gnutls_assert();
921 return ret;
922 }
923
924 if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) {
925 ret = gnutls_x509_privkey_init(&pkey->key.x509);
926 if (ret < 0)
927 return gnutls_assert_val(ret);
928
929 ret = gnutls_x509_privkey_cpy(pkey->key.x509, key);
930 if (ret < 0) {
931 gnutls_x509_privkey_deinit(pkey->key.x509);
932 return gnutls_assert_val(ret);
933 }
934 } else
935 pkey->key.x509 = key;
936
937 pkey->type = GNUTLS_PRIVKEY_X509;
938 pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm(key);
939 pkey->flags = flags;
940
941 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
gnutls_privkey_export_x509(gnutls_privkey_t pkey,gnutls_x509_privkey_t * key)960 gnutls_privkey_export_x509(gnutls_privkey_t pkey,
961 gnutls_x509_privkey_t *key)
962 {
963 int ret;
964
965 if (pkey->type != GNUTLS_PRIVKEY_X509) {
966 gnutls_assert();
967 return GNUTLS_E_INVALID_REQUEST;
968 }
969
970 ret = gnutls_x509_privkey_init(key);
971 if (ret < 0)
972 return gnutls_assert_val(ret);
973
974 ret = gnutls_x509_privkey_cpy(*key, pkey->key.x509);
975 if (ret < 0) {
976 gnutls_x509_privkey_deinit(*key);
977 *key = NULL;
978
979 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
gnutls_privkey_generate(gnutls_privkey_t pkey,gnutls_pk_algorithm_t algo,unsigned int bits,unsigned int flags)1019 gnutls_privkey_generate(gnutls_privkey_t pkey,
1020 gnutls_pk_algorithm_t algo, unsigned int bits,
1021 unsigned int flags)
1022 {
1023 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
gnutls_privkey_generate2(gnutls_privkey_t pkey,gnutls_pk_algorithm_t algo,unsigned int bits,unsigned int flags,const gnutls_keygen_data_st * data,unsigned data_size)1067 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 int ret;
1072
1073 ret = gnutls_x509_privkey_init(&pkey->key.x509);
1074 if (ret < 0)
1075 return gnutls_assert_val(ret);
1076
1077 ret = gnutls_x509_privkey_generate2(pkey->key.x509, algo, bits, flags, data, data_size);
1078 if (ret < 0) {
1079 gnutls_x509_privkey_deinit(pkey->key.x509);
1080 pkey->key.x509 = NULL;
1081 return gnutls_assert_val(ret);
1082 }
1083
1084 pkey->type = GNUTLS_PRIVKEY_X509;
1085 pkey->pk_algorithm = algo;
1086 pkey->flags = flags | GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
1087
1088 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
gnutls_privkey_sign_data(gnutls_privkey_t signer,gnutls_digest_algorithm_t hash,unsigned int flags,const gnutls_datum_t * data,gnutls_datum_t * signature)1113 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 int ret;
1120 gnutls_x509_spki_st params;
1121
1122 if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
1123 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1124
1125 ret = _gnutls_privkey_get_spki_params(signer, ¶ms);
1126 if (ret < 0) {
1127 gnutls_assert();
1128 return ret;
1129 }
1130
1131 ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm,
1132 hash, flags, ¶ms);
1133 if (ret < 0) {
1134 gnutls_assert();
1135 return ret;
1136 }
1137
1138 FIX_SIGN_PARAMS(params, flags, hash);
1139
1140 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
gnutls_privkey_sign_data2(gnutls_privkey_t signer,gnutls_sign_algorithm_t algo,unsigned int flags,const gnutls_datum_t * data,gnutls_datum_t * signature)1162 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 int ret;
1169 gnutls_x509_spki_st params;
1170 const gnutls_sign_entry_st *se;
1171
1172 if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
1173 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1174
1175 se = _gnutls_sign_to_entry(algo);
1176 if (se == NULL)
1177 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1178
1179 ret = _gnutls_privkey_get_spki_params(signer, ¶ms);
1180 if (ret < 0) {
1181 gnutls_assert();
1182 return ret;
1183 }
1184
1185 ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash,
1186 flags, ¶ms);
1187 if (ret < 0) {
1188 gnutls_assert();
1189 return ret;
1190 }
1191
1192 FIX_SIGN_PARAMS(params, flags, se->hash);
1193
1194 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
gnutls_privkey_sign_hash2(gnutls_privkey_t signer,gnutls_sign_algorithm_t algo,unsigned int flags,const gnutls_datum_t * hash_data,gnutls_datum_t * signature)1223 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 int ret;
1230 gnutls_x509_spki_st params;
1231 const gnutls_sign_entry_st *se;
1232
1233 if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA) {
1234 /* the corresponding signature algorithm is SIGN_RSA_RAW,
1235 * irrespective of hash algorithm. */
1236 se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
1237 } else {
1238 se = _gnutls_sign_to_entry(algo);
1239 if (unlikely(se == NULL))
1240 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1241
1242 }
1243
1244 ret = _gnutls_privkey_get_spki_params(signer, ¶ms);
1245 if (ret < 0) {
1246 gnutls_assert();
1247 return ret;
1248 }
1249
1250 ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash,
1251 flags, ¶ms);
1252 if (ret < 0) {
1253 gnutls_assert();
1254 return ret;
1255 }
1256
1257 FIX_SIGN_PARAMS(params, flags, se->hash);
1258
1259 return privkey_sign_prehashed(signer, se, hash_data, signature, ¶ms);
1260 }
1261
1262 int
privkey_sign_and_hash_data(gnutls_privkey_t signer,const gnutls_sign_entry_st * se,const gnutls_datum_t * data,gnutls_datum_t * signature,gnutls_x509_spki_st * params)1263 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 int ret;
1270 gnutls_datum_t digest;
1271 const mac_entry_st *me;
1272
1273 if (unlikely(se == NULL))
1274 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1275
1276 if (_gnutls_pk_is_not_prehashed(se->pk)) {
1277 return privkey_sign_raw_data(signer, se, data, signature, params);
1278 }
1279
1280 me = hash_to_entry(se->hash);
1281 if (me == NULL)
1282 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1283
1284 ret = pk_hash_data(se->pk, me, NULL, data, &digest);
1285 if (ret < 0) {
1286 gnutls_assert();
1287 return ret;
1288 }
1289
1290 ret = pk_prepare_hash(se->pk, me, &digest);
1291 if (ret < 0) {
1292 gnutls_assert();
1293 goto cleanup;
1294 }
1295
1296 ret = privkey_sign_raw_data(signer, se, &digest, signature, params);
1297 _gnutls_free_datum(&digest);
1298
1299 if (ret < 0) {
1300 gnutls_assert();
1301 return ret;
1302 }
1303
1304 return 0;
1305
1306 cleanup:
1307 _gnutls_free_datum(&digest);
1308 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
gnutls_privkey_sign_hash(gnutls_privkey_t signer,gnutls_digest_algorithm_t hash_algo,unsigned int flags,const gnutls_datum_t * hash_data,gnutls_datum_t * signature)1341 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 int ret;
1348 gnutls_x509_spki_st params;
1349 const gnutls_sign_entry_st *se;
1350
1351 ret = _gnutls_privkey_get_spki_params(signer, ¶ms);
1352 if (ret < 0) {
1353 gnutls_assert();
1354 return ret;
1355 }
1356
1357 ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm,
1358 hash_algo, flags, ¶ms);
1359 if (ret < 0) {
1360 gnutls_assert();
1361 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 if (hash_algo == 0 && (params.pk == GNUTLS_PK_DSA || params.pk == GNUTLS_PK_ECDSA)) {
1368 hash_algo = _gnutls_hash_size_to_sha_hash(hash_data->size);
1369 }
1370
1371 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 se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
1375 } else {
1376 se = _gnutls_pk_to_sign_entry(params.pk, hash_algo);
1377 }
1378
1379 if (unlikely(se == NULL))
1380 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1381
1382 FIX_SIGN_PARAMS(params, flags, hash_algo);
1383
1384 return privkey_sign_prehashed(signer, se,
1385 hash_data, signature, ¶ms);
1386 }
1387
1388 static int
privkey_sign_prehashed(gnutls_privkey_t signer,const gnutls_sign_entry_st * se,const gnutls_datum_t * hash_data,gnutls_datum_t * signature,gnutls_x509_spki_st * params)1389 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 int ret;
1396 gnutls_datum_t digest;
1397
1398 if (unlikely(se == NULL))
1399 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1400
1401 if (se->id == GNUTLS_SIGN_RSA_RAW) {
1402 return privkey_sign_raw_data(signer,
1403 se,
1404 hash_data, signature,
1405 params);
1406 }
1407
1408 if (_gnutls_pk_is_not_prehashed(signer->pk_algorithm)) {
1409 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1410 }
1411
1412 digest.data = gnutls_malloc(hash_data->size);
1413 if (digest.data == NULL) {
1414 gnutls_assert();
1415 return GNUTLS_E_MEMORY_ERROR;
1416 }
1417 digest.size = hash_data->size;
1418 memcpy(digest.data, hash_data->data, digest.size);
1419
1420 ret = pk_prepare_hash(se->pk, hash_to_entry(se->hash), &digest);
1421 if (ret < 0) {
1422 gnutls_assert();
1423 goto cleanup;
1424 }
1425
1426 ret = privkey_sign_raw_data(signer,
1427 se,
1428 &digest, signature,
1429 params);
1430 if (ret < 0) {
1431 gnutls_assert();
1432 goto cleanup;
1433 }
1434
1435 ret = 0;
1436
1437 cleanup:
1438 _gnutls_free_datum(&digest);
1439 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
privkey_sign_raw_data(gnutls_privkey_t key,const gnutls_sign_entry_st * se,const gnutls_datum_t * data,gnutls_datum_t * signature,gnutls_x509_spki_st * params)1465 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 if (unlikely(se == NULL))
1472 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1473
1474 switch (key->type) {
1475 #ifdef ENABLE_PKCS11
1476 case GNUTLS_PRIVKEY_PKCS11:
1477 return _gnutls_pkcs11_privkey_sign(key->key.pkcs11, se,
1478 data, signature,
1479 params);
1480 #endif
1481 case GNUTLS_PRIVKEY_X509:
1482 return _gnutls_pk_sign(se->pk, signature, data,
1483 &key->key.x509->params, params);
1484 case GNUTLS_PRIVKEY_EXT:
1485 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 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1489
1490 if (_gnutls_pk_is_not_prehashed(se->pk)) {
1491 if (!key->key.ext.sign_data_func)
1492 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1493
1494 return key->key.ext.sign_data_func(key, se->id,
1495 key->key.ext.userdata,
1496 0,
1497 data, signature);
1498 } else if (key->key.ext.sign_hash_func) {
1499 if (se->pk == GNUTLS_PK_RSA) {
1500 se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW);
1501 assert(se != NULL);
1502 }
1503
1504 /* se may not be set here if we are doing legacy RSA */
1505 return key->key.ext.sign_hash_func(key, se->id,
1506 key->key.ext.userdata,
1507 0,
1508 data, signature);
1509 } else {
1510 if (!PK_IS_OK_FOR_EXT2(se->pk))
1511 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1512
1513 return key->key.ext.sign_func(key, key->key.ext.userdata,
1514 data, signature);
1515 }
1516 default:
1517 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
gnutls_privkey_decrypt_data(gnutls_privkey_t key,unsigned int flags,const gnutls_datum_t * ciphertext,gnutls_datum_t * plaintext)1538 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 switch (key->type) {
1544 case GNUTLS_PRIVKEY_X509:
1545 return _gnutls_pk_decrypt(key->pk_algorithm, plaintext,
1546 ciphertext, &key->key.x509->params);
1547 #ifdef ENABLE_PKCS11
1548 case GNUTLS_PRIVKEY_PKCS11:
1549 return _gnutls_pkcs11_privkey_decrypt_data(key->key.pkcs11,
1550 flags,
1551 ciphertext,
1552 plaintext);
1553 #endif
1554 case GNUTLS_PRIVKEY_EXT:
1555 if (key->key.ext.decrypt_func == NULL)
1556 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1557
1558 return key->key.ext.decrypt_func(key,
1559 key->key.ext.userdata,
1560 ciphertext, plaintext);
1561 default:
1562 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
gnutls_privkey_decrypt_data2(gnutls_privkey_t key,unsigned int flags,const gnutls_datum_t * ciphertext,unsigned char * plaintext,size_t plaintext_size)1586 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 if (key->type == GNUTLS_PRIVKEY_EXT &&
1599 key->key.ext.decrypt_func2 == NULL &&
1600 key->key.ext.decrypt_func != NULL) {
1601 gnutls_datum_t plain;
1602 int ret;
1603 ret = key->key.ext.decrypt_func(key,
1604 key->key.ext.userdata,
1605 ciphertext,
1606 &plain);
1607 if (plain.size != plaintext_size) {
1608 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1609 } else {
1610 memcpy(plaintext, plain.data, plain.size);
1611 }
1612 gnutls_free(plain.data);
1613 return ret;
1614 }
1615
1616 switch (key->type) {
1617 case GNUTLS_PRIVKEY_X509:
1618 return _gnutls_pk_decrypt2(key->pk_algorithm, ciphertext,
1619 plaintext, plaintext_size,
1620 &key->key.x509->params);
1621 #ifdef ENABLE_PKCS11
1622 case GNUTLS_PRIVKEY_PKCS11:
1623 return _gnutls_pkcs11_privkey_decrypt_data2(key->key.pkcs11,
1624 flags,
1625 ciphertext,
1626 plaintext,
1627 plaintext_size);
1628 #endif
1629 case GNUTLS_PRIVKEY_EXT:
1630 if (key->key.ext.decrypt_func2 == NULL)
1631 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1632
1633 return key->key.ext.decrypt_func2(key,
1634 key->key.ext.userdata,
1635 ciphertext, plaintext,
1636 plaintext_size);
1637 default:
1638 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 **/
gnutls_privkey_import_x509_raw(gnutls_privkey_t pkey,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format,const char * password,unsigned int flags)1662 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 gnutls_x509_privkey_t xpriv;
1668 int ret;
1669
1670 ret = gnutls_x509_privkey_init(&xpriv);
1671 if (ret < 0)
1672 return gnutls_assert_val(ret);
1673
1674 if (pkey->pin.cb) {
1675 gnutls_x509_privkey_set_pin_function(xpriv, pkey->pin.cb,
1676 pkey->pin.data);
1677 }
1678
1679 ret = gnutls_x509_privkey_import2(xpriv, data, format, password, flags);
1680 if (ret < 0) {
1681 gnutls_assert();
1682 goto cleanup;
1683 }
1684
1685 ret =
1686 gnutls_privkey_import_x509(pkey, xpriv,
1687 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
1688 if (ret < 0) {
1689 gnutls_assert();
1690 goto cleanup;
1691 }
1692
1693 return 0;
1694
1695 cleanup:
1696 gnutls_x509_privkey_deinit(xpriv);
1697
1698 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
gnutls_privkey_import_url(gnutls_privkey_t key,const char * url,unsigned int flags)1717 gnutls_privkey_import_url(gnutls_privkey_t key, const char *url,
1718 unsigned int flags)
1719 {
1720 unsigned i;
1721 int ret;
1722
1723 for (i=0;i<_gnutls_custom_urls_size;i++) {
1724 if (strncmp(url, _gnutls_custom_urls[i].name, _gnutls_custom_urls[i].name_size) == 0) {
1725 if (_gnutls_custom_urls[i].import_key) {
1726 ret = _gnutls_custom_urls[i].import_key(key, url, flags);
1727 goto cleanup;
1728 }
1729 break;
1730 }
1731 }
1732
1733 if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0) {
1734 #ifdef ENABLE_PKCS11
1735 ret = _gnutls_privkey_import_pkcs11_url(key, url, flags);
1736 #else
1737 ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1738 #endif
1739 goto cleanup;
1740 }
1741
1742 if (strncmp(url, TPMKEY_URL, TPMKEY_URL_SIZE) == 0) {
1743 #ifdef HAVE_TROUSERS
1744 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 goto cleanup;
1749 }
1750
1751 if (strncmp(url, SYSTEM_URL, SYSTEM_URL_SIZE) == 0) {
1752 ret = _gnutls_privkey_import_system_url(key, url);
1753 goto cleanup;
1754 }
1755
1756 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1757 cleanup:
1758 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 **/
gnutls_privkey_set_pin_function(gnutls_privkey_t key,gnutls_pin_callback_t fn,void * userdata)1777 void gnutls_privkey_set_pin_function(gnutls_privkey_t key,
1778 gnutls_pin_callback_t fn, void *userdata)
1779 {
1780 key->pin.cb = fn;
1781 key->pin.data = userdata;
1782 }
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 **/
gnutls_privkey_set_flags(gnutls_privkey_t key,unsigned int flags)1796 void gnutls_privkey_set_flags(gnutls_privkey_t key,
1797 unsigned int flags)
1798 {
1799 key->flags |= flags;
1800 if (key->type == GNUTLS_PRIVKEY_X509)
1801 gnutls_x509_privkey_set_flags(key->key.x509, flags);
1802 }
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 **/
gnutls_privkey_status(gnutls_privkey_t key)1819 int gnutls_privkey_status(gnutls_privkey_t key)
1820 {
1821 switch (key->type) {
1822 #ifdef ENABLE_PKCS11
1823 case GNUTLS_PRIVKEY_PKCS11:
1824 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 **/
gnutls_privkey_verify_params(gnutls_privkey_t key)1842 int gnutls_privkey_verify_params(gnutls_privkey_t key)
1843 {
1844 gnutls_pk_params_st params;
1845 int ret;
1846
1847 gnutls_pk_params_init(¶ms);
1848
1849 ret = _gnutls_privkey_get_mpis(key, ¶ms);
1850 if (ret < 0)
1851 return gnutls_assert_val(ret);
1852
1853 ret = _gnutls_pk_verify_priv_params(key->pk_algorithm, ¶ms);
1854
1855 gnutls_pk_params_release(¶ms);
1856
1857 if (ret < 0) {
1858 gnutls_assert();
1859 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
gnutls_privkey_get_spki(gnutls_privkey_t privkey,gnutls_x509_spki_t spki,unsigned int flags)1880 gnutls_privkey_get_spki(gnutls_privkey_t privkey, gnutls_x509_spki_t spki, unsigned int flags)
1881 {
1882 if (privkey == NULL || privkey->type != GNUTLS_PRIVKEY_X509) {
1883 gnutls_assert();
1884 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1885 }
1886
1887 if (privkey->key.x509->params.spki.pk == GNUTLS_PK_UNKNOWN)
1888 return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1889
1890 memcpy(spki, &privkey->key.x509->params.spki, sizeof(gnutls_x509_spki_st));
1891
1892 return 0;
1893 }
1894
1895 /**
1896 * gnutls_privkey_set_spki:
1897 * @privkey: a public key of type #gnutls_privkey_t
1898 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_privkey_spki_t
1899 * @flags: must be zero
1900 *
1901 * This function will set the public key information.
1902 * The provided @spki must be initialized.
1903 *
1904 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1905 * negative error value.
1906 *
1907 * Since: 3.6.0
1908 **/
1909 int
gnutls_privkey_set_spki(gnutls_privkey_t privkey,const gnutls_x509_spki_t spki,unsigned int flags)1910 gnutls_privkey_set_spki(gnutls_privkey_t privkey, const gnutls_x509_spki_t spki, unsigned int flags)
1911 {
1912 if (privkey == NULL || privkey->type != GNUTLS_PRIVKEY_X509) {
1913 gnutls_assert();
1914 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1915 }
1916
1917 return gnutls_x509_privkey_set_spki(privkey->key.x509, spki, flags);
1918 }
1919
1920 /* Checks whether the public key given is compatible with the
1921 * signature algorithm used. The session is only used for audit logging, and
1922 * it may be null.
1923 */
_gnutls_privkey_compatible_with_sig(gnutls_privkey_t privkey,gnutls_sign_algorithm_t sign)1924 unsigned _gnutls_privkey_compatible_with_sig(gnutls_privkey_t privkey,
1925 gnutls_sign_algorithm_t sign)
1926 {
1927 const gnutls_sign_entry_st *se;
1928
1929 se = _gnutls_sign_to_entry(sign);
1930 if (unlikely(se == NULL))
1931 return gnutls_assert_val(0);
1932
1933 /* Prevent RSA-PSS private keys from negotiating an RSA signature,
1934 * and RSA keys which cannot do RSA-PSS (e.g., smart card) from
1935 * negotiating RSA-PSS sig.
1936 */
1937
1938 if (se->pk != privkey->pk_algorithm) { /* if the PK algorithm of the signature differs to the one on the pubkey */
1939 if (!sign_supports_priv_pk_algorithm(se, privkey->pk_algorithm)) {
1940 _gnutls_handshake_log("cannot use privkey of %s with %s\n",
1941 gnutls_pk_get_name(privkey->pk_algorithm), se->name);
1942 return 0;
1943 }
1944 }
1945
1946 if (privkey->type == GNUTLS_PRIVKEY_EXT) {
1947 if (privkey->key.ext.info_func) {
1948 int ret;
1949
1950 ret = privkey->key.ext.info_func(privkey,
1951 GNUTLS_SIGN_ALGO_TO_FLAGS(sign)|GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO,
1952 privkey->key.ext.userdata);
1953 if (ret != -1)
1954 return ret;
1955
1956 /* use the old flag */
1957 ret = privkey->key.ext.info_func(privkey, GNUTLS_PRIVKEY_INFO_SIGN_ALGO,
1958 privkey->key.ext.userdata);
1959 if (ret == (int)sign)
1960 return 1;
1961 }
1962
1963 /* This key type is very limited on what it can handle */
1964 if (!PK_IS_OK_FOR_EXT2(se->pk))
1965 return gnutls_assert_val(0);
1966 }
1967 #ifdef ENABLE_PKCS11
1968 else if (privkey->type == GNUTLS_PRIVKEY_PKCS11) {
1969 if (privkey->pk_algorithm == GNUTLS_PK_RSA && se->pk == GNUTLS_PK_RSA_PSS) {
1970 if (!privkey->key.pkcs11->rsa_pss_ok)
1971 return 0;
1972 }
1973 }
1974 #endif
1975
1976 return 1;
1977 }
1978