1 /*
2  * GnuTLS public key support
3  * Copyright (C) 2010-2012 Free Software Foundation, Inc.
4  * Copyright (C) 2017 Red Hat, Inc.
5  *
6  * Author: Nikos Mavrogiannopoulos
7  *
8  * The GnuTLS is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>
20  */
21 
22 #include "gnutls_int.h"
23 #include <gnutls/pkcs11.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include "errors.h"
27 #include <datum.h>
28 #include <pkcs11_int.h>
29 #include <gnutls/abstract.h>
30 #include <tls-sig.h>
31 #include <pk.h>
32 #include <x509_int.h>
33 #include <num.h>
34 #include <x509/common.h>
35 #include <x509_b64.h>
36 #include <abstract_int.h>
37 #include <fips.h>
38 #include "urls.h"
39 #include <ecc.h>
40 
41 static int
42 pubkey_verify_hashed_data(const gnutls_sign_entry_st *se,
43 			  const mac_entry_st *me,
44 			  const gnutls_datum_t * hash,
45 			  const gnutls_datum_t * signature,
46 			  gnutls_pk_params_st * params,
47 			  gnutls_x509_spki_st * sign_params,
48 			  unsigned flags);
49 
50 static
51 int pubkey_supports_sig(gnutls_pubkey_t pubkey,
52 			const gnutls_sign_entry_st *se);
53 
pubkey_to_bits(const gnutls_pk_params_st * params)54 unsigned pubkey_to_bits(const gnutls_pk_params_st * params)
55 {
56 	switch (params->algo) {
57 	case GNUTLS_PK_RSA:
58 	case GNUTLS_PK_RSA_PSS:
59 		return _gnutls_mpi_get_nbits(params->params[RSA_MODULUS]);
60 	case GNUTLS_PK_DSA:
61 		return _gnutls_mpi_get_nbits(params->params[DSA_P]);
62 	case GNUTLS_PK_ECDSA:
63 	case GNUTLS_PK_EDDSA_ED25519:
64 	case GNUTLS_PK_EDDSA_ED448:
65 	case GNUTLS_PK_GOST_01:
66 	case GNUTLS_PK_GOST_12_256:
67 	case GNUTLS_PK_GOST_12_512:
68 		return gnutls_ecc_curve_get_size(params->curve) * 8;
69 	default:
70 		return 0;
71 	}
72 }
73 
74 /**
75  * gnutls_pubkey_get_pk_algorithm:
76  * @key: should contain a #gnutls_pubkey_t type
77  * @bits: If set will return the number of bits of the parameters (may be NULL)
78  *
79  * This function will return the public key algorithm of a public
80  * key and if possible will return a number of bits that indicates
81  * the security parameter of the key.
82  *
83  * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
84  *   success, or a negative error code on error.
85  *
86  * Since: 2.12.0
87  **/
gnutls_pubkey_get_pk_algorithm(gnutls_pubkey_t key,unsigned int * bits)88 int gnutls_pubkey_get_pk_algorithm(gnutls_pubkey_t key, unsigned int *bits)
89 {
90 	if (bits)
91 		*bits = key->bits;
92 
93 	return key->params.algo;
94 }
95 
96 /**
97  * gnutls_pubkey_get_key_usage:
98  * @key: should contain a #gnutls_pubkey_t type
99  * @usage: If set will return the number of bits of the parameters (may be NULL)
100  *
101  * This function will return the key usage of the public key.
102  *
103  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
104  *   negative error value.
105  *
106  * Since: 2.12.0
107  **/
gnutls_pubkey_get_key_usage(gnutls_pubkey_t key,unsigned int * usage)108 int gnutls_pubkey_get_key_usage(gnutls_pubkey_t key, unsigned int *usage)
109 {
110 	if (usage)
111 		*usage = key->key_usage;
112 
113 	return 0;
114 }
115 
116 /**
117  * gnutls_pubkey_init:
118  * @key: A pointer to the type to be initialized
119  *
120  * This function will initialize a public key.
121  *
122  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
123  *   negative error value.
124  *
125  * Since: 2.12.0
126  **/
gnutls_pubkey_init(gnutls_pubkey_t * key)127 int gnutls_pubkey_init(gnutls_pubkey_t * key)
128 {
129 	FAIL_IF_LIB_ERROR;
130 
131 	*key = gnutls_calloc(1, sizeof(struct gnutls_pubkey_st));
132 	if (*key == NULL) {
133 		gnutls_assert();
134 		return GNUTLS_E_MEMORY_ERROR;
135 	}
136 
137 	return 0;
138 }
139 
140 /**
141  * gnutls_pubkey_deinit:
142  * @key: The key to be deinitialized
143  *
144  * This function will deinitialize a public key structure.
145  *
146  * Since: 2.12.0
147  **/
gnutls_pubkey_deinit(gnutls_pubkey_t key)148 void gnutls_pubkey_deinit(gnutls_pubkey_t key)
149 {
150 	if (!key)
151 		return;
152 	gnutls_pk_params_release(&key->params);
153 	gnutls_free(key);
154 }
155 
156 /**
157  * gnutls_pubkey_import_x509:
158  * @key: The public key
159  * @crt: The certificate to be imported
160  * @flags: should be zero
161  *
162  * This function will import the given public key to the abstract
163  * #gnutls_pubkey_t type.
164  *
165  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
166  *   negative error value.
167  *
168  * Since: 2.12.0
169  **/
170 int
gnutls_pubkey_import_x509(gnutls_pubkey_t key,gnutls_x509_crt_t crt,unsigned int flags)171 gnutls_pubkey_import_x509(gnutls_pubkey_t key, gnutls_x509_crt_t crt,
172 			  unsigned int flags)
173 {
174 	int ret;
175 
176 	gnutls_pk_params_release(&key->params);
177 	/* params initialized in _gnutls_x509_crt_get_mpis */
178 
179 	ret = gnutls_x509_crt_get_pk_algorithm(crt, &key->bits);
180 	if (ret < 0)
181 		return gnutls_assert_val(ret);
182 
183 	key->params.algo = ret;
184 
185 	ret = gnutls_x509_crt_get_key_usage(crt, &key->key_usage, NULL);
186 	if (ret < 0)
187 		key->key_usage = 0;
188 
189 	ret = _gnutls_x509_crt_get_mpis(crt, &key->params);
190 	if (ret < 0) {
191 		gnutls_assert();
192 		return ret;
193 	}
194 
195 	return 0;
196 }
197 
198 /**
199  * gnutls_pubkey_import_x509_crq:
200  * @key: The public key
201  * @crq: The certificate to be imported
202  * @flags: should be zero
203  *
204  * This function will import the given public key to the abstract
205  * #gnutls_pubkey_t type.
206  *
207  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
208  *   negative error value.
209  *
210  * Since: 3.1.5
211  **/
212 int
gnutls_pubkey_import_x509_crq(gnutls_pubkey_t key,gnutls_x509_crq_t crq,unsigned int flags)213 gnutls_pubkey_import_x509_crq(gnutls_pubkey_t key, gnutls_x509_crq_t crq,
214 			      unsigned int flags)
215 {
216 	int ret;
217 
218 	gnutls_pk_params_release(&key->params);
219 	/* params initialized in _gnutls_x509_crq_get_mpis */
220 
221 	key->params.algo = gnutls_x509_crq_get_pk_algorithm(crq, &key->bits);
222 
223 	ret = gnutls_x509_crq_get_key_usage(crq, &key->key_usage, NULL);
224 	if (ret < 0)
225 		key->key_usage = 0;
226 
227 	ret = _gnutls_x509_crq_get_mpis(crq, &key->params);
228 	if (ret < 0) {
229 		gnutls_assert();
230 		return ret;
231 	}
232 
233 	return 0;
234 }
235 
236 /**
237  * gnutls_pubkey_import_privkey:
238  * @key: The public key
239  * @pkey: The private key
240  * @usage: GNUTLS_KEY_* key usage flags.
241  * @flags: should be zero
242  *
243  * Imports the public key from a private.  This function will import
244  * the given public key to the abstract #gnutls_pubkey_t type.
245  *
246  * Note that in certain keys this operation may not be possible, e.g.,
247  * in other than RSA PKCS#11 keys.
248  *
249  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
250  *   negative error value.
251  *
252  * Since: 2.12.0
253  **/
254 int
gnutls_pubkey_import_privkey(gnutls_pubkey_t key,gnutls_privkey_t pkey,unsigned int usage,unsigned int flags)255 gnutls_pubkey_import_privkey(gnutls_pubkey_t key, gnutls_privkey_t pkey,
256 			     unsigned int usage, unsigned int flags)
257 {
258 	gnutls_pk_params_release(&key->params);
259 	gnutls_pk_params_init(&key->params);
260 
261 	key->key_usage = usage;
262 	key->params.algo = gnutls_privkey_get_pk_algorithm(pkey, &key->bits);
263 
264 	return _gnutls_privkey_get_public_mpis(pkey, &key->params);
265 }
266 
267 /**
268  * gnutls_pubkey_get_preferred_hash_algorithm:
269  * @key: Holds the certificate
270  * @hash: The result of the call with the hash algorithm used for signature
271  * @mand: If non zero it means that the algorithm MUST use this hash. May be NULL.
272  *
273  * This function will read the certificate and return the appropriate digest
274  * algorithm to use for signing with this certificate. Some certificates (i.e.
275  * DSA might not be able to sign without the preferred algorithm).
276  *
277  * To get the signature algorithm instead of just the hash use gnutls_pk_to_sign()
278  * with the algorithm of the certificate/key and the provided @hash.
279  *
280  * Returns: the 0 if the hash algorithm is found. A negative error code is
281  * returned on error.
282  *
283  * Since: 2.12.0
284  **/
285 int
gnutls_pubkey_get_preferred_hash_algorithm(gnutls_pubkey_t key,gnutls_digest_algorithm_t * hash,unsigned int * mand)286 gnutls_pubkey_get_preferred_hash_algorithm(gnutls_pubkey_t key,
287 					   gnutls_digest_algorithm_t *
288 					   hash, unsigned int *mand)
289 {
290 	int ret;
291 	const mac_entry_st *me;
292 
293 	if (key == NULL) {
294 		gnutls_assert();
295 		return GNUTLS_E_INVALID_REQUEST;
296 	}
297 
298 	if (mand)
299 		*mand = 0;
300 
301 	switch (key->params.algo) {
302 	case GNUTLS_PK_DSA:
303 		if (mand)
304 			*mand = 1;
305 		FALLTHROUGH;
306 	case GNUTLS_PK_ECDSA:
307 
308 		me = _gnutls_dsa_q_to_hash(&key->params, NULL);
309 		if (hash)
310 			*hash = (gnutls_digest_algorithm_t)me->id;
311 
312 		ret = 0;
313 		break;
314 	case GNUTLS_PK_EDDSA_ED25519:
315 		if (hash)
316 			*hash = GNUTLS_DIG_SHA512;
317 
318 		ret = 0;
319 		break;
320 	case GNUTLS_PK_EDDSA_ED448:
321 		if (hash)
322 			*hash = GNUTLS_DIG_SHAKE_256;
323 
324 		ret = 0;
325 		break;
326 	case GNUTLS_PK_GOST_01:
327 	case GNUTLS_PK_GOST_12_256:
328 	case GNUTLS_PK_GOST_12_512:
329 		if (hash)
330 			*hash = _gnutls_gost_digest(key->params.algo);
331 		if (mand)
332 			*mand = 1;
333 
334 		ret = 0;
335 		break;
336 	case GNUTLS_PK_RSA_PSS:
337 		if (mand && key->params.spki.rsa_pss_dig)
338 			*mand = 1;
339 
340 		if (hash) {
341 			if (key->params.spki.rsa_pss_dig) {
342 				*hash = key->params.spki.rsa_pss_dig;
343 			} else {
344 				*hash = _gnutls_pk_bits_to_sha_hash(pubkey_to_bits(&key->params));
345 			}
346 		}
347 		ret = 0;
348 		break;
349 	case GNUTLS_PK_RSA:
350 		if (hash)
351 			*hash = _gnutls_pk_bits_to_sha_hash(pubkey_to_bits(&key->params));
352 		ret = 0;
353 		break;
354 
355 	default:
356 		gnutls_assert();
357 		ret = GNUTLS_E_INTERNAL_ERROR;
358 	}
359 
360 	return ret;
361 }
362 
363 #ifdef ENABLE_PKCS11
364 
365 /* The EC_PARAMS attribute can contain either printable string with curve name
366  * or OID defined in RFC 8410 */
367 static int
gnutls_pubkey_parse_ecc_eddsa_params(const gnutls_datum_t * parameters,gnutls_ecc_curve_t * outcurve)368 gnutls_pubkey_parse_ecc_eddsa_params(const gnutls_datum_t *parameters,
369 				     gnutls_ecc_curve_t *outcurve)
370 {
371 	gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
372 	ASN1_TYPE asn1 = ASN1_TYPE_EMPTY;
373 	unsigned int etype = ASN1_ETYPE_INVALID;
374 	char str[MAX_OID_SIZE];
375 	int str_size;
376 	int ret;
377 
378 	ret = asn1_create_element(_gnutls_get_gnutls_asn(),
379 				  "GNUTLS.pkcs-11-ec-Parameters", &asn1);
380 	if (ret != ASN1_SUCCESS) {
381 		gnutls_assert();
382 		return _gnutls_asn2err(ret);
383 	}
384 
385 	ret = asn1_der_decoding(&asn1, parameters->data, parameters->size,
386 				NULL);
387 	if (ret != ASN1_SUCCESS) {
388 		gnutls_assert();
389 		ret = _gnutls_asn2err(ret);
390 		goto cleanup;
391 	}
392 
393 	/* Read the type of choice.
394 	 */
395 	str_size = sizeof(str) - 1;
396 	ret = asn1_read_value(asn1, "", str, &str_size);
397 	if (ret != ASN1_SUCCESS) {
398 		gnutls_assert();
399 		ret = _gnutls_asn2err(ret);
400 		goto cleanup;
401 	}
402 	str[str_size] = 0;
403 
404 	/* Convert the choice to enum type */
405 	if (strcmp(str, "oId") == 0) {
406 		etype = ASN1_ETYPE_OBJECT_ID;
407 	} else if (strcmp(str, "curveName") == 0) {
408 		etype = ASN1_ETYPE_PRINTABLE_STRING;
409 	}
410 
411 	str_size = sizeof(str) - 1;
412 	switch (etype) {
413 	case ASN1_ETYPE_OBJECT_ID:
414 		ret = asn1_read_value(asn1, "oId", str, &str_size);
415 		if (ret != ASN1_SUCCESS) {
416 			gnutls_assert();
417 			ret = _gnutls_asn2err(ret);
418 			break;
419 		}
420 
421 		curve = gnutls_oid_to_ecc_curve(str);
422 		if (curve != GNUTLS_ECC_CURVE_ED25519 &&
423 		    curve != GNUTLS_ECC_CURVE_ED448) {
424 			_gnutls_debug_log("Curve %s is not supported for EdDSA\n", str);
425 			gnutls_assert();
426 			curve = GNUTLS_ECC_CURVE_INVALID;
427 			ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
428 			break;
429 		}
430 
431 		ret = GNUTLS_E_SUCCESS;
432 		break;
433 
434 	case ASN1_ETYPE_PRINTABLE_STRING:
435 		ret = asn1_read_value(asn1, "curveName", str, &str_size);
436 		if (ret != ASN1_SUCCESS) {
437 			gnutls_assert();
438 			ret = _gnutls_asn2err(ret);
439 			break;
440 		}
441 
442 		if (str_size == strlen("edwards25519") &&
443 		    strncmp(str, "edwards25519", str_size) == 0) {
444 			curve = GNUTLS_ECC_CURVE_ED25519;
445 			ret = GNUTLS_E_SUCCESS;
446 			break;
447 		} else if (str_size == strlen("edwards448") &&
448 			   strncmp(str, "edwards448", str_size) == 0) {
449 			curve = GNUTLS_ECC_CURVE_ED448;
450 			ret = GNUTLS_E_SUCCESS;
451 			break;
452 		}
453 		/* FALLTHROUGH */
454 
455 	default:
456 		/* Neither of CHOICEs found. Fail */
457 		gnutls_assert();
458 		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
459 		curve = GNUTLS_ECC_CURVE_INVALID;
460 		break;
461 	}
462 
463 
464       cleanup:
465 	asn1_delete_structure(&asn1);
466 	*outcurve = curve;
467 	return ret;
468 }
469 
470 
471 static int
gnutls_pubkey_import_ecc_eddsa(gnutls_pubkey_t key,const gnutls_datum_t * parameters,const gnutls_datum_t * ecpoint)472 gnutls_pubkey_import_ecc_eddsa(gnutls_pubkey_t key,
473 			       const gnutls_datum_t * parameters,
474 			       const gnutls_datum_t * ecpoint)
475 {
476 	int ret;
477 
478 	gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID;
479 	gnutls_datum_t raw_point = {NULL, 0};
480 
481 	ret = gnutls_pubkey_parse_ecc_eddsa_params(parameters, &curve);
482 	if (ret < 0) {
483 		return gnutls_assert_val(ret);
484 	}
485 
486 	ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING,
487 					 ecpoint->data, ecpoint->size,
488 					 &raw_point, 0);
489 	if (ret < 0) {
490 		gnutls_assert();
491 		gnutls_free(raw_point.data);
492 		return ret;
493 	}
494 	ret = gnutls_pubkey_import_ecc_raw(key, curve, &raw_point, NULL);
495 
496 	gnutls_free(raw_point.data);
497 	return ret;
498 }
499 
500 /**
501  * gnutls_pubkey_import_pkcs11:
502  * @key: The public key
503  * @obj: The parameters to be imported
504  * @flags: should be zero
505  *
506  * Imports a public key from a pkcs11 key. This function will import
507  * the given public key to the abstract #gnutls_pubkey_t type.
508  *
509  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
510  *   negative error value.
511  *
512  * Since: 2.12.0
513  **/
514 int
gnutls_pubkey_import_pkcs11(gnutls_pubkey_t key,gnutls_pkcs11_obj_t obj,unsigned int flags)515 gnutls_pubkey_import_pkcs11(gnutls_pubkey_t key,
516 			    gnutls_pkcs11_obj_t obj, unsigned int flags)
517 {
518 	int ret, type;
519 
520 	type = gnutls_pkcs11_obj_get_type(obj);
521 	if (type != GNUTLS_PKCS11_OBJ_PUBKEY
522 	    && type != GNUTLS_PKCS11_OBJ_X509_CRT) {
523 		gnutls_assert();
524 		return GNUTLS_E_INVALID_REQUEST;
525 	}
526 
527 	if (type == GNUTLS_PKCS11_OBJ_X509_CRT) {
528 		gnutls_x509_crt_t xcrt;
529 
530 		ret = gnutls_x509_crt_init(&xcrt);
531 		if (ret < 0) {
532 			gnutls_assert()
533 			    return ret;
534 		}
535 
536 		ret = gnutls_x509_crt_import_pkcs11(xcrt, obj);
537 		if (ret < 0) {
538 			gnutls_assert();
539 			goto cleanup_crt;
540 		}
541 
542 		ret = gnutls_pubkey_import_x509(key, xcrt, 0);
543 		if (ret < 0) {
544 			gnutls_assert();
545 			goto cleanup_crt;
546 		}
547 
548 		ret = gnutls_x509_crt_get_key_usage(xcrt, &key->key_usage, NULL);
549 		if (ret < 0)
550 		  key->key_usage = 0;
551 
552 		ret = 0;
553 	      cleanup_crt:
554 		gnutls_x509_crt_deinit(xcrt);
555 		return ret;
556 	}
557 
558 	key->key_usage = obj->key_usage;
559 
560 	switch (obj->pk_algorithm) {
561 	case GNUTLS_PK_RSA:
562 	case GNUTLS_PK_RSA_PSS:
563 		ret = gnutls_pubkey_import_rsa_raw(key, &obj->pubkey[0],
564 						   &obj->pubkey[1]);
565 		break;
566 	case GNUTLS_PK_DSA:
567 		ret = gnutls_pubkey_import_dsa_raw(key, &obj->pubkey[0],
568 						   &obj->pubkey[1],
569 						   &obj->pubkey[2],
570 						   &obj->pubkey[3]);
571 		break;
572 	case GNUTLS_PK_EC:
573 		ret = gnutls_pubkey_import_ecc_x962(key, &obj->pubkey[0],
574 						    &obj->pubkey[1]);
575 		break;
576 	case GNUTLS_PK_EDDSA_ED25519:
577 		ret = gnutls_pubkey_import_ecc_eddsa(key, &obj->pubkey[0],
578 						     &obj->pubkey[1]);
579 		break;
580 	default:
581 		gnutls_assert();
582 		return GNUTLS_E_UNIMPLEMENTED_FEATURE;
583 	}
584 
585 	if (ret < 0) {
586 		gnutls_assert();
587 		return ret;
588 	}
589 
590 	return 0;
591 }
592 
593 #endif				/* ENABLE_PKCS11 */
594 
595 /**
596  * gnutls_pubkey_export:
597  * @key: Holds the certificate
598  * @format: the format of output params. One of PEM or DER.
599  * @output_data: will contain a certificate PEM or DER encoded
600  * @output_data_size: holds the size of output_data (and will be
601  *   replaced by the actual size of parameters)
602  *
603  * This function will export the public key to DER or PEM format.
604  * The contents of the exported data is the SubjectPublicKeyInfo
605  * X.509 structure.
606  *
607  * If the buffer provided is not long enough to hold the output, then
608  * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
609  * be returned.
610  *
611  * If the structure is PEM encoded, it will have a header
612  * of "BEGIN CERTIFICATE".
613  *
614  * Returns: In case of failure a negative error code will be
615  *   returned, and 0 on success.
616  *
617  * Since: 2.12.0
618  **/
619 int
gnutls_pubkey_export(gnutls_pubkey_t key,gnutls_x509_crt_fmt_t format,void * output_data,size_t * output_data_size)620 gnutls_pubkey_export(gnutls_pubkey_t key,
621 		     gnutls_x509_crt_fmt_t format, void *output_data,
622 		     size_t * output_data_size)
623 {
624 	int result;
625 	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
626 
627 	if (key == NULL) {
628 		gnutls_assert();
629 		return GNUTLS_E_INVALID_REQUEST;
630 	}
631 
632 	if ((result = asn1_create_element
633 	     (_gnutls_get_pkix(), "PKIX1.SubjectPublicKeyInfo", &spk))
634 	    != ASN1_SUCCESS) {
635 		gnutls_assert();
636 		return _gnutls_asn2err(result);
637 	}
638 
639 	result =
640 	    _gnutls_x509_encode_and_copy_PKI_params(spk, "",
641 						    &key->params);
642 	if (result < 0) {
643 		gnutls_assert();
644 		goto cleanup;
645 	}
646 
647 	result = _gnutls_x509_export_int_named(spk, "",
648 					       format, PEM_PK,
649 					       output_data,
650 					       output_data_size);
651 	if (result < 0) {
652 		gnutls_assert();
653 		goto cleanup;
654 	}
655 
656 	result = 0;
657 
658       cleanup:
659 	asn1_delete_structure(&spk);
660 
661 	return result;
662 }
663 
664 /**
665  * gnutls_pubkey_export2:
666  * @key: Holds the certificate
667  * @format: the format of output params. One of PEM or DER.
668  * @out: will contain a certificate PEM or DER encoded
669  *
670  * This function will export the public key to DER or PEM format.
671  * The contents of the exported data is the SubjectPublicKeyInfo
672  * X.509 structure.
673  *
674  * The output buffer will be allocated using gnutls_malloc().
675  *
676  * If the structure is PEM encoded, it will have a header
677  * of "BEGIN CERTIFICATE".
678  *
679  * Returns: In case of failure a negative error code will be
680  *   returned, and 0 on success.
681  *
682  * Since: 3.1.3
683  **/
684 int
gnutls_pubkey_export2(gnutls_pubkey_t key,gnutls_x509_crt_fmt_t format,gnutls_datum_t * out)685 gnutls_pubkey_export2(gnutls_pubkey_t key,
686 		      gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
687 {
688 	int result;
689 	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
690 
691 	if (key == NULL) {
692 		gnutls_assert();
693 		return GNUTLS_E_INVALID_REQUEST;
694 	}
695 
696 	if ((result = asn1_create_element
697 	     (_gnutls_get_pkix(), "PKIX1.SubjectPublicKeyInfo", &spk))
698 	    != ASN1_SUCCESS) {
699 		gnutls_assert();
700 		return _gnutls_asn2err(result);
701 	}
702 
703 	result =
704 	    _gnutls_x509_encode_and_copy_PKI_params(spk, "",
705 						    &key->params);
706 	if (result < 0) {
707 		gnutls_assert();
708 		goto cleanup;
709 	}
710 
711 	result = _gnutls_x509_export_int_named2(spk, "",
712 						format, PEM_PK,
713 						out);
714 	if (result < 0) {
715 		gnutls_assert();
716 		goto cleanup;
717 	}
718 
719 	result = 0;
720 
721       cleanup:
722 	asn1_delete_structure(&spk);
723 
724 	return result;
725 }
726 
727 /**
728  * gnutls_pubkey_get_key_id:
729  * @key: Holds the public key
730  * @flags: should be one of the flags from %gnutls_keyid_flags_t
731  * @output_data: will contain the key ID
732  * @output_data_size: holds the size of output_data (and will be
733  *   replaced by the actual size of parameters)
734  *
735  * This function will return a unique ID that depends on the public
736  * key parameters. This ID can be used in checking whether a
737  * certificate corresponds to the given public key.
738  *
739  * If the buffer provided is not long enough to hold the output, then
740  * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will
741  * be returned.  The output will normally be a SHA-1 hash output,
742  * which is 20 bytes.
743  *
744  * Returns: In case of failure a negative error code will be
745  *   returned, and 0 on success.
746  *
747  * Since: 2.12.0
748  **/
749 int
gnutls_pubkey_get_key_id(gnutls_pubkey_t key,unsigned int flags,unsigned char * output_data,size_t * output_data_size)750 gnutls_pubkey_get_key_id(gnutls_pubkey_t key, unsigned int flags,
751 			 unsigned char *output_data,
752 			 size_t * output_data_size)
753 {
754 	int ret = 0;
755 
756 	if (key == NULL) {
757 		gnutls_assert();
758 		return GNUTLS_E_INVALID_REQUEST;
759 	}
760 
761 	ret =
762 	    _gnutls_get_key_id(&key->params,
763 			       output_data, output_data_size, flags);
764 	if (ret < 0) {
765 		gnutls_assert();
766 		return ret;
767 	}
768 
769 	return 0;
770 }
771 
772 /**
773  * gnutls_pubkey_export_rsa_raw2:
774  * @key: Holds the certificate
775  * @m: will hold the modulus (may be %NULL)
776  * @e: will hold the public exponent (may be %NULL)
777  * @flags: flags from %gnutls_abstract_export_flags_t
778  *
779  * This function will export the RSA public key's parameters found in
780  * the given structure.  The new parameters will be allocated using
781  * gnutls_malloc() and will be stored in the appropriate datum.
782  *
783  * This function allows for %NULL parameters since 3.4.1.
784  *
785  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
786  *
787  * Since: 3.6.0
788  **/
789 int
gnutls_pubkey_export_rsa_raw2(gnutls_pubkey_t key,gnutls_datum_t * m,gnutls_datum_t * e,unsigned flags)790 gnutls_pubkey_export_rsa_raw2(gnutls_pubkey_t key,
791 			     gnutls_datum_t * m, gnutls_datum_t * e,
792 			     unsigned flags)
793 {
794 	int ret;
795 	mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
796 
797 	if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
798 		dprint = _gnutls_mpi_dprint;
799 
800 	if (key == NULL) {
801 		gnutls_assert();
802 		return GNUTLS_E_INVALID_REQUEST;
803 	}
804 
805 	if (!GNUTLS_PK_IS_RSA(key->params.algo)) {
806 		gnutls_assert();
807 		return GNUTLS_E_INVALID_REQUEST;
808 	}
809 
810 	if (m) {
811 		ret = dprint(key->params.params[0], m);
812 		if (ret < 0) {
813 			gnutls_assert();
814 			return ret;
815 		}
816 	}
817 
818 	if (e) {
819 		ret = dprint(key->params.params[1], e);
820 		if (ret < 0) {
821 			gnutls_assert();
822 			_gnutls_free_datum(m);
823 			return ret;
824 		}
825 	}
826 
827 	return 0;
828 }
829 
830 /**
831  * gnutls_pubkey_export_rsa_raw:
832  * @key: Holds the certificate
833  * @m: will hold the modulus (may be %NULL)
834  * @e: will hold the public exponent (may be %NULL)
835  *
836  * This function will export the RSA public key's parameters found in
837  * the given structure.  The new parameters will be allocated using
838  * gnutls_malloc() and will be stored in the appropriate datum.
839  *
840  * This function allows for %NULL parameters since 3.4.1.
841  *
842  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
843  *
844  * Since: 3.3.0
845  **/
846 int
gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key,gnutls_datum_t * m,gnutls_datum_t * e)847 gnutls_pubkey_export_rsa_raw(gnutls_pubkey_t key,
848 			     gnutls_datum_t * m, gnutls_datum_t * e)
849 {
850 	return gnutls_pubkey_export_rsa_raw2(key, m, e, 0);
851 }
852 
853 
854 /**
855  * gnutls_pubkey_export_dsa_raw:
856  * @key: Holds the public key
857  * @p: will hold the p (may be %NULL)
858  * @q: will hold the q (may be %NULL)
859  * @g: will hold the g (may be %NULL)
860  * @y: will hold the y (may be %NULL)
861  *
862  * This function will export the DSA public key's parameters found in
863  * the given certificate.  The new parameters will be allocated using
864  * gnutls_malloc() and will be stored in the appropriate datum.
865  *
866  * This function allows for %NULL parameters since 3.4.1.
867  *
868  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
869  *
870  * Since: 3.3.0
871  **/
872 int
gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key,gnutls_datum_t * p,gnutls_datum_t * q,gnutls_datum_t * g,gnutls_datum_t * y)873 gnutls_pubkey_export_dsa_raw(gnutls_pubkey_t key,
874 			     gnutls_datum_t * p, gnutls_datum_t * q,
875 			     gnutls_datum_t * g, gnutls_datum_t * y)
876 {
877 	return gnutls_pubkey_export_dsa_raw2(key, p, q, g, y, 0);
878 }
879 
880 /**
881  * gnutls_pubkey_export_dsa_raw2:
882  * @key: Holds the public key
883  * @p: will hold the p (may be %NULL)
884  * @q: will hold the q (may be %NULL)
885  * @g: will hold the g (may be %NULL)
886  * @y: will hold the y (may be %NULL)
887  * @flags: flags from %gnutls_abstract_export_flags_t
888  *
889  * This function will export the DSA public key's parameters found in
890  * the given certificate.  The new parameters will be allocated using
891  * gnutls_malloc() and will be stored in the appropriate datum.
892  *
893  * This function allows for %NULL parameters since 3.4.1.
894  *
895  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
896  *
897  * Since: 3.6.0
898  **/
899 int
gnutls_pubkey_export_dsa_raw2(gnutls_pubkey_t key,gnutls_datum_t * p,gnutls_datum_t * q,gnutls_datum_t * g,gnutls_datum_t * y,unsigned flags)900 gnutls_pubkey_export_dsa_raw2(gnutls_pubkey_t key,
901 			     gnutls_datum_t * p, gnutls_datum_t * q,
902 			     gnutls_datum_t * g, gnutls_datum_t * y,
903 			     unsigned flags)
904 {
905 	int ret;
906 	mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
907 
908 	if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
909 		dprint = _gnutls_mpi_dprint;
910 
911 	if (key == NULL) {
912 		gnutls_assert();
913 		return GNUTLS_E_INVALID_REQUEST;
914 	}
915 
916 	if (key->params.algo != GNUTLS_PK_DSA) {
917 		gnutls_assert();
918 		return GNUTLS_E_INVALID_REQUEST;
919 	}
920 
921 	/* P */
922 	if (p) {
923 		ret = dprint(key->params.params[0], p);
924 		if (ret < 0) {
925 			gnutls_assert();
926 			return ret;
927 		}
928 	}
929 
930 	/* Q */
931 	if (q) {
932 		ret = dprint(key->params.params[1], q);
933 		if (ret < 0) {
934 			gnutls_assert();
935 			_gnutls_free_datum(p);
936 			return ret;
937 		}
938 	}
939 
940 	/* G */
941 	if (g) {
942 		ret = dprint(key->params.params[2], g);
943 		if (ret < 0) {
944 			gnutls_assert();
945 			_gnutls_free_datum(p);
946 			_gnutls_free_datum(q);
947 			return ret;
948 		}
949 	}
950 
951 	/* Y */
952 	if (y) {
953 		ret = dprint(key->params.params[3], y);
954 		if (ret < 0) {
955 			gnutls_assert();
956 			_gnutls_free_datum(p);
957 			_gnutls_free_datum(g);
958 			_gnutls_free_datum(q);
959 			return ret;
960 		}
961 	}
962 
963 	return 0;
964 }
965 
966 /**
967  * gnutls_pubkey_export_ecc_raw:
968  * @key: Holds the public key
969  * @curve: will hold the curve (may be %NULL)
970  * @x: will hold x-coordinate (may be %NULL)
971  * @y: will hold y-coordinate (may be %NULL)
972  *
973  * This function will export the ECC public key's parameters found in
974  * the given key.  The new parameters will be allocated using
975  * gnutls_malloc() and will be stored in the appropriate datum.
976  *
977  * In EdDSA curves the @y parameter will be %NULL and the other parameters
978  * will be in the native format for the curve.
979  *
980  * This function allows for %NULL parameters since 3.4.1.
981  *
982  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
983  *
984  * Since: 3.0
985  **/
986 int
gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key,gnutls_ecc_curve_t * curve,gnutls_datum_t * x,gnutls_datum_t * y)987 gnutls_pubkey_export_ecc_raw(gnutls_pubkey_t key,
988 			     gnutls_ecc_curve_t * curve,
989 			     gnutls_datum_t * x, gnutls_datum_t * y)
990 {
991 	return gnutls_pubkey_export_ecc_raw2(key, curve, x, y, 0);
992 }
993 
994 /**
995  * gnutls_pubkey_export_ecc_raw2:
996  * @key: Holds the public key
997  * @curve: will hold the curve (may be %NULL)
998  * @x: will hold x-coordinate (may be %NULL)
999  * @y: will hold y-coordinate (may be %NULL)
1000  * @flags: flags from %gnutls_abstract_export_flags_t
1001  *
1002  * This function will export the ECC public key's parameters found in
1003  * the given key.  The new parameters will be allocated using
1004  * gnutls_malloc() and will be stored in the appropriate datum.
1005  *
1006  * In EdDSA curves the @y parameter will be %NULL and the other parameters
1007  * will be in the native format for the curve.
1008  *
1009  * This function allows for %NULL parameters since 3.4.1.
1010  *
1011  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1012  *
1013  * Since: 3.6.0
1014  **/
1015 int
gnutls_pubkey_export_ecc_raw2(gnutls_pubkey_t key,gnutls_ecc_curve_t * curve,gnutls_datum_t * x,gnutls_datum_t * y,unsigned int flags)1016 gnutls_pubkey_export_ecc_raw2(gnutls_pubkey_t key,
1017 			     gnutls_ecc_curve_t * curve,
1018 			     gnutls_datum_t * x, gnutls_datum_t * y,
1019 			     unsigned int flags)
1020 {
1021 	int ret;
1022 	mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
1023 
1024 	if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
1025 		dprint = _gnutls_mpi_dprint;
1026 
1027 	if (key == NULL) {
1028 		gnutls_assert();
1029 		return GNUTLS_E_INVALID_REQUEST;
1030 	}
1031 
1032 	if (!IS_EC(key->params.algo)) {
1033 		gnutls_assert();
1034 		return GNUTLS_E_INVALID_REQUEST;
1035 	}
1036 
1037 	if (curve)
1038 		*curve = key->params.curve;
1039 
1040 	if (key->params.algo == GNUTLS_PK_EDDSA_ED25519 ||
1041 	    key->params.algo == GNUTLS_PK_EDDSA_ED448) {
1042 		if (x) {
1043 			ret = _gnutls_set_datum(x, key->params.raw_pub.data, key->params.raw_pub.size);
1044 			if (ret < 0)
1045 				return gnutls_assert_val(ret);
1046 		}
1047 		if (y) {
1048 			y->data = NULL;
1049 			y->size = 0;
1050 		}
1051 		return 0;
1052 	}
1053 
1054 	/* ECDSA */
1055 
1056 	/* X */
1057 	if (x) {
1058 		ret = dprint(key->params.params[ECC_X], x);
1059 		if (ret < 0) {
1060 			gnutls_assert();
1061 			return ret;
1062 		}
1063 	}
1064 
1065 	/* Y */
1066 	if (y) {
1067 		ret = dprint(key->params.params[ECC_Y], y);
1068 		if (ret < 0) {
1069 			gnutls_assert();
1070 			_gnutls_free_datum(x);
1071 			return ret;
1072 		}
1073 	}
1074 
1075 	return 0;
1076 }
1077 
1078 /**
1079  * gnutls_pubkey_export_ecc_x962:
1080  * @key: Holds the public key
1081  * @parameters: DER encoding of an ANSI X9.62 parameters
1082  * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1083  *
1084  * This function will export the ECC public key's parameters found in
1085  * the given certificate.  The new parameters will be allocated using
1086  * gnutls_malloc() and will be stored in the appropriate datum.
1087  *
1088  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1089  *
1090  * Since: 3.3.0
1091  **/
gnutls_pubkey_export_ecc_x962(gnutls_pubkey_t key,gnutls_datum_t * parameters,gnutls_datum_t * ecpoint)1092 int gnutls_pubkey_export_ecc_x962(gnutls_pubkey_t key,
1093 				  gnutls_datum_t * parameters,
1094 				  gnutls_datum_t * ecpoint)
1095 {
1096 	int ret;
1097 	gnutls_datum_t raw_point = {NULL,0};
1098 
1099 	if (key == NULL || key->params.algo != GNUTLS_PK_EC)
1100 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1101 
1102 	ret = _gnutls_x509_write_ecc_pubkey(&key->params, &raw_point);
1103 	if (ret < 0)
1104 		return gnutls_assert_val(ret);
1105 
1106 	ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
1107 					 raw_point.data, raw_point.size, ecpoint);
1108 	if (ret < 0) {
1109 		gnutls_assert();
1110 		goto cleanup;
1111 	}
1112 
1113 	ret = _gnutls_x509_write_ecc_params(key->params.curve, parameters);
1114 	if (ret < 0) {
1115 		_gnutls_free_datum(ecpoint);
1116 		gnutls_assert();
1117 		goto cleanup;
1118 	}
1119 
1120 	ret = 0;
1121  cleanup:
1122 	gnutls_free(raw_point.data);
1123 	return ret;
1124 }
1125 
1126 /**
1127  * gnutls_pubkey_export_gost_raw2:
1128  * @key: Holds the public key
1129  * @curve: will hold the curve (may be %NULL)
1130  * @digest: will hold the curve (may be %NULL)
1131  * @paramset: will hold the parameters id (may be %NULL)
1132  * @x: will hold the x-coordinate (may be %NULL)
1133  * @y: will hold the y-coordinate (may be %NULL)
1134  * @flags: flags from %gnutls_abstract_export_flags_t
1135  *
1136  * This function will export the GOST public key's parameters found in
1137  * the given key.  The new parameters will be allocated using
1138  * gnutls_malloc() and will be stored in the appropriate datum.
1139  *
1140  * Note: parameters will be stored with least significant byte first. On
1141  * version 3.6.3 this was incorrectly returned in big-endian format.
1142  *
1143  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1144  *
1145  * Since: 3.6.3
1146  **/
1147 int
gnutls_pubkey_export_gost_raw2(gnutls_pubkey_t key,gnutls_ecc_curve_t * curve,gnutls_digest_algorithm_t * digest,gnutls_gost_paramset_t * paramset,gnutls_datum_t * x,gnutls_datum_t * y,unsigned int flags)1148 gnutls_pubkey_export_gost_raw2(gnutls_pubkey_t key,
1149 			       gnutls_ecc_curve_t * curve,
1150 			       gnutls_digest_algorithm_t * digest,
1151 			       gnutls_gost_paramset_t * paramset,
1152 			       gnutls_datum_t * x, gnutls_datum_t * y,
1153 			       unsigned int flags)
1154 {
1155 	int ret;
1156 
1157 	mpi_dprint_func dprint = _gnutls_mpi_dprint_le;
1158 
1159 	if (key == NULL) {
1160 		gnutls_assert();
1161 		return GNUTLS_E_INVALID_REQUEST;
1162 	}
1163 
1164 	if (key->params.algo != GNUTLS_PK_GOST_01 &&
1165 	    key->params.algo != GNUTLS_PK_GOST_12_256 &&
1166 	    key->params.algo != GNUTLS_PK_GOST_12_512) {
1167 		gnutls_assert();
1168 		return GNUTLS_E_INVALID_REQUEST;
1169 	}
1170 
1171 	if (curve)
1172 		*curve = key->params.curve;
1173 
1174 	if (digest)
1175 		*digest = _gnutls_gost_digest(key->params.algo);
1176 
1177 	if (paramset)
1178 		*paramset = key->params.gost_params;
1179 
1180 	/* X */
1181 	if (x) {
1182 		ret = dprint(key->params.params[GOST_X], x);
1183 		if (ret < 0) {
1184 			gnutls_assert();
1185 			return ret;
1186 		}
1187 	}
1188 
1189 	/* Y */
1190 	if (y) {
1191 		ret = dprint(key->params.params[GOST_Y], y);
1192 		if (ret < 0) {
1193 			gnutls_assert();
1194 			_gnutls_free_datum(x);
1195 			return ret;
1196 		}
1197 	}
1198 
1199 	return 0;
1200 }
1201 
1202 /**
1203  * gnutls_pubkey_import:
1204  * @key: The public key.
1205  * @data: The DER or PEM encoded certificate.
1206  * @format: One of DER or PEM
1207  *
1208  * This function will import the provided public key in
1209  * a SubjectPublicKeyInfo X.509 structure to a native
1210  * %gnutls_pubkey_t type. The output will be stored
1211  * in @key. If the public key is PEM encoded it should have a header
1212  * of "PUBLIC KEY".
1213  *
1214  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1215  * negative error value.
1216  *
1217  * Since: 2.12.0
1218  **/
1219 int
gnutls_pubkey_import(gnutls_pubkey_t key,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format)1220 gnutls_pubkey_import(gnutls_pubkey_t key,
1221 		     const gnutls_datum_t * data,
1222 		     gnutls_x509_crt_fmt_t format)
1223 {
1224 	int result = 0, need_free = 0;
1225 	gnutls_datum_t _data;
1226 	ASN1_TYPE spk;
1227 
1228 	if (key == NULL) {
1229 		gnutls_assert();
1230 		return GNUTLS_E_INVALID_REQUEST;
1231 	}
1232 
1233 	_data.data = data->data;
1234 	_data.size = data->size;
1235 
1236 	/* If the Certificate is in PEM format then decode it
1237 	 */
1238 	if (format == GNUTLS_X509_FMT_PEM) {
1239 		/* Try the first header */
1240 		result =
1241 		    _gnutls_fbase64_decode(PEM_PK, data->data,
1242 					   data->size, &_data);
1243 
1244 		if (result < 0) {
1245 			gnutls_assert();
1246 			return result;
1247 		}
1248 
1249 		need_free = 1;
1250 	}
1251 
1252 	if ((result = asn1_create_element
1253 	     (_gnutls_get_pkix(), "PKIX1.SubjectPublicKeyInfo", &spk))
1254 	    != ASN1_SUCCESS) {
1255 		gnutls_assert();
1256 		result = _gnutls_asn2err(result);
1257 		goto cleanup;
1258 	}
1259 
1260 	result = _asn1_strict_der_decode(&spk, _data.data, _data.size, NULL);
1261 	if (result != ASN1_SUCCESS) {
1262 		gnutls_assert();
1263 		result = _gnutls_asn2err(result);
1264 		goto cleanup;
1265 	}
1266 
1267 	result = _gnutls_get_asn_mpis(spk, "", &key->params);
1268 	if (result < 0) {
1269 		gnutls_assert();
1270 		goto cleanup;
1271 	}
1272 
1273 	key->bits = pubkey_to_bits(&key->params);
1274 	result = 0;
1275 
1276       cleanup:
1277 	asn1_delete_structure(&spk);
1278 
1279 	if (need_free)
1280 		_gnutls_free_datum(&_data);
1281 	return result;
1282 }
1283 
1284 /**
1285  * gnutls_x509_crt_set_pubkey:
1286  * @crt: should contain a #gnutls_x509_crt_t type
1287  * @key: holds a public key
1288  *
1289  * This function will set the public parameters from the given public
1290  * key to the certificate. The @key can be deallocated after that.
1291  *
1292  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1293  *   negative error value.
1294  *
1295  * Since: 2.12.0
1296  **/
gnutls_x509_crt_set_pubkey(gnutls_x509_crt_t crt,gnutls_pubkey_t key)1297 int gnutls_x509_crt_set_pubkey(gnutls_x509_crt_t crt, gnutls_pubkey_t key)
1298 {
1299 	int result;
1300 
1301 	if (crt == NULL) {
1302 		gnutls_assert();
1303 		return GNUTLS_E_INVALID_REQUEST;
1304 	}
1305 
1306 	result = _gnutls_x509_encode_and_copy_PKI_params(crt->cert,
1307 							 "tbsCertificate.subjectPublicKeyInfo",
1308 							 &key->params);
1309 
1310 	if (result < 0) {
1311 		gnutls_assert();
1312 		return result;
1313 	}
1314 
1315 	if (key->key_usage)
1316 		gnutls_x509_crt_set_key_usage(crt, key->key_usage);
1317 
1318 	return 0;
1319 }
1320 
1321 /**
1322  * gnutls_x509_crq_set_pubkey:
1323  * @crq: should contain a #gnutls_x509_crq_t type
1324  * @key: holds a public key
1325  *
1326  * This function will set the public parameters from the given public
1327  * key to the request. The @key can be deallocated after that.
1328  *
1329  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1330  *   negative error value.
1331  *
1332  * Since: 2.12.0
1333  **/
gnutls_x509_crq_set_pubkey(gnutls_x509_crq_t crq,gnutls_pubkey_t key)1334 int gnutls_x509_crq_set_pubkey(gnutls_x509_crq_t crq, gnutls_pubkey_t key)
1335 {
1336 	int result;
1337 
1338 	if (crq == NULL) {
1339 		gnutls_assert();
1340 		return GNUTLS_E_INVALID_REQUEST;
1341 	}
1342 
1343 	result = _gnutls_x509_encode_and_copy_PKI_params
1344 	    (crq->crq,
1345 	     "certificationRequestInfo.subjectPKInfo",
1346 	     &key->params);
1347 
1348 	if (result < 0) {
1349 		gnutls_assert();
1350 		return result;
1351 	}
1352 
1353 	if (key->key_usage)
1354 		gnutls_x509_crq_set_key_usage(crq, key->key_usage);
1355 
1356 	return 0;
1357 }
1358 
1359 /**
1360  * gnutls_pubkey_set_key_usage:
1361  * @key: a certificate of type #gnutls_x509_crt_t
1362  * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
1363  *
1364  * This function will set the key usage flags of the public key. This
1365  * is only useful if the key is to be exported to a certificate or
1366  * certificate request.
1367  *
1368  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1369  *   negative error value.
1370  *
1371  * Since: 2.12.0
1372  **/
gnutls_pubkey_set_key_usage(gnutls_pubkey_t key,unsigned int usage)1373 int gnutls_pubkey_set_key_usage(gnutls_pubkey_t key, unsigned int usage)
1374 {
1375 	key->key_usage = usage;
1376 
1377 	return 0;
1378 }
1379 
1380 #ifdef ENABLE_PKCS11
1381 
1382 #if 0
1383 /**
1384  * gnutls_pubkey_import_pkcs11_url:
1385  * @key: A key of type #gnutls_pubkey_t
1386  * @url: A PKCS 11 url
1387  * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1388  *
1389  * This function will import a PKCS 11 certificate to a #gnutls_pubkey_t
1390  * structure.
1391  *
1392  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1393  *   negative error value.
1394  *
1395  * Since: 2.12.0
1396  **/
1397 int
1398 gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url,
1399 				unsigned int flags)
1400 {
1401 	int x;
1402 }
1403 #endif
1404 
1405 static int
_gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key,const char * url,unsigned int flags)1406 _gnutls_pubkey_import_pkcs11_url(gnutls_pubkey_t key, const char *url,
1407 				unsigned int flags)
1408 {
1409 	gnutls_pkcs11_obj_t pcrt;
1410 	int ret;
1411 
1412 	ret = gnutls_pkcs11_obj_init(&pcrt);
1413 	if (ret < 0) {
1414 		gnutls_assert();
1415 		return ret;
1416 	}
1417 
1418 	if (key->pin.cb)
1419 		gnutls_pkcs11_obj_set_pin_function(pcrt, key->pin.cb,
1420 						   key->pin.data);
1421 
1422 	ret = gnutls_pkcs11_obj_import_url(pcrt, url, flags|GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PUBKEY);
1423 	if (ret < 0) {
1424 		gnutls_assert();
1425 		goto cleanup;
1426 	}
1427 
1428 	ret = gnutls_pubkey_import_pkcs11(key, pcrt, flags);
1429 	if (ret < 0) {
1430 		gnutls_assert();
1431 		goto cleanup;
1432 	}
1433 
1434 	ret = 0;
1435       cleanup:
1436 
1437 	gnutls_pkcs11_obj_deinit(pcrt);
1438 
1439 	return ret;
1440 }
1441 
1442 #endif				/* ENABLE_PKCS11 */
1443 
1444 /**
1445  * gnutls_pubkey_import_url:
1446  * @key: A key of type #gnutls_pubkey_t
1447  * @url: A PKCS 11 url
1448  * @flags: One of GNUTLS_PKCS11_OBJ_* flags
1449  *
1450  * This function will import a public key from the provided URL.
1451  *
1452  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1453  *   negative error value.
1454  *
1455  * Since: 3.1.0
1456  **/
1457 int
gnutls_pubkey_import_url(gnutls_pubkey_t key,const char * url,unsigned int flags)1458 gnutls_pubkey_import_url(gnutls_pubkey_t key, const char *url,
1459 			 unsigned int flags)
1460 {
1461 	unsigned i;
1462 
1463 	for (i=0;i<_gnutls_custom_urls_size;i++) {
1464 		if (strncmp(url, _gnutls_custom_urls[i].name, _gnutls_custom_urls[i].name_size) == 0) {
1465 			if (_gnutls_custom_urls[i].import_pubkey)
1466 				return _gnutls_custom_urls[i].import_pubkey(key, url, flags);
1467 		}
1468 	}
1469 
1470 	if (strncmp(url, PKCS11_URL, PKCS11_URL_SIZE) == 0)
1471 #ifdef ENABLE_PKCS11
1472 		return _gnutls_pubkey_import_pkcs11_url(key, url, flags);
1473 #else
1474 		return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1475 #endif
1476 
1477 	if (strncmp(url, TPMKEY_URL, TPMKEY_URL_SIZE) == 0)
1478 #ifdef HAVE_TROUSERS
1479 		return gnutls_pubkey_import_tpm_url(key, url, NULL, 0);
1480 #else
1481 		return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
1482 #endif
1483 
1484 	return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1485 }
1486 
1487 /**
1488  * gnutls_pubkey_import_rsa_raw:
1489  * @key: The key
1490  * @m: holds the modulus
1491  * @e: holds the public exponent
1492  *
1493  * This function will replace the parameters in the given structure.
1494  * The new parameters should be stored in the appropriate
1495  * gnutls_datum.
1496  *
1497  * Returns: %GNUTLS_E_SUCCESS on success, or an negative error code.
1498  *
1499  * Since: 2.12.0
1500  **/
1501 int
gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key,const gnutls_datum_t * m,const gnutls_datum_t * e)1502 gnutls_pubkey_import_rsa_raw(gnutls_pubkey_t key,
1503 			     const gnutls_datum_t * m,
1504 			     const gnutls_datum_t * e)
1505 {
1506 	if (key == NULL) {
1507 		gnutls_assert();
1508 		return GNUTLS_E_INVALID_REQUEST;
1509 	}
1510 
1511 	gnutls_pk_params_release(&key->params);
1512 	gnutls_pk_params_init(&key->params);
1513 
1514 	if (_gnutls_mpi_init_scan_nz(&key->params.params[0], m->data, m->size)) {
1515 		gnutls_assert();
1516 		return GNUTLS_E_MPI_SCAN_FAILED;
1517 	}
1518 
1519 	if (_gnutls_mpi_init_scan_nz(&key->params.params[1], e->data, e->size)) {
1520 		gnutls_assert();
1521 		_gnutls_mpi_release(&key->params.params[0]);
1522 		return GNUTLS_E_MPI_SCAN_FAILED;
1523 	}
1524 
1525 	key->params.params_nr = RSA_PUBLIC_PARAMS;
1526 	key->params.algo = GNUTLS_PK_RSA;
1527 	key->bits = pubkey_to_bits(&key->params);
1528 
1529 	return 0;
1530 }
1531 
1532 /**
1533  * gnutls_pubkey_import_ecc_raw:
1534  * @key: The structure to store the parsed key
1535  * @curve: holds the curve
1536  * @x: holds the x-coordinate
1537  * @y: holds the y-coordinate
1538  *
1539  * This function will convert the given elliptic curve parameters to a
1540  * #gnutls_pubkey_t.  The output will be stored in @key.
1541  *
1542  * In EdDSA curves the @y parameter should be %NULL and the @x parameter must
1543  * be the value in the native format for the curve.
1544  *
1545  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1546  *   negative error value.
1547  *
1548  * Since: 3.0
1549  **/
1550 int
gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key,gnutls_ecc_curve_t curve,const gnutls_datum_t * x,const gnutls_datum_t * y)1551 gnutls_pubkey_import_ecc_raw(gnutls_pubkey_t key,
1552 			     gnutls_ecc_curve_t curve,
1553 			     const gnutls_datum_t * x,
1554 			     const gnutls_datum_t * y)
1555 {
1556 	int ret;
1557 
1558 	if (key == NULL || x == NULL) {
1559 		gnutls_assert();
1560 		return GNUTLS_E_INVALID_REQUEST;
1561 	}
1562 
1563 	gnutls_pk_params_release(&key->params);
1564 	gnutls_pk_params_init(&key->params);
1565 
1566 	if (curve_is_eddsa(curve)) {
1567 		unsigned size = gnutls_ecc_curve_get_size(curve);
1568 		if (x->size != size) {
1569 			ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1570 			goto cleanup;
1571 		}
1572 
1573 		ret = _gnutls_set_datum(&key->params.raw_pub, x->data, x->size);
1574 		if (ret < 0) {
1575 			gnutls_assert();
1576 			goto cleanup;
1577 		}
1578 
1579 		switch (curve) {
1580 		case GNUTLS_ECC_CURVE_ED25519:
1581 			key->params.algo = GNUTLS_PK_EDDSA_ED25519;
1582 			break;
1583 		case GNUTLS_ECC_CURVE_ED448:
1584 			key->params.algo = GNUTLS_PK_EDDSA_ED448;
1585 			break;
1586 		default:
1587 			break;
1588 		}
1589 		key->params.curve = curve;
1590 		key->bits = pubkey_to_bits(&key->params);
1591 
1592 		return 0;
1593 	}
1594 
1595 	/* ECDSA */
1596 	if (y == NULL) {
1597 		gnutls_assert();
1598 		return GNUTLS_E_INVALID_REQUEST;
1599 	}
1600 
1601 	key->params.curve = curve;
1602 
1603 	if (_gnutls_mpi_init_scan_nz
1604 	    (&key->params.params[ECC_X], x->data, x->size)) {
1605 		gnutls_assert();
1606 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1607 		goto cleanup;
1608 	}
1609 	key->params.params_nr++;
1610 
1611 	if (_gnutls_mpi_init_scan_nz
1612 	    (&key->params.params[ECC_Y], y->data, y->size)) {
1613 		gnutls_assert();
1614 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1615 		goto cleanup;
1616 	}
1617 	key->params.params_nr++;
1618 	key->params.algo = GNUTLS_PK_ECDSA;
1619 	key->bits = pubkey_to_bits(&key->params);
1620 
1621 	return 0;
1622 
1623       cleanup:
1624 	gnutls_pk_params_release(&key->params);
1625 	return ret;
1626 }
1627 
1628 /**
1629  * gnutls_pubkey_import_ecc_x962:
1630  * @key: The structure to store the parsed key
1631  * @parameters: DER encoding of an ANSI X9.62 parameters
1632  * @ecpoint: DER encoding of ANSI X9.62 ECPoint
1633  *
1634  * This function will convert the given elliptic curve parameters to a
1635  * #gnutls_pubkey_t.  The output will be stored in @key.
1636  *
1637  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1638  *   negative error value.
1639  *
1640  * Since: 3.0
1641  **/
1642 int
gnutls_pubkey_import_ecc_x962(gnutls_pubkey_t key,const gnutls_datum_t * parameters,const gnutls_datum_t * ecpoint)1643 gnutls_pubkey_import_ecc_x962(gnutls_pubkey_t key,
1644 			      const gnutls_datum_t * parameters,
1645 			      const gnutls_datum_t * ecpoint)
1646 {
1647 	int ret;
1648 	gnutls_datum_t raw_point = {NULL,0};
1649 
1650 	if (key == NULL) {
1651 		gnutls_assert();
1652 		return GNUTLS_E_INVALID_REQUEST;
1653 	}
1654 
1655 	gnutls_pk_params_release(&key->params);
1656 	gnutls_pk_params_init(&key->params);
1657 
1658 	key->params.params_nr = 0;
1659 
1660 	ret =
1661 	    _gnutls_x509_read_ecc_params(parameters->data,
1662 					 parameters->size, &key->params.curve);
1663 	if (ret < 0) {
1664 		gnutls_assert();
1665 		goto cleanup;
1666 	}
1667 
1668 	ret = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING,
1669 					 ecpoint->data, ecpoint->size, &raw_point, 0);
1670 	if (ret < 0) {
1671 		gnutls_assert();
1672 		goto cleanup;
1673 	}
1674 
1675 	ret = _gnutls_ecc_ansi_x962_import(raw_point.data, raw_point.size,
1676 					   &key->params.params[ECC_X],
1677 					   &key->params.params[ECC_Y]);
1678 	if (ret < 0) {
1679 		gnutls_assert();
1680 		goto cleanup;
1681 	}
1682 	key->params.params_nr += 2;
1683 	key->params.algo = GNUTLS_PK_EC;
1684 
1685 	gnutls_free(raw_point.data);
1686 	return 0;
1687 
1688       cleanup:
1689 	gnutls_pk_params_release(&key->params);
1690 	gnutls_free(raw_point.data);
1691 	return ret;
1692 }
1693 
1694 /**
1695  * gnutls_pubkey_import_gost_raw:
1696  * @key: The structure to store the parsed key
1697  * @curve: holds the curve
1698  * @digest: holds the digest
1699  * @paramset: holds the parameters id
1700  * @x: holds the x-coordinate
1701  * @y: holds the y-coordinate
1702  *
1703  * This function will convert the given GOST public key's parameters to a
1704  * #gnutls_pubkey_t.  The output will be stored in @key.  @digest should be
1705  * one of GNUTLS_DIG_GOSR_94, GNUTLS_DIG_STREEBOG_256 or
1706  * GNUTLS_DIG_STREEBOG_512.  If @paramset is set to GNUTLS_GOST_PARAMSET_UNKNOWN
1707  * default one will be selected depending on @digest.
1708  *
1709  * Note: parameters should be stored with least significant byte first. On
1710  * version 3.6.3 big-endian format was used incorrectly.
1711  *
1712  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1713  *   negative error value.
1714  *
1715  * Since: 3.6.3
1716  **/
1717 int
gnutls_pubkey_import_gost_raw(gnutls_pubkey_t key,gnutls_ecc_curve_t curve,gnutls_digest_algorithm_t digest,gnutls_gost_paramset_t paramset,const gnutls_datum_t * x,const gnutls_datum_t * y)1718 gnutls_pubkey_import_gost_raw(gnutls_pubkey_t key,
1719 			     gnutls_ecc_curve_t curve,
1720 			     gnutls_digest_algorithm_t digest,
1721 			     gnutls_gost_paramset_t paramset,
1722 			     const gnutls_datum_t * x,
1723 			     const gnutls_datum_t * y)
1724 {
1725 	int ret;
1726 	gnutls_pk_algorithm_t pk_algo;
1727 
1728 	if (key == NULL) {
1729 		gnutls_assert();
1730 		return GNUTLS_E_INVALID_REQUEST;
1731 	}
1732 
1733 	pk_algo = _gnutls_digest_gost(digest);
1734 	if (pk_algo == GNUTLS_PK_UNKNOWN)
1735 		return GNUTLS_E_ILLEGAL_PARAMETER;
1736 
1737 	if (paramset == GNUTLS_GOST_PARAMSET_UNKNOWN)
1738 		paramset = _gnutls_gost_paramset_default(pk_algo);
1739 
1740 	gnutls_pk_params_release(&key->params);
1741 	gnutls_pk_params_init(&key->params);
1742 
1743 	key->params.curve = curve;
1744 	key->params.gost_params = paramset;
1745 
1746 	if (_gnutls_mpi_init_scan_le
1747 	    (&key->params.params[GOST_X], x->data, x->size)) {
1748 		gnutls_assert();
1749 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1750 		goto cleanup;
1751 	}
1752 	key->params.params_nr++;
1753 
1754 	if (_gnutls_mpi_init_scan_le
1755 	    (&key->params.params[GOST_Y], y->data, y->size)) {
1756 		gnutls_assert();
1757 		ret = GNUTLS_E_MPI_SCAN_FAILED;
1758 		goto cleanup;
1759 	}
1760 	key->params.params_nr++;
1761 	key->params.algo = pk_algo;
1762 
1763 	return 0;
1764 
1765       cleanup:
1766 	gnutls_pk_params_release(&key->params);
1767 	return ret;
1768 }
1769 
1770 /**
1771  * gnutls_pubkey_import_dsa_raw:
1772  * @key: The structure to store the parsed key
1773  * @p: holds the p
1774  * @q: holds the q
1775  * @g: holds the g
1776  * @y: holds the y
1777  *
1778  * This function will convert the given DSA raw parameters to the
1779  * native #gnutls_pubkey_t format.  The output will be stored
1780  * in @key.
1781  *
1782  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1783  *   negative error value.
1784  *
1785  * Since: 2.12.0
1786  **/
1787 int
gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key,const gnutls_datum_t * p,const gnutls_datum_t * q,const gnutls_datum_t * g,const gnutls_datum_t * y)1788 gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key,
1789 			     const gnutls_datum_t * p,
1790 			     const gnutls_datum_t * q,
1791 			     const gnutls_datum_t * g,
1792 			     const gnutls_datum_t * y)
1793 {
1794 	size_t siz = 0;
1795 
1796 	if (key == NULL) {
1797 		gnutls_assert();
1798 		return GNUTLS_E_INVALID_REQUEST;
1799 	}
1800 
1801 	gnutls_pk_params_release(&key->params);
1802 	gnutls_pk_params_init(&key->params);
1803 
1804 	siz = p->size;
1805 	if (_gnutls_mpi_init_scan_nz(&key->params.params[0], p->data, siz)) {
1806 		gnutls_assert();
1807 		return GNUTLS_E_MPI_SCAN_FAILED;
1808 	}
1809 
1810 	siz = q->size;
1811 	if (_gnutls_mpi_init_scan_nz(&key->params.params[1], q->data, siz)) {
1812 		gnutls_assert();
1813 		_gnutls_mpi_release(&key->params.params[0]);
1814 		return GNUTLS_E_MPI_SCAN_FAILED;
1815 	}
1816 
1817 	siz = g->size;
1818 	if (_gnutls_mpi_init_scan_nz(&key->params.params[2], g->data, siz)) {
1819 		gnutls_assert();
1820 		_gnutls_mpi_release(&key->params.params[1]);
1821 		_gnutls_mpi_release(&key->params.params[0]);
1822 		return GNUTLS_E_MPI_SCAN_FAILED;
1823 	}
1824 
1825 	siz = y->size;
1826 	if (_gnutls_mpi_init_scan_nz(&key->params.params[3], y->data, siz)) {
1827 		gnutls_assert();
1828 		_gnutls_mpi_release(&key->params.params[2]);
1829 		_gnutls_mpi_release(&key->params.params[1]);
1830 		_gnutls_mpi_release(&key->params.params[0]);
1831 		return GNUTLS_E_MPI_SCAN_FAILED;
1832 	}
1833 
1834 	key->params.params_nr = DSA_PUBLIC_PARAMS;
1835 	key->params.algo = GNUTLS_PK_DSA;
1836 	key->bits = pubkey_to_bits(&key->params);
1837 
1838 	return 0;
1839 
1840 }
1841 
1842 /* Updates the gnutls_x509_spki_st parameters based on the signature
1843  * information, and reports any incompatibilities between the existing
1844  * parameters (if any) with the signature algorithm */
1845 static
fixup_spki_params(const gnutls_pk_params_st * key_params,const gnutls_sign_entry_st * se,const mac_entry_st * me,gnutls_x509_spki_st * params)1846 int fixup_spki_params(const gnutls_pk_params_st *key_params, const gnutls_sign_entry_st *se,
1847 		       const mac_entry_st *me, gnutls_x509_spki_st *params)
1848 {
1849 	unsigned bits;
1850 
1851 	if (se->pk != key_params->algo) {
1852 		if (!sign_supports_priv_pk_algorithm(se, key_params->algo)) {
1853 			_gnutls_debug_log("have key: %s/%d, with sign %s/%d\n",
1854 					gnutls_pk_get_name(key_params->algo), key_params->algo,
1855 					se->name, se->id);
1856 			return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
1857 		}
1858 	}
1859 
1860 	if (params->pk == GNUTLS_PK_RSA_PSS) {
1861 		int ret;
1862 		if (!GNUTLS_PK_IS_RSA(key_params->algo))
1863 			return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
1864 
1865 		/* The requested sign algorithm is RSA-PSS, while the
1866 		 * pubkey doesn't include parameter information. Fill
1867 		 * it with the same way as gnutls_privkey_sign*. */
1868 		if (key_params->algo == GNUTLS_PK_RSA || params->rsa_pss_dig == 0) {
1869 			bits = pubkey_to_bits(key_params);
1870 			params->rsa_pss_dig = se->hash;
1871 			ret = _gnutls_find_rsa_pss_salt_size(bits, me, 0);
1872 			if (ret < 0)
1873 				return gnutls_assert_val(ret);
1874 
1875 			params->salt_size = ret;
1876 		}
1877 
1878 		if (params->rsa_pss_dig != se->hash)
1879 			return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
1880 	}
1881 
1882 	return 0;
1883 }
1884 
1885 /**
1886  * gnutls_pubkey_verify_data2:
1887  * @pubkey: Holds the public key
1888  * @algo: The signature algorithm used
1889  * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
1890  * @data: holds the signed data
1891  * @signature: contains the signature
1892  *
1893  * This function will verify the given signed data, using the
1894  * parameters from the certificate.
1895  *
1896  * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1897  * is returned, and zero or positive code on success. For known to be insecure
1898  * signatures this function will return %GNUTLS_E_INSUFFICIENT_SECURITY unless
1899  * the flag %GNUTLS_VERIFY_ALLOW_BROKEN is specified.
1900  *
1901  * Since: 3.0
1902  **/
1903 int
gnutls_pubkey_verify_data2(gnutls_pubkey_t pubkey,gnutls_sign_algorithm_t algo,unsigned int flags,const gnutls_datum_t * data,const gnutls_datum_t * signature)1904 gnutls_pubkey_verify_data2(gnutls_pubkey_t pubkey,
1905 			   gnutls_sign_algorithm_t algo,
1906 			   unsigned int flags,
1907 			   const gnutls_datum_t * data,
1908 			   const gnutls_datum_t * signature)
1909 {
1910 	int ret;
1911 	const mac_entry_st *me;
1912 	gnutls_x509_spki_st params;
1913 	const gnutls_sign_entry_st *se;
1914 
1915 	if (pubkey == NULL) {
1916 		gnutls_assert();
1917 		return GNUTLS_E_INVALID_REQUEST;
1918 	}
1919 
1920 	if (flags & GNUTLS_VERIFY_USE_TLS1_RSA)
1921 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1922 
1923 	memcpy(&params, &pubkey->params.spki, sizeof(gnutls_x509_spki_st));
1924 
1925 	se = _gnutls_sign_to_entry(algo);
1926 	if (se == NULL)
1927 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1928 
1929 	ret = pubkey_supports_sig(pubkey, se);
1930 	if (ret < 0)
1931 		return gnutls_assert_val(ret);
1932 
1933 	params.pk = se->pk;
1934 
1935 	me = hash_to_entry(se->hash);
1936 	if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk))
1937 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1938 
1939 	ret = pubkey_verify_data(se, me, data, signature, &pubkey->params,
1940 				 &params, flags);
1941 	if (ret < 0) {
1942 		gnutls_assert();
1943 		return ret;
1944 	}
1945 
1946 	return 0;
1947 }
1948 
1949 /**
1950  * gnutls_pubkey_verify_hash2:
1951  * @key: Holds the public key
1952  * @algo: The signature algorithm used
1953  * @flags: Zero or an OR list of #gnutls_certificate_verify_flags
1954  * @hash: holds the hash digest to be verified
1955  * @signature: contains the signature
1956  *
1957  * This function will verify the given signed digest, using the
1958  * parameters from the public key. Note that unlike gnutls_privkey_sign_hash(),
1959  * this function accepts a signature algorithm instead of a digest algorithm.
1960  * You can use gnutls_pk_to_sign() to get the appropriate value.
1961  *
1962  * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
1963  * is returned, and zero or positive code on success. For known to be insecure
1964  * signatures this function will return %GNUTLS_E_INSUFFICIENT_SECURITY unless
1965  * the flag %GNUTLS_VERIFY_ALLOW_BROKEN is specified.
1966  *
1967  * Since: 3.0
1968  **/
1969 int
gnutls_pubkey_verify_hash2(gnutls_pubkey_t key,gnutls_sign_algorithm_t algo,unsigned int flags,const gnutls_datum_t * hash,const gnutls_datum_t * signature)1970 gnutls_pubkey_verify_hash2(gnutls_pubkey_t key,
1971 			   gnutls_sign_algorithm_t algo,
1972 			   unsigned int flags,
1973 			   const gnutls_datum_t * hash,
1974 			   const gnutls_datum_t * signature)
1975 {
1976 	const mac_entry_st *me;
1977 	gnutls_x509_spki_st params;
1978 	const gnutls_sign_entry_st *se;
1979 	int ret;
1980 
1981 	if (key == NULL) {
1982 		gnutls_assert();
1983 		return GNUTLS_E_INVALID_REQUEST;
1984 	}
1985 
1986 	if (_gnutls_pk_is_not_prehashed(key->params.algo)) {
1987 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1988 	}
1989 
1990 	memcpy(&params, &key->params.spki, sizeof(gnutls_x509_spki_st));
1991 
1992 	if (flags & GNUTLS_VERIFY_USE_TLS1_RSA) {
1993 		if (!GNUTLS_PK_IS_RSA(key->params.algo))
1994 			return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
1995 		params.pk = GNUTLS_PK_RSA;
1996 		/* we do not check for insecure algorithms with this flag */
1997 		return _gnutls_pk_verify(params.pk, hash, signature,
1998 					 &key->params, &params);
1999 	} else {
2000 		se = _gnutls_sign_to_entry(algo);
2001 		if (se == NULL)
2002 			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2003 
2004 		ret = pubkey_supports_sig(key, se);
2005 		if (ret < 0)
2006 			return gnutls_assert_val(ret);
2007 
2008 		params.pk = se->pk;
2009 
2010 		me = hash_to_entry(se->hash);
2011 		if (me == NULL && !_gnutls_pk_is_not_prehashed(se->pk))
2012 			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2013 
2014 		ret = pubkey_verify_hashed_data(se, me, hash, signature,
2015 						&key->params,
2016 						&params, flags);
2017 		if (ret < 0) {
2018 			gnutls_assert();
2019 			return ret;
2020 		}
2021 	}
2022 
2023 	return 0;
2024 }
2025 
2026 /**
2027  * gnutls_pubkey_encrypt_data:
2028  * @key: Holds the public key
2029  * @flags: should be 0 for now
2030  * @plaintext: The data to be encrypted
2031  * @ciphertext: contains the encrypted data
2032  *
2033  * This function will encrypt the given data, using the public
2034  * key. On success the @ciphertext will be allocated using gnutls_malloc().
2035  *
2036  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2037  *   negative error value.
2038  *
2039  * Since: 3.0
2040  **/
2041 int
gnutls_pubkey_encrypt_data(gnutls_pubkey_t key,unsigned int flags,const gnutls_datum_t * plaintext,gnutls_datum_t * ciphertext)2042 gnutls_pubkey_encrypt_data(gnutls_pubkey_t key, unsigned int flags,
2043 			   const gnutls_datum_t * plaintext,
2044 			   gnutls_datum_t * ciphertext)
2045 {
2046 	if (key == NULL) {
2047 		gnutls_assert();
2048 		return GNUTLS_E_INVALID_REQUEST;
2049 	}
2050 
2051 	return _gnutls_pk_encrypt(key->params.algo, ciphertext,
2052 				  plaintext, &key->params);
2053 }
2054 
2055 static
pubkey_supports_sig(gnutls_pubkey_t pubkey,const gnutls_sign_entry_st * se)2056 int pubkey_supports_sig(gnutls_pubkey_t pubkey,
2057 			const gnutls_sign_entry_st *se)
2058 {
2059 	if (pubkey->params.algo == GNUTLS_PK_ECDSA && se->curve) {
2060 		gnutls_ecc_curve_t curve = pubkey->params.curve;
2061 
2062 		if (curve != se->curve) {
2063 			_gnutls_handshake_log("have key: ECDSA with %s/%d, with sign %s/%d\n",
2064 				gnutls_ecc_curve_get_name(curve), (int)curve,
2065 				se->name, se->id);
2066 			return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
2067 		}
2068 	}
2069 
2070 	if (se->pk != pubkey->params.algo) { /* if the PK algorithm of the signature differs to the one on the pubkey */
2071 		if (!sign_supports_priv_pk_algorithm(se, pubkey->params.algo)) {
2072 			_gnutls_handshake_log("have key: %s/%d, with sign %s/%d\n",
2073 					gnutls_pk_get_name(pubkey->params.algo), pubkey->params.algo,
2074 					se->name, se->id);
2075 			return gnutls_assert_val(GNUTLS_E_INCOMPATIBLE_SIG_WITH_KEY);
2076 		}
2077 	}
2078 
2079 	return 0;
2080 }
2081 
2082 /* Checks whether the public key given is compatible with the
2083  * signature algorithm used. The session is only used for audit logging, and
2084  * it may be null.
2085  */
_gnutls_pubkey_compatible_with_sig(gnutls_session_t session,gnutls_pubkey_t pubkey,const version_entry_st * ver,gnutls_sign_algorithm_t sign)2086 int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session,
2087 				       gnutls_pubkey_t pubkey,
2088 				       const version_entry_st * ver,
2089 				       gnutls_sign_algorithm_t sign)
2090 {
2091 	unsigned int hash_size = 0;
2092 	unsigned int sig_hash_size;
2093 	const mac_entry_st *me;
2094 	const gnutls_sign_entry_st *se;
2095 	int ret;
2096 
2097 	se = _gnutls_sign_to_entry(sign);
2098 	if (se != NULL) {
2099 		ret = pubkey_supports_sig(pubkey, se);
2100 		if (ret < 0)
2101 			return gnutls_assert_val(ret);
2102 	} else if (_gnutls_version_has_selectable_sighash(ver)) {
2103 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2104 	}
2105 
2106 	if (pubkey->params.algo == GNUTLS_PK_DSA) {
2107 		me = _gnutls_dsa_q_to_hash(&pubkey->params, &hash_size);
2108 
2109 		/* DSA keys over 1024 bits cannot be used with TLS 1.x, x<2 */
2110 		if (!_gnutls_version_has_selectable_sighash(ver)) {
2111 			if (me->id != GNUTLS_MAC_SHA1)
2112 				return
2113 				    gnutls_assert_val
2114 				    (GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
2115 		} else if (se != NULL) {
2116 			me = hash_to_entry(se->hash);
2117 
2118 			sig_hash_size = _gnutls_hash_get_algo_len(me);
2119 			if (sig_hash_size < hash_size)
2120 				_gnutls_audit_log(session,
2121 						  "The hash size used in signature (%u) is less than the expected (%u)\n",
2122 						  sig_hash_size,
2123 						  hash_size);
2124 		}
2125 
2126 	} else if (pubkey->params.algo == GNUTLS_PK_ECDSA) {
2127 		if (_gnutls_version_has_selectable_sighash(ver)
2128 		    && se != NULL) {
2129 			_gnutls_dsa_q_to_hash(&pubkey->params, &hash_size);
2130 
2131 			me = hash_to_entry(se->hash);
2132 
2133 			sig_hash_size = _gnutls_hash_get_algo_len(me);
2134 
2135 			if (sig_hash_size < hash_size)
2136 				_gnutls_audit_log(session,
2137 						  "The hash size used in signature (%u) is less than the expected (%u)\n",
2138 						  sig_hash_size,
2139 						  hash_size);
2140 		}
2141 
2142 	} else if (pubkey->params.algo == GNUTLS_PK_GOST_01 ||
2143 		   pubkey->params.algo == GNUTLS_PK_GOST_12_256 ||
2144 		   pubkey->params.algo == GNUTLS_PK_GOST_12_512) {
2145 		if (_gnutls_version_has_selectable_sighash(ver)
2146 		    && se != NULL) {
2147 			if (_gnutls_gost_digest(pubkey->params.algo) != se->hash) {
2148 				_gnutls_audit_log(session,
2149 						  "The hash algo used in signature (%u) is not expected (%u)\n",
2150 						  se->hash, _gnutls_gost_digest(pubkey->params.algo));
2151 				return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2152 			}
2153 		}
2154 
2155 	} else if (pubkey->params.algo == GNUTLS_PK_RSA_PSS) {
2156 		if (!_gnutls_version_has_selectable_sighash(ver))
2157 			/* this should not have happened */
2158 			return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
2159 
2160 		/* RSA PSS public keys are restricted to a single digest, i.e., signature */
2161 
2162 		if (pubkey->params.spki.rsa_pss_dig && pubkey->params.spki.rsa_pss_dig != se->hash) {
2163 			return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR);
2164 		}
2165 	}
2166 
2167 	return 0;
2168 }
2169 
2170 /* Returns the public key.
2171  */
2172 int
_gnutls_pubkey_get_mpis(gnutls_pubkey_t key,gnutls_pk_params_st * params)2173 _gnutls_pubkey_get_mpis(gnutls_pubkey_t key, gnutls_pk_params_st * params)
2174 {
2175 	return _gnutls_pk_params_copy(params, &key->params);
2176 }
2177 
2178 /* if hash==MD5 then we do RSA-MD5
2179  * if hash==SHA then we do RSA-SHA
2180  * params[0] is modulus
2181  * params[1] is public key
2182  */
2183 static int
_pkcs1_rsa_verify_sig(gnutls_pk_algorithm_t pk,const mac_entry_st * me,const gnutls_datum_t * text,const gnutls_datum_t * prehash,const gnutls_datum_t * signature,gnutls_pk_params_st * params,gnutls_x509_spki_st * sign_params)2184 _pkcs1_rsa_verify_sig(gnutls_pk_algorithm_t pk,
2185 		      const mac_entry_st * me,
2186 		      const gnutls_datum_t * text,
2187 		      const gnutls_datum_t * prehash,
2188 		      const gnutls_datum_t * signature,
2189 		      gnutls_pk_params_st * params,
2190 		      gnutls_x509_spki_st * sign_params)
2191 {
2192 	int ret;
2193 	uint8_t md[MAX_HASH_SIZE], *cmp;
2194 	unsigned int digest_size;
2195 	gnutls_datum_t d, di;
2196 
2197 	if (unlikely(me == NULL))
2198 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2199 
2200 	digest_size = _gnutls_hash_get_algo_len(me);
2201 	if (prehash) {
2202 		if (prehash->data == NULL || prehash->size != digest_size)
2203 			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2204 
2205 		cmp = prehash->data;
2206 	} else {
2207 		if (!text) {
2208 			gnutls_assert();
2209 			return GNUTLS_E_INVALID_REQUEST;
2210 		}
2211 
2212 		ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)me->id,
2213 					text->data, text->size, md);
2214 		if (ret < 0) {
2215 			gnutls_assert();
2216 			return ret;
2217 		}
2218 
2219 		cmp = md;
2220 	}
2221 
2222 	d.data = cmp;
2223 	d.size = digest_size;
2224 
2225 	if (pk == GNUTLS_PK_RSA) {
2226 		/* decrypted is a BER encoded data of type DigestInfo
2227 		 */
2228 		ret = encode_ber_digest_info(me, &d, &di);
2229 		if (ret < 0)
2230 			return gnutls_assert_val(ret);
2231 
2232 		ret = _gnutls_pk_verify(pk, &di, signature, params,
2233 					sign_params);
2234 		_gnutls_free_datum(&di);
2235 	} else {
2236 		ret = _gnutls_pk_verify(pk, &d, signature, params,
2237 					sign_params);
2238 	}
2239 
2240 	return ret;
2241 }
2242 
2243 /* Hashes input data and verifies a signature.
2244  */
2245 static int
dsa_verify_hashed_data(gnutls_pk_algorithm_t pk,const mac_entry_st * algo,const gnutls_datum_t * hash,const gnutls_datum_t * signature,gnutls_pk_params_st * params,gnutls_x509_spki_st * sign_params)2246 dsa_verify_hashed_data(gnutls_pk_algorithm_t pk,
2247 		       const mac_entry_st * algo,
2248 		       const gnutls_datum_t * hash,
2249 		       const gnutls_datum_t * signature,
2250 		       gnutls_pk_params_st * params,
2251 		       gnutls_x509_spki_st * sign_params)
2252 {
2253 	gnutls_datum_t digest;
2254 	unsigned int hash_len;
2255 
2256 	if (algo == NULL)
2257 		algo = _gnutls_dsa_q_to_hash(params, &hash_len);
2258 	else
2259 		hash_len = _gnutls_hash_get_algo_len(algo);
2260 
2261 	/* SHA1 or better allowed */
2262 	if (!hash->data || hash->size < hash_len) {
2263 		gnutls_assert();
2264 		_gnutls_debug_log
2265 		    ("Hash size (%d) does not correspond to hash %s(%d) or better.\n",
2266 		     (int) hash->size, _gnutls_mac_get_name(algo),
2267 		     hash_len);
2268 
2269 		if (hash->size != 20)	/* SHA1 is allowed */
2270 			return
2271 			    gnutls_assert_val
2272 			    (GNUTLS_E_PK_SIG_VERIFY_FAILED);
2273 	}
2274 
2275 	digest.data = hash->data;
2276 	digest.size = hash->size;
2277 
2278 	return _gnutls_pk_verify(pk, &digest, signature, params, sign_params);
2279 }
2280 
2281 static int
dsa_verify_data(gnutls_pk_algorithm_t pk,const mac_entry_st * algo,const gnutls_datum_t * data,const gnutls_datum_t * signature,gnutls_pk_params_st * params,gnutls_x509_spki_st * sign_params)2282 dsa_verify_data(gnutls_pk_algorithm_t pk,
2283 		const mac_entry_st * algo,
2284 		const gnutls_datum_t * data,
2285 		const gnutls_datum_t * signature,
2286 		gnutls_pk_params_st * params,
2287 		gnutls_x509_spki_st * sign_params)
2288 {
2289 	int ret;
2290 	uint8_t _digest[MAX_HASH_SIZE];
2291 	gnutls_datum_t digest;
2292 
2293 	if (algo == NULL)
2294 		algo = _gnutls_dsa_q_to_hash(params, NULL);
2295 
2296 	ret = _gnutls_hash_fast((gnutls_digest_algorithm_t)algo->id,
2297 				data->data, data->size, _digest);
2298 	if (ret < 0)
2299 		return gnutls_assert_val(ret);
2300 
2301 	digest.data = _digest;
2302 	digest.size = _gnutls_hash_get_algo_len(algo);
2303 
2304 	return _gnutls_pk_verify(pk, &digest, signature, params, sign_params);
2305 }
2306 
2307 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
2308  * not verified, or 1 otherwise.
2309  */
2310 static int
pubkey_verify_hashed_data(const gnutls_sign_entry_st * se,const mac_entry_st * me,const gnutls_datum_t * hash,const gnutls_datum_t * signature,gnutls_pk_params_st * params,gnutls_x509_spki_st * sign_params,unsigned flags)2311 pubkey_verify_hashed_data(const gnutls_sign_entry_st *se,
2312 			  const mac_entry_st *me,
2313 			  const gnutls_datum_t * hash,
2314 			  const gnutls_datum_t * signature,
2315 			  gnutls_pk_params_st * params,
2316 			  gnutls_x509_spki_st * sign_params,
2317 			  unsigned flags)
2318 {
2319 	int ret;
2320 
2321 	if (unlikely(me==NULL))
2322 		return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
2323 
2324 	ret = fixup_spki_params(params, se, me, sign_params);
2325 	if (ret < 0)
2326 		return gnutls_assert_val(ret);
2327 
2328 	switch (se->pk) {
2329 	case GNUTLS_PK_RSA:
2330 	case GNUTLS_PK_RSA_PSS:
2331 
2332 		if (_pkcs1_rsa_verify_sig
2333 		    (se->pk, me, NULL, hash, signature, params, sign_params) != 0)
2334 		{
2335 			gnutls_assert();
2336 			return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2337 		}
2338 
2339 		break;
2340 
2341 	case GNUTLS_PK_ECDSA:
2342 	case GNUTLS_PK_GOST_01:
2343 	case GNUTLS_PK_GOST_12_256:
2344 	case GNUTLS_PK_GOST_12_512:
2345 	case GNUTLS_PK_DSA:
2346 		if (dsa_verify_hashed_data
2347 		    (se->pk, me, hash, signature, params, sign_params) != 0) {
2348 			gnutls_assert();
2349 			return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2350 		}
2351 
2352 		break;
2353 	default:
2354 		gnutls_assert();
2355 		return GNUTLS_E_INVALID_REQUEST;
2356 
2357 	}
2358 
2359 	if (_gnutls_sign_is_secure2(se, 0) == 0 && _gnutls_is_broken_sig_allowed(se, flags) == 0) {
2360 		return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
2361 	}
2362 
2363 	return 1;
2364 }
2365 
2366 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if
2367  * not verified, or 1 otherwise.
2368  */
2369 int
pubkey_verify_data(const gnutls_sign_entry_st * se,const mac_entry_st * me,const gnutls_datum_t * data,const gnutls_datum_t * signature,gnutls_pk_params_st * params,gnutls_x509_spki_st * sign_params,unsigned flags)2370 pubkey_verify_data(const gnutls_sign_entry_st *se,
2371 		   const mac_entry_st *me,
2372 		   const gnutls_datum_t * data,
2373 		   const gnutls_datum_t * signature,
2374 		   gnutls_pk_params_st * params,
2375 		   gnutls_x509_spki_st * sign_params,
2376 		   unsigned flags)
2377 {
2378 	int ret;
2379 
2380 	if (unlikely(me == NULL))
2381 		return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
2382 
2383 	ret = fixup_spki_params(params, se, me, sign_params);
2384 	if (ret < 0)
2385 		return gnutls_assert_val(ret);
2386 
2387 	switch (se->pk) {
2388 	case GNUTLS_PK_RSA:
2389 	case GNUTLS_PK_RSA_PSS:
2390 		if (_pkcs1_rsa_verify_sig
2391 		    (se->pk, me, data, NULL, signature, params, sign_params) != 0) {
2392 			gnutls_assert();
2393 			return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2394 		}
2395 
2396 		break;
2397 
2398 	case GNUTLS_PK_EDDSA_ED25519:
2399 	case GNUTLS_PK_EDDSA_ED448:
2400 		if (_gnutls_pk_verify(se->pk, data, signature, params, sign_params) != 0) {
2401 			gnutls_assert();
2402 			return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2403 		}
2404 
2405 		break;
2406 
2407 	case GNUTLS_PK_EC:
2408 	case GNUTLS_PK_DSA:
2409 	case GNUTLS_PK_GOST_01:
2410 	case GNUTLS_PK_GOST_12_256:
2411 	case GNUTLS_PK_GOST_12_512:
2412 		if (dsa_verify_data
2413 		    (se->pk, me, data, signature, params, sign_params) != 0) {
2414 			gnutls_assert();
2415 			return GNUTLS_E_PK_SIG_VERIFY_FAILED;
2416 		}
2417 
2418 		break;
2419 	default:
2420 		gnutls_assert();
2421 		return GNUTLS_E_INVALID_REQUEST;
2422 
2423 	}
2424 
2425 	if (_gnutls_sign_is_secure2(se,0) == 0 && _gnutls_is_broken_sig_allowed(se, flags) == 0) {
2426 		return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_SECURITY);
2427 	}
2428 
2429 	return 1;
2430 }
2431 
_gnutls_dsa_q_to_hash(const gnutls_pk_params_st * params,unsigned int * hash_len)2432 const mac_entry_st *_gnutls_dsa_q_to_hash(const gnutls_pk_params_st *
2433 					  params, unsigned int *hash_len)
2434 {
2435 	int bits = 0;
2436 	int ret;
2437 
2438 	if (params->algo == GNUTLS_PK_DSA)
2439 		bits = _gnutls_mpi_get_nbits(params->params[1]);
2440 	else if (params->algo == GNUTLS_PK_EC)
2441 		bits = gnutls_ecc_curve_get_size(params->curve) * 8;
2442 
2443 	if (bits <= 160) {
2444 		if (hash_len)
2445 			*hash_len = 20;
2446 		ret = GNUTLS_DIG_SHA1;
2447 	} else if (bits <= 192) {
2448 		if (hash_len)
2449 			*hash_len = 24;
2450 		ret = GNUTLS_DIG_SHA256;
2451 	} else if (bits <= 224) {
2452 		if (hash_len)
2453 			*hash_len = 28;
2454 		ret = GNUTLS_DIG_SHA256;
2455 	} else if (bits <= 256) {
2456 		if (hash_len)
2457 			*hash_len = 32;
2458 		ret = GNUTLS_DIG_SHA256;
2459 	} else if (bits <= 384) {
2460 		if (hash_len)
2461 			*hash_len = 48;
2462 		ret = GNUTLS_DIG_SHA384;
2463 	} else {
2464 		if (hash_len)
2465 			*hash_len = 64;
2466 		ret = GNUTLS_DIG_SHA512;
2467 	}
2468 
2469 	return mac_to_entry(ret);
2470 }
2471 
2472 /**
2473  * gnutls_pubkey_set_pin_function:
2474  * @key: A key of type #gnutls_pubkey_t
2475  * @fn: the callback
2476  * @userdata: data associated with the callback
2477  *
2478  * This function will set a callback function to be used when
2479  * required to access the object. This function overrides any other
2480  * global PIN functions.
2481  *
2482  * Note that this function must be called right after initialization
2483  * to have effect.
2484  *
2485  * Since: 3.1.0
2486  *
2487  **/
gnutls_pubkey_set_pin_function(gnutls_pubkey_t key,gnutls_pin_callback_t fn,void * userdata)2488 void gnutls_pubkey_set_pin_function(gnutls_pubkey_t key,
2489 				    gnutls_pin_callback_t fn,
2490 				    void *userdata)
2491 {
2492 	key->pin.cb = fn;
2493 	key->pin.data = userdata;
2494 }
2495 
2496 /**
2497  * gnutls_pubkey_import_x509_raw:
2498  * @pkey: The public key
2499  * @data: The public key data to be imported
2500  * @format: The format of the public key
2501  * @flags: should be zero
2502  *
2503  * This function will import the given public key to the abstract
2504  * #gnutls_pubkey_t type.
2505  *
2506  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2507  *   negative error value.
2508  *
2509  * Since: 3.1.3
2510  **/
gnutls_pubkey_import_x509_raw(gnutls_pubkey_t pkey,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format,unsigned int flags)2511 int gnutls_pubkey_import_x509_raw(gnutls_pubkey_t pkey,
2512 				  const gnutls_datum_t * data,
2513 				  gnutls_x509_crt_fmt_t format,
2514 				  unsigned int flags)
2515 {
2516 	gnutls_x509_crt_t xpriv;
2517 	int ret;
2518 
2519 	ret = gnutls_x509_crt_init(&xpriv);
2520 	if (ret < 0)
2521 		return gnutls_assert_val(ret);
2522 
2523 	ret = gnutls_x509_crt_import(xpriv, data, format);
2524 	if (ret < 0) {
2525 		gnutls_assert();
2526 		goto cleanup;
2527 	}
2528 
2529 	ret = gnutls_pubkey_import_x509(pkey, xpriv, flags);
2530 	if (ret < 0) {
2531 		gnutls_assert();
2532 		goto cleanup;
2533 	}
2534 
2535 	ret = 0;
2536 
2537       cleanup:
2538 	gnutls_x509_crt_deinit(xpriv);
2539 
2540 	return ret;
2541 }
2542 
2543 /**
2544  * gnutls_pubkey_verify_params:
2545  * @key: should contain a #gnutls_pubkey_t type
2546  *
2547  * This function will verify the public key parameters.
2548  *
2549  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2550  *   negative error value.
2551  *
2552  * Since: 3.3.0
2553  **/
gnutls_pubkey_verify_params(gnutls_pubkey_t key)2554 int gnutls_pubkey_verify_params(gnutls_pubkey_t key)
2555 {
2556 	int ret;
2557 
2558 	ret = _gnutls_pk_verify_pub_params(key->params.algo, &key->params);
2559 	if (ret < 0) {
2560 		gnutls_assert();
2561 		return ret;
2562 	}
2563 
2564 	return 0;
2565 }
2566 
2567 /**
2568  * gnutls_pubkey_get_spki:
2569  * @pubkey: a public key of type #gnutls_pubkey_t
2570  * @spki: a SubjectPublicKeyInfo structure of type #gnutls_pubkey_spki_t
2571  * @flags: must be zero
2572  *
2573  * This function will return the public key information if available.
2574  * The provided @spki must be initialized.
2575  *
2576  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2577  *   negative error value.
2578  *
2579  * Since: 3.6.0
2580  **/
2581 int
gnutls_pubkey_get_spki(gnutls_pubkey_t pubkey,gnutls_x509_spki_t spki,unsigned int flags)2582 gnutls_pubkey_get_spki(gnutls_pubkey_t pubkey, gnutls_x509_spki_t spki, unsigned int flags)
2583 {
2584 	if (pubkey == NULL) {
2585 		gnutls_assert();
2586 		return GNUTLS_E_INVALID_REQUEST;
2587 	}
2588 
2589 	if (pubkey->params.spki.pk == GNUTLS_PK_UNKNOWN)
2590 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2591 
2592 	memcpy(spki, &pubkey->params.spki, sizeof(gnutls_x509_spki_st));
2593 
2594 	return 0;
2595 }
2596 
2597 /**
2598  * gnutls_pubkey_set_spki:
2599  * @pubkey: a public key of type #gnutls_pubkey_t
2600  * @spki: a SubjectPublicKeyInfo structure of type #gnutls_pubkey_spki_t
2601  * @flags: must be zero
2602  *
2603  * This function will set the public key information.
2604  * The provided @spki must be initialized.
2605  *
2606  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2607  *   negative error value.
2608  *
2609  * Since: 3.6.0
2610  **/
2611 int
gnutls_pubkey_set_spki(gnutls_pubkey_t pubkey,const gnutls_x509_spki_t spki,unsigned int flags)2612 gnutls_pubkey_set_spki(gnutls_pubkey_t pubkey, const gnutls_x509_spki_t spki, unsigned int flags)
2613 {
2614 	if (pubkey == NULL) {
2615 		gnutls_assert();
2616 		return GNUTLS_E_INVALID_REQUEST;
2617 	}
2618 
2619 	if (!_gnutls_pk_are_compat(pubkey->params.algo, spki->pk))
2620                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2621 
2622 	memcpy(&pubkey->params.spki, spki, sizeof(gnutls_x509_spki_st));
2623 
2624 	pubkey->params.algo = spki->pk;
2625 
2626 	return 0;
2627 }
2628