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, &params);
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, &params);
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, &params);
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, &params);
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, &params);
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, &params);
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, &params);
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, &params);
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, &params);
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, &params);
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, &params);
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, &params);
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(&params);
1848 
1849 	ret = _gnutls_privkey_get_mpis(key, &params);
1850 	if (ret < 0)
1851 		return gnutls_assert_val(ret);
1852 
1853 	ret = _gnutls_pk_verify_priv_params(key->pk_algorithm, &params);
1854 
1855 	gnutls_pk_params_release(&params);
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