1 /*
2  * Copyright (C) 2011-2012 Free Software Foundation, Inc.
3  * Copyright (C) 2013-2017 Red Hat
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
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 
24 #include "gnutls_int.h"
25 #include "errors.h"
26 #include <global.h>
27 #include <libtasn1.h>
28 #include <datum.h>
29 #include "common.h"
30 #include "x509_int.h"
31 #include "pk.h"
32 #include <num.h>
33 #include <ecc.h>
34 
35 static int _gnutls_x509_read_rsa_pubkey(uint8_t * der, int dersize,
36 					gnutls_pk_params_st * params);
37 static int _gnutls_x509_read_dsa_pubkey(uint8_t * der, int dersize,
38 					gnutls_pk_params_st * params);
39 static int _gnutls_x509_read_ecc_pubkey(uint8_t * der, int dersize,
40 					gnutls_pk_params_st * params);
41 static int _gnutls_x509_read_eddsa_pubkey(gnutls_ecc_curve_t curve,
42 					  uint8_t * der, int dersize,
43 					  gnutls_pk_params_st * params);
44 static int _gnutls_x509_read_gost_pubkey(uint8_t * der, int dersize,
45 					gnutls_pk_params_st * params);
46 
47 static int
48 _gnutls_x509_read_dsa_params(uint8_t * der, int dersize,
49 			     gnutls_pk_params_st * params);
50 
51 /*
52  * some x509 certificate parsing functions that relate to MPI parameter
53  * extraction. This reads the BIT STRING subjectPublicKey.
54  * Returns 2 parameters (m,e). It does not set params_nr.
55  */
56 int
_gnutls_x509_read_rsa_pubkey(uint8_t * der,int dersize,gnutls_pk_params_st * params)57 _gnutls_x509_read_rsa_pubkey(uint8_t * der, int dersize,
58 			     gnutls_pk_params_st * params)
59 {
60 	int result;
61 	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
62 
63 	if ((result = asn1_create_element
64 	     (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk))
65 	    != ASN1_SUCCESS) {
66 		gnutls_assert();
67 		return _gnutls_asn2err(result);
68 	}
69 
70 	result = asn1_der_decoding(&spk, der, dersize, NULL);
71 
72 	if (result != ASN1_SUCCESS) {
73 		gnutls_assert();
74 		asn1_delete_structure(&spk);
75 		return _gnutls_asn2err(result);
76 	}
77 
78 
79 	if ((result =
80 	     _gnutls_x509_read_int(spk, "modulus",
81 				   &params->params[0])) < 0) {
82 		gnutls_assert();
83 		asn1_delete_structure(&spk);
84 		return GNUTLS_E_ASN1_GENERIC_ERROR;
85 	}
86 
87 	if ((result = _gnutls_x509_read_int(spk, "publicExponent",
88 					    &params->params[1])) < 0) {
89 		gnutls_assert();
90 		_gnutls_mpi_release(&params->params[0]);
91 		asn1_delete_structure(&spk);
92 		return GNUTLS_E_ASN1_GENERIC_ERROR;
93 	}
94 
95 	asn1_delete_structure(&spk);
96 
97 	return 0;
98 
99 }
100 
101 /*
102  * some x509 certificate parsing functions that relate to MPI parameter
103  * extraction. This reads the BIT STRING subjectPublicKey.
104  * Returns 2 parameters (m,e). It does not set params_nr.
105  */
106 int
_gnutls_x509_read_ecc_pubkey(uint8_t * der,int dersize,gnutls_pk_params_st * params)107 _gnutls_x509_read_ecc_pubkey(uint8_t * der, int dersize,
108 			     gnutls_pk_params_st * params)
109 {
110 	/* RFC5480 defines the public key to be an ECPoint (i.e. OCTET STRING),
111 	 * Then it says that the OCTET STRING _value_ is converted to BIT STRING.
112 	 * That means that the value we place there is the raw X9.62 one. */
113 	return _gnutls_ecc_ansi_x962_import(der, dersize,
114 					    &params->params[ECC_X],
115 					    &params->params[ECC_Y]);
116 }
117 
_gnutls_x509_read_eddsa_pubkey(gnutls_ecc_curve_t curve,uint8_t * der,int dersize,gnutls_pk_params_st * params)118 int _gnutls_x509_read_eddsa_pubkey(gnutls_ecc_curve_t curve,
119 				   uint8_t * der, int dersize,
120 				   gnutls_pk_params_st * params)
121 {
122 	int size = gnutls_ecc_curve_get_size(curve);
123 	if (dersize != size)
124 		return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
125 
126 	return _gnutls_set_datum(&params->raw_pub, der, dersize);
127 }
128 
129 /* Pubkey is a concatenation of X (in little endian) and Y (also LE)
130  * encoded into OCTET STRING. */
131 static int
_gnutls_x509_read_gost_pubkey(uint8_t * der,int dersize,gnutls_pk_params_st * params)132 _gnutls_x509_read_gost_pubkey(uint8_t * der, int dersize,
133 			     gnutls_pk_params_st * params)
134 {
135 	int ret;
136 	int len;
137 	bigint_t *x = &params->params[GOST_X];
138 	bigint_t *y = &params->params[GOST_Y];
139 
140 	/* Quick and dirty parsing of OCTET STRING of 0x40 or 0x80 bytes */
141 	if (dersize < 1 || der[0] != ASN1_TAG_OCTET_STRING) {
142 		return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
143 	}
144 
145 	der++;
146 	dersize--;
147 
148 	ret = asn1_get_length_der(der, dersize, &len);
149 	if (ret <= 0 || ret % 2 != 0 || dersize != len + ret) {
150 		return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
151 	}
152 
153 	der += len;
154 	dersize -= len;
155 
156 	/* read data */
157 	ret = _gnutls_mpi_init_scan_le(x, der, dersize / 2);
158 	if (ret < 0)
159 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
160 
161 	ret = _gnutls_mpi_init_scan_le(y, der + dersize / 2, dersize / 2);
162 	if (ret < 0) {
163 		_gnutls_mpi_release(y);
164 		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
165 	}
166 
167 	return 0;
168 }
169 
170 /* reads p,q and g
171  * from the certificate (subjectPublicKey BIT STRING).
172  * params[0-2]. It does NOT set params_nr.
173  */
174 static int
_gnutls_x509_read_dsa_params(uint8_t * der,int dersize,gnutls_pk_params_st * params)175 _gnutls_x509_read_dsa_params(uint8_t * der, int dersize,
176 			     gnutls_pk_params_st * params)
177 {
178 	int result;
179 	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
180 
181 	if ((result = asn1_create_element
182 	     (_gnutls_get_pkix(), "PKIX1.Dss-Parms",
183 	      &spk)) != ASN1_SUCCESS) {
184 		gnutls_assert();
185 		return _gnutls_asn2err(result);
186 	}
187 
188 	result = asn1_der_decoding(&spk, der, dersize, NULL);
189 
190 	if (result != ASN1_SUCCESS) {
191 		gnutls_assert();
192 		asn1_delete_structure(&spk);
193 		return _gnutls_asn2err(result);
194 	}
195 
196 	/* If the parameters are not included in the certificate
197 	 * then the issuer's parameters should be used. This is not
198 	 * implemented, and is not used in practice (along with DSA).
199 	 */
200 
201 	/* Read p */
202 
203 	if ((result =
204 	     _gnutls_x509_read_int(spk, "p", &params->params[0])) < 0) {
205 		gnutls_assert();
206 		asn1_delete_structure(&spk);
207 		return GNUTLS_E_ASN1_GENERIC_ERROR;
208 	}
209 
210 	/* Read q */
211 
212 	if ((result =
213 	     _gnutls_x509_read_int(spk, "q", &params->params[1])) < 0) {
214 		gnutls_assert();
215 		asn1_delete_structure(&spk);
216 		_gnutls_mpi_release(&params->params[0]);
217 		return GNUTLS_E_ASN1_GENERIC_ERROR;
218 	}
219 
220 	/* Read g */
221 
222 	if ((result =
223 	     _gnutls_x509_read_int(spk, "g", &params->params[2])) < 0) {
224 		gnutls_assert();
225 		asn1_delete_structure(&spk);
226 		_gnutls_mpi_release(&params->params[0]);
227 		_gnutls_mpi_release(&params->params[1]);
228 		return GNUTLS_E_ASN1_GENERIC_ERROR;
229 	}
230 
231 	asn1_delete_structure(&spk);
232 
233 	params->params_nr = 3; /* public key is missing */
234 	params->algo = GNUTLS_PK_DSA;
235 
236 	return 0;
237 
238 }
239 
240 /* reads the curve from the certificate.
241  * params[0-4]. It does NOT set params_nr.
242  */
243 int
_gnutls_x509_read_ecc_params(uint8_t * der,int dersize,unsigned int * curve)244 _gnutls_x509_read_ecc_params(uint8_t * der, int dersize,
245 			     unsigned int * curve)
246 {
247 	int ret;
248 	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
249 	char oid[MAX_OID_SIZE];
250 	int oid_size;
251 
252 	if ((ret = asn1_create_element
253 	     (_gnutls_get_gnutls_asn(), "GNUTLS.ECParameters",
254 	      &spk)) != ASN1_SUCCESS) {
255 		gnutls_assert();
256 		return _gnutls_asn2err(ret);
257 	}
258 
259 	ret = asn1_der_decoding(&spk, der, dersize, NULL);
260 
261 	if (ret != ASN1_SUCCESS) {
262 		gnutls_assert();
263 		ret = _gnutls_asn2err(ret);
264 		goto cleanup;
265 	}
266 
267 	/* read the curve */
268 	oid_size = sizeof(oid);
269 	ret = asn1_read_value(spk, "namedCurve", oid, &oid_size);
270 	if (ret != ASN1_SUCCESS) {
271 		gnutls_assert();
272 		ret = _gnutls_asn2err(ret);
273 		goto cleanup;
274 	}
275 
276 	*curve = gnutls_oid_to_ecc_curve(oid);
277 	if (*curve == GNUTLS_ECC_CURVE_INVALID) {
278 		_gnutls_debug_log("Curve %s is not supported\n", oid);
279 		gnutls_assert();
280 		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
281 		goto cleanup;
282 	}
283 
284 	ret = 0;
285 
286       cleanup:
287 
288 	asn1_delete_structure(&spk);
289 
290 	return ret;
291 
292 }
293 
294 /* Reads RSA-PSS parameters.
295  */
296 int
_gnutls_x509_read_rsa_pss_params(uint8_t * der,int dersize,gnutls_x509_spki_st * params)297 _gnutls_x509_read_rsa_pss_params(uint8_t * der, int dersize,
298 				 gnutls_x509_spki_st * params)
299 {
300 	int result;
301 	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
302 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
303 	gnutls_digest_algorithm_t digest;
304 	char oid[MAX_OID_SIZE] = "";
305 	int size;
306 	unsigned int trailer;
307 	gnutls_datum_t value = { NULL, 0 };
308 
309 	if ((result = asn1_create_element
310 	     (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPSSParameters", &spk))
311 	    != ASN1_SUCCESS) {
312 		gnutls_assert();
313 		result = _gnutls_asn2err(result);
314 		goto cleanup;
315 	}
316 
317 	result = _asn1_strict_der_decode(&spk, der, dersize, NULL);
318 
319 	if (result != ASN1_SUCCESS) {
320 		gnutls_assert();
321 		result = _gnutls_asn2err(result);
322 		goto cleanup;
323 	}
324 
325 	size = sizeof(oid);
326 	result = asn1_read_value(spk, "hashAlgorithm.algorithm", oid, &size);
327 	if (result == ASN1_SUCCESS)
328 		digest = gnutls_oid_to_digest(oid);
329 	else if (result == ASN1_ELEMENT_NOT_FOUND)
330 		/* The default hash algorithm is SHA-1 */
331 		digest = GNUTLS_DIG_SHA1;
332 	else {
333 		gnutls_assert();
334 		result = _gnutls_asn2err(result);
335 		goto cleanup;
336 	}
337 
338 	if (digest == GNUTLS_DIG_UNKNOWN) {
339 		gnutls_assert();
340 		_gnutls_debug_log("Unknown RSA-PSS hash: %s\n", oid);
341 		result = GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
342 		goto cleanup;
343 	}
344 
345 	size = sizeof(oid);
346 	result = asn1_read_value(spk, "maskGenAlgorithm.algorithm", oid, &size);
347 	if (result == ASN1_SUCCESS) {
348 		gnutls_digest_algorithm_t digest2;
349 
350 		/* Error out if algorithm other than mgf1 is specified */
351 		if (strcmp(oid, PKIX1_RSA_PSS_MGF1_OID) != 0) {
352 			gnutls_assert();
353 			_gnutls_debug_log("Unknown mask algorithm: %s\n", oid);
354 			result = GNUTLS_E_UNKNOWN_ALGORITHM;
355 			goto cleanup;
356 		}
357 
358 		/* Check if maskGenAlgorithm.parameters does exist and
359 		 * is identical to hashAlgorithm */
360 		result = _gnutls_x509_read_value(spk, "maskGenAlgorithm.parameters", &value);
361 		if (result < 0) {
362 			gnutls_assert();
363 			goto cleanup;
364 		}
365 
366 		if ((result = asn1_create_element
367 		     (_gnutls_get_pkix(), "PKIX1.AlgorithmIdentifier", &c2))
368 		    != ASN1_SUCCESS) {
369 			gnutls_assert();
370 			result = _gnutls_asn2err(result);
371 			goto cleanup;
372 		}
373 
374 		result = _asn1_strict_der_decode(&c2, value.data, value.size, NULL);
375 		if (result != ASN1_SUCCESS) {
376 			gnutls_assert();
377 			result = _gnutls_asn2err(result);
378 			goto cleanup;
379 		}
380 
381 		size = sizeof(oid);
382 		result = asn1_read_value(c2, "algorithm", oid, &size);
383 		if (result == ASN1_SUCCESS)
384 			digest2 = gnutls_oid_to_digest(oid);
385 		else if (result == ASN1_ELEMENT_NOT_FOUND)
386 			/* The default hash algorithm for mgf1 is SHA-1 */
387 			digest2 = GNUTLS_DIG_SHA1;
388 		else {
389 			gnutls_assert();
390 			result = _gnutls_asn2err(result);
391 			goto cleanup;
392 		}
393 
394 		if (digest != digest2) {
395 			gnutls_assert();
396 			result = GNUTLS_E_CONSTRAINT_ERROR;
397 			goto cleanup;
398 		}
399 	} else if (result != ASN1_ELEMENT_NOT_FOUND) {
400 		gnutls_assert();
401 		result = _gnutls_asn2err(result);
402 		goto cleanup;
403 	}
404 
405 	memset(params, 0, sizeof(gnutls_x509_spki_st));
406 	params->pk = GNUTLS_PK_RSA_PSS;
407 	params->rsa_pss_dig = digest;
408 
409 	result = _gnutls_x509_read_uint(spk, "saltLength", &params->salt_size);
410 	if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
411 	    result == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
412 		params->salt_size = 20;
413 	else if (result < 0) {
414 		gnutls_assert();
415 		goto cleanup;
416 	}
417 
418 	result = _gnutls_x509_read_uint(spk, "trailerField", &trailer);
419 	if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
420 	    result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
421 		trailer = 1;
422 	else if (result < 0) {
423 		gnutls_assert();
424 		goto cleanup;
425 	}
426 	if (trailer != 1) {
427 		gnutls_assert();
428 		result = GNUTLS_E_CERTIFICATE_ERROR;
429 		goto cleanup;
430 	}
431 
432 	result = 0;
433  cleanup:
434 	_gnutls_free_datum(&value);
435 	asn1_delete_structure(&c2);
436 	asn1_delete_structure(&spk);
437 	return result;
438 }
439 
440 /* reads the curve from the certificate.
441  * It does NOT set params_nr.
442  */
443 int
_gnutls_x509_read_gost_params(uint8_t * der,int dersize,gnutls_pk_params_st * params,gnutls_pk_algorithm_t algo)444 _gnutls_x509_read_gost_params(uint8_t * der, int dersize,
445 			      gnutls_pk_params_st * params,
446 			      gnutls_pk_algorithm_t algo)
447 {
448 	int ret;
449 	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
450 	char oid[MAX_OID_SIZE];
451 	int oid_size;
452 	gnutls_ecc_curve_t curve;
453 	gnutls_gost_paramset_t param;
454 
455 	if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
456 				       algo == GNUTLS_PK_GOST_01 ?
457 				       "GNUTLS.GOSTParametersOld" :
458 				       "GNUTLS.GOSTParameters",
459 				       &spk)) != ASN1_SUCCESS) {
460 		gnutls_assert();
461 		return _gnutls_asn2err(ret);
462 	}
463 
464 	ret = _asn1_strict_der_decode(&spk, der, dersize, NULL);
465 
466 	if (ret != ASN1_SUCCESS) {
467 		gnutls_assert();
468 		ret = _gnutls_asn2err(ret);
469 		goto cleanup;
470 	}
471 
472 	/* read the curve */
473 	oid_size = sizeof(oid);
474 	ret = asn1_read_value(spk, "publicKeyParamSet", oid, &oid_size);
475 	if (ret != ASN1_SUCCESS) {
476 		gnutls_assert();
477 		ret = _gnutls_asn2err(ret);
478 		goto cleanup;
479 	}
480 
481 	curve = gnutls_oid_to_ecc_curve(oid);
482 	if (curve == GNUTLS_ECC_CURVE_INVALID) {
483 		_gnutls_debug_log("Curve %s is not supported\n", oid);
484 		gnutls_assert();
485 		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
486 		goto cleanup;
487 	}
488 
489 	/* Read the digest */
490 	oid_size = sizeof(oid);
491 	ret = asn1_read_value(spk, "digestParamSet", oid, &oid_size);
492 	if (ret != ASN1_SUCCESS &&
493 	    ret != ASN1_ELEMENT_NOT_FOUND) {
494 		gnutls_assert();
495 		ret = _gnutls_asn2err(ret);
496 		goto cleanup;
497 	}
498 	/* For now ignore the OID: we use pk OID instead */
499 
500 	oid_size = sizeof(oid);
501 	ret = asn1_read_value(spk, "encryptionParamSet", oid, &oid_size);
502 	if (ret != ASN1_SUCCESS &&
503 	    ret != ASN1_ELEMENT_NOT_FOUND) {
504 		gnutls_assert();
505 		ret = _gnutls_asn2err(ret);
506 		goto cleanup;
507 	}
508 
509 	if (ret != ASN1_ELEMENT_NOT_FOUND)
510 		param = gnutls_oid_to_gost_paramset(oid);
511 	else
512 		param = _gnutls_gost_paramset_default(algo);
513 
514 	if (param == GNUTLS_GOST_PARAMSET_UNKNOWN) {
515 		gnutls_assert();
516 		ret = param;
517 		goto cleanup;
518 	}
519 
520 	params->curve = curve;
521 	params->gost_params = param;
522 	ret = 0;
523 
524       cleanup:
525 
526 	asn1_delete_structure(&spk);
527 
528 	return ret;
529 
530 }
531 
532 /* This function must be called after _gnutls_x509_read_params()
533  */
_gnutls_x509_read_pubkey(gnutls_pk_algorithm_t algo,uint8_t * der,int dersize,gnutls_pk_params_st * params)534 int _gnutls_x509_read_pubkey(gnutls_pk_algorithm_t algo, uint8_t * der,
535 			     int dersize, gnutls_pk_params_st * params)
536 {
537 	int ret;
538 
539 	switch (algo) {
540 	case GNUTLS_PK_RSA:
541 	case GNUTLS_PK_RSA_PSS:
542 		ret = _gnutls_x509_read_rsa_pubkey(der, dersize, params);
543 		if (ret >= 0) {
544 			params->algo = algo;
545 			params->params_nr = RSA_PUBLIC_PARAMS;
546 		}
547 		break;
548 	case GNUTLS_PK_DSA:
549 		if (params->params_nr != 3) /* _gnutls_x509_read_pubkey_params must have been called */
550 			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
551 
552 		ret = _gnutls_x509_read_dsa_pubkey(der, dersize, params);
553 		if (ret >= 0) {
554 			params->algo = GNUTLS_PK_DSA;
555 			params->params_nr = DSA_PUBLIC_PARAMS;
556 		}
557 		break;
558 	case GNUTLS_PK_ECDSA:
559 		ret = _gnutls_x509_read_ecc_pubkey(der, dersize, params);
560 		if (ret >= 0) {
561 			params->algo = GNUTLS_PK_ECDSA;
562 			params->params_nr = ECC_PUBLIC_PARAMS;
563 		}
564 		break;
565 	case GNUTLS_PK_EDDSA_ED25519:
566 		ret = _gnutls_x509_read_eddsa_pubkey(GNUTLS_ECC_CURVE_ED25519, der, dersize, params);
567 		break;
568 	case GNUTLS_PK_EDDSA_ED448:
569 		ret = _gnutls_x509_read_eddsa_pubkey(GNUTLS_ECC_CURVE_ED448, der, dersize, params);
570 		break;
571 	case GNUTLS_PK_GOST_01:
572 	case GNUTLS_PK_GOST_12_256:
573 	case GNUTLS_PK_GOST_12_512:
574 		ret = _gnutls_x509_read_gost_pubkey(der, dersize, params);
575 		if (ret >= 0) {
576 			params->algo = algo;
577 			params->params_nr = GOST_PUBLIC_PARAMS;
578 		}
579 		break;
580 	default:
581 		ret = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
582 		break;
583 	}
584 	return ret;
585 }
586 
587 /* This function must be called prior to _gnutls_x509_read_pubkey()
588  */
_gnutls_x509_read_pubkey_params(gnutls_pk_algorithm_t algo,uint8_t * der,int dersize,gnutls_pk_params_st * params)589 int _gnutls_x509_read_pubkey_params(gnutls_pk_algorithm_t algo,
590 				    uint8_t * der, int dersize,
591 				    gnutls_pk_params_st * params)
592 {
593 	switch (algo) {
594 	case GNUTLS_PK_RSA:
595 	case GNUTLS_PK_EDDSA_ED25519:
596 	case GNUTLS_PK_EDDSA_ED448:
597 		return 0;
598 	case GNUTLS_PK_RSA_PSS:
599 		return _gnutls_x509_read_rsa_pss_params(der, dersize, &params->spki);
600 	case GNUTLS_PK_DSA:
601 		return _gnutls_x509_read_dsa_params(der, dersize, params);
602 	case GNUTLS_PK_EC:
603 		return _gnutls_x509_read_ecc_params(der, dersize, &params->curve);
604 	case GNUTLS_PK_GOST_01:
605 	case GNUTLS_PK_GOST_12_256:
606 	case GNUTLS_PK_GOST_12_512:
607 		return _gnutls_x509_read_gost_params(der, dersize, params, algo);
608 	default:
609 		return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
610 	}
611 }
612 
613 /* This function must be called after _gnutls_x509_read_pubkey()
614  */
_gnutls_x509_check_pubkey_params(gnutls_pk_params_st * params)615 int _gnutls_x509_check_pubkey_params(gnutls_pk_params_st * params)
616 {
617 	switch (params->algo) {
618 	case GNUTLS_PK_RSA_PSS: {
619 		unsigned bits;
620 		const mac_entry_st *me;
621 		size_t hash_size;
622 
623 		if (params->spki.pk == GNUTLS_PK_UNKNOWN) /* no params present */
624 			return 0;
625 
626 		bits = pubkey_to_bits(params);
627 
628 		me = hash_to_entry(params->spki.rsa_pss_dig);
629 		if (unlikely(me == NULL))
630 			return gnutls_assert_val(GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
631 
632 		hash_size = _gnutls_hash_get_algo_len(me);
633 		if (hash_size + params->spki.salt_size + 2 > (bits + 7) / 8)
634 			return gnutls_assert_val(GNUTLS_E_PK_INVALID_PUBKEY_PARAMS);
635 		return 0;
636 	}
637 	case GNUTLS_PK_RSA:
638 	case GNUTLS_PK_DSA:
639 	case GNUTLS_PK_ECDSA:
640 	case GNUTLS_PK_EDDSA_ED25519:
641 	case GNUTLS_PK_EDDSA_ED448:
642 	case GNUTLS_PK_GOST_01:
643 	case GNUTLS_PK_GOST_12_256:
644 	case GNUTLS_PK_GOST_12_512:
645 		return 0;
646 	default:
647 		return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
648 	}
649 }
650 
651 /* reads DSA's Y
652  * from the certificate
653  * only sets params[3]
654  */
655 int
_gnutls_x509_read_dsa_pubkey(uint8_t * der,int dersize,gnutls_pk_params_st * params)656 _gnutls_x509_read_dsa_pubkey(uint8_t * der, int dersize,
657 			     gnutls_pk_params_st * params)
658 {
659 	return _gnutls_x509_read_der_int(der, dersize, &params->params[3]);
660 }
661