1 /*
2  * Copyright (C) 2003-2012 Free Software Foundation, Inc.
3  * Copyright (C) 2015-2017 Red Hat, Inc.
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 <num.h>
32 #include <limits.h>
33 
34 /* Reads an Integer from the DER encoded data
35  */
36 
_gnutls_x509_read_der_int(uint8_t * der,int dersize,bigint_t * out)37 int _gnutls_x509_read_der_int(uint8_t * der, int dersize, bigint_t * out)
38 {
39 	int result;
40 	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
41 
42 	/* == INTEGER */
43 	if ((result = asn1_create_element
44 	     (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey",
45 	      &spk)) != ASN1_SUCCESS) {
46 		gnutls_assert();
47 		return _gnutls_asn2err(result);
48 	}
49 
50 	result = _asn1_strict_der_decode(&spk, der, dersize, NULL);
51 
52 	if (result != ASN1_SUCCESS) {
53 		gnutls_assert();
54 		asn1_delete_structure(&spk);
55 		return _gnutls_asn2err(result);
56 	}
57 
58 	/* Read Y */
59 
60 	if ((result = _gnutls_x509_read_int(spk, "", out)) < 0) {
61 		gnutls_assert();
62 		asn1_delete_structure(&spk);
63 		return _gnutls_asn2err(result);
64 	}
65 
66 	asn1_delete_structure(&spk);
67 
68 	return 0;
69 
70 }
71 
_gnutls_x509_read_der_uint(uint8_t * der,int dersize,unsigned int * out)72 int _gnutls_x509_read_der_uint(uint8_t * der, int dersize, unsigned int *out)
73 {
74 	int result;
75 	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
76 
77 	/* == INTEGER */
78 	if ((result = asn1_create_element
79 	     (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey",
80 	      &spk)) != ASN1_SUCCESS) {
81 		gnutls_assert();
82 		return _gnutls_asn2err(result);
83 	}
84 
85 	result = _asn1_strict_der_decode(&spk, der, dersize, NULL);
86 
87 	if (result != ASN1_SUCCESS) {
88 		gnutls_assert();
89 		asn1_delete_structure(&spk);
90 		return _gnutls_asn2err(result);
91 	}
92 
93 	/* Read Y */
94 
95 	if ((result = _gnutls_x509_read_uint(spk, "", out)) < 0) {
96 		gnutls_assert();
97 		asn1_delete_structure(&spk);
98 		return _gnutls_asn2err(result);
99 	}
100 
101 	asn1_delete_structure(&spk);
102 
103 	return 0;
104 
105 }
106 
107 
108 /* Extracts DSA and RSA parameters from a certificate.
109  */
110 int
_gnutls_get_asn_mpis(ASN1_TYPE asn,const char * root,gnutls_pk_params_st * params)111 _gnutls_get_asn_mpis(ASN1_TYPE asn, const char *root,
112 		     gnutls_pk_params_st * params)
113 {
114 	int result;
115 	char name[256];
116 	gnutls_datum_t tmp = { NULL, 0 };
117 	gnutls_pk_algorithm_t pk_algorithm;
118 	gnutls_ecc_curve_t curve;
119 
120 	gnutls_pk_params_init(params);
121 
122 	result = _gnutls_x509_get_pk_algorithm(asn, root, &curve, NULL);
123 	if (result < 0) {
124 		gnutls_assert();
125 		return result;
126 	}
127 
128 	pk_algorithm = result;
129 	params->curve = curve;
130 	params->algo = pk_algorithm;
131 
132 	/* Read the algorithm's parameters
133 	 */
134 	_asnstr_append_name(name, sizeof(name), root,
135 			    ".algorithm.parameters");
136 
137 	if (pk_algorithm != GNUTLS_PK_RSA &&
138 	    pk_algorithm != GNUTLS_PK_EDDSA_ED25519 && pk_algorithm != GNUTLS_PK_ECDH_X25519 &&
139 	    pk_algorithm != GNUTLS_PK_EDDSA_ED448 && pk_algorithm != GNUTLS_PK_ECDH_X448) {
140 		/* RSA and EdDSA do not use parameters */
141 		result = _gnutls_x509_read_value(asn, name, &tmp);
142 		if (pk_algorithm == GNUTLS_PK_RSA_PSS &&
143 		    (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND || result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)) {
144 			goto skip_params;
145 		}
146 		if (result < 0) {
147 			gnutls_assert();
148 			goto error;
149 		}
150 
151 		result =
152 		     _gnutls_x509_read_pubkey_params(pk_algorithm,
153 						     tmp.data, tmp.size,
154 						     params);
155 		if (result < 0) {
156 			gnutls_assert();
157 			goto error;
158 		}
159 
160 		_gnutls_free_datum(&tmp);
161 	}
162 
163  skip_params:
164 	/* Now read the public key */
165 	_asnstr_append_name(name, sizeof(name), root, ".subjectPublicKey");
166 
167 	result = _gnutls_x509_read_value(asn, name, &tmp);
168 	if (result < 0) {
169 		gnutls_assert();
170 		goto error;
171 	}
172 
173 	if ((result =
174 	     _gnutls_x509_read_pubkey(pk_algorithm, tmp.data, tmp.size,
175 				      params)) < 0) {
176 		gnutls_assert();
177 		goto error;
178 	}
179 
180 	result = _gnutls_x509_check_pubkey_params(params);
181 	if (result < 0) {
182 		gnutls_assert();
183 		goto error;
184 	}
185 
186 	result = 0;
187 
188  error:
189 	if (result < 0)
190 		gnutls_pk_params_release(params);
191 	_gnutls_free_datum(&tmp);
192 	return result;
193 }
194 
195 /* Extracts DSA and RSA parameters from a certificate.
196  */
197 int
_gnutls_x509_crt_get_mpis(gnutls_x509_crt_t cert,gnutls_pk_params_st * params)198 _gnutls_x509_crt_get_mpis(gnutls_x509_crt_t cert,
199 			  gnutls_pk_params_st * params)
200 {
201 	/* Read the algorithm's OID
202 	 */
203 	return _gnutls_get_asn_mpis(cert->cert,
204 				    "tbsCertificate.subjectPublicKeyInfo",
205 				    params);
206 }
207 
208 /* Extracts DSA and RSA parameters from a certificate.
209  */
210 int
_gnutls_x509_crq_get_mpis(gnutls_x509_crq_t cert,gnutls_pk_params_st * params)211 _gnutls_x509_crq_get_mpis(gnutls_x509_crq_t cert,
212 			  gnutls_pk_params_st * params)
213 {
214 	/* Read the algorithm's OID
215 	 */
216 	return _gnutls_get_asn_mpis(cert->crq,
217 				    "certificationRequestInfo.subjectPKInfo",
218 				    params);
219 }
220 
221 /*
222  * This function reads and decodes the parameters for DSS or RSA keys.
223  * This is the "signatureAlgorithm" fields.
224  */
225 int
_gnutls_x509_read_pkalgo_params(ASN1_TYPE src,const char * src_name,gnutls_x509_spki_st * spki,unsigned is_sig)226 _gnutls_x509_read_pkalgo_params(ASN1_TYPE src, const char *src_name,
227 			      gnutls_x509_spki_st *spki, unsigned is_sig)
228 {
229 	int result;
230 	char name[128];
231 	char oid[MAX_OID_SIZE];
232 	int oid_size;
233 
234 	memset(spki, 0, sizeof(*spki));
235 
236 	_gnutls_str_cpy(name, sizeof(name), src_name);
237 	_gnutls_str_cat(name, sizeof(name), ".algorithm");
238 
239 	oid_size = sizeof(oid);
240 	result = asn1_read_value(src, name, oid, &oid_size);
241 
242 	if (result != ASN1_SUCCESS) {
243 		gnutls_assert();
244 		return _gnutls_asn2err(result);
245 	}
246 
247 	if (strcmp (oid, PK_PKIX1_RSA_PSS_OID) == 0) {
248 		gnutls_datum_t tmp = { NULL, 0 };
249 
250 		_gnutls_str_cpy(name, sizeof(name), src_name);
251 		_gnutls_str_cat(name, sizeof(name), ".parameters");
252 
253 		result = _gnutls_x509_read_value(src, name, &tmp);
254 		if (result < 0) {
255 			if (!is_sig) {
256 				if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
257 				    result != GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
258 					/* it is ok to not have parameters in SPKI, but
259 					 * not in signatures */
260 					return 0;
261 				}
262 			}
263 
264 			return gnutls_assert_val(result);
265 		}
266 
267 		result = _gnutls_x509_read_rsa_pss_params(tmp.data, tmp.size,
268 							  spki);
269 		_gnutls_free_datum(&tmp);
270 
271 		if (result < 0)
272 			gnutls_assert();
273 
274 		return result;
275 	}
276 
277 	return 0;
278 }
279 
write_oid_and_params(ASN1_TYPE dst,const char * dst_name,const char * oid,gnutls_x509_spki_st * params)280 static int write_oid_and_params(ASN1_TYPE dst, const char *dst_name, const char *oid, gnutls_x509_spki_st *params)
281 {
282 	int result;
283 	char name[128];
284 
285 	if (params == NULL) {
286 		gnutls_assert();
287 		return GNUTLS_E_INVALID_REQUEST;
288 	}
289 
290 	_gnutls_str_cpy(name, sizeof(name), dst_name);
291 	_gnutls_str_cat(name, sizeof(name), ".algorithm");
292 
293 	/* write the OID.
294 	 */
295 	result = asn1_write_value(dst, name, oid, 1);
296 	if (result != ASN1_SUCCESS) {
297 		gnutls_assert();
298 		return _gnutls_asn2err(result);
299 	}
300 
301 	_gnutls_str_cpy(name, sizeof(name), dst_name);
302 	_gnutls_str_cat(name, sizeof(name), ".parameters");
303 
304 	if (params->pk == GNUTLS_PK_RSA)
305 		result =
306 		    asn1_write_value(dst, name, ASN1_NULL, ASN1_NULL_SIZE);
307 	else if (params->pk == GNUTLS_PK_RSA_PSS) {
308 		gnutls_datum_t tmp = { NULL, 0 };
309 
310 		result = _gnutls_x509_write_rsa_pss_params(params, &tmp);
311 		if (result < 0)
312 			return gnutls_assert_val(result);
313 
314 		result = asn1_write_value(dst, name, tmp.data, tmp.size);
315 		_gnutls_free_datum(&tmp);
316 	} else
317 		result = asn1_write_value(dst, name, NULL, 0);
318 
319 	if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) {
320 		/* Here we ignore the element not found error, since this
321 		 * may have been disabled before.
322 		 */
323 		gnutls_assert();
324 		return _gnutls_asn2err(result);
325 	}
326 
327 	return 0;
328 }
329 
330 int
_gnutls_x509_write_spki_params(ASN1_TYPE dst,const char * dst_name,gnutls_x509_spki_st * params)331 _gnutls_x509_write_spki_params(ASN1_TYPE dst, const char *dst_name,
332 			       gnutls_x509_spki_st *params)
333 {
334 	const char *oid;
335 
336 	if (params->legacy && params->pk == GNUTLS_PK_RSA)
337 		oid = PK_PKIX1_RSA_OID;
338 	else if (params->pk == GNUTLS_PK_RSA_PSS)
339 		oid = PK_PKIX1_RSA_PSS_OID;
340 	else
341 		oid = gnutls_pk_get_oid(params->pk);
342 
343 	if (oid == NULL) {
344 		gnutls_assert();
345 		_gnutls_debug_log
346 		    ("Cannot find OID for public key algorithm %s\n",
347 		     gnutls_pk_get_name(params->pk));
348 		return GNUTLS_E_INVALID_REQUEST;
349 	}
350 
351 	return write_oid_and_params(dst, dst_name, oid, params);
352 }
353 
354 int
_gnutls_x509_write_sign_params(ASN1_TYPE dst,const char * dst_name,const gnutls_sign_entry_st * se,gnutls_x509_spki_st * params)355 _gnutls_x509_write_sign_params(ASN1_TYPE dst, const char *dst_name,
356 			       const gnutls_sign_entry_st *se, gnutls_x509_spki_st *params)
357 {
358 	const char *oid;
359 
360 	if (params->legacy && params->pk == GNUTLS_PK_RSA)
361 		oid = PK_PKIX1_RSA_OID;
362 	else if (params->pk == GNUTLS_PK_RSA_PSS)
363 		oid = PK_PKIX1_RSA_PSS_OID;
364 	else
365 		oid = se->oid;
366 
367 	if (oid == NULL) {
368 		gnutls_assert();
369 		_gnutls_debug_log
370 		    ("Cannot find OID for sign algorithm %s\n",
371 		     se->name);
372 		return GNUTLS_E_INVALID_REQUEST;
373 	}
374 
375 	return write_oid_and_params(dst, dst_name, oid, params);
376 }
377 
378 /* this function reads a (small) unsigned integer
379  * from asn1 structs. Combines the read and the conversion
380  * steps.
381  */
382 int
_gnutls_x509_read_uint(ASN1_TYPE node,const char * value,unsigned int * ret)383 _gnutls_x509_read_uint(ASN1_TYPE node, const char *value,
384 		       unsigned int *ret)
385 {
386 	int len, result;
387 	uint8_t *tmpstr;
388 
389 	len = 0;
390 	result = asn1_read_value(node, value, NULL, &len);
391 	if (result != ASN1_MEM_ERROR) {
392 		return _gnutls_asn2err(result);
393 	}
394 
395 	tmpstr = gnutls_malloc(len);
396 	if (tmpstr == NULL) {
397 		gnutls_assert();
398 		return GNUTLS_E_MEMORY_ERROR;
399 	}
400 
401 	result = asn1_read_value(node, value, tmpstr, &len);
402 
403 	if (result != ASN1_SUCCESS) {
404 		gnutls_assert();
405 		gnutls_free(tmpstr);
406 		return _gnutls_asn2err(result);
407 	}
408 
409 	if (len == 1)
410 		*ret = tmpstr[0];
411 	else if (len == 2)
412 		*ret = _gnutls_read_uint16(tmpstr);
413 	else if (len == 3)
414 		*ret = _gnutls_read_uint24(tmpstr);
415 	else if (len == 4)
416 		*ret = _gnutls_read_uint32(tmpstr);
417 	else {
418 		gnutls_assert();
419 		gnutls_free(tmpstr);
420 		return GNUTLS_E_INTERNAL_ERROR;
421 	}
422 
423 	gnutls_free(tmpstr);
424 
425 	return 0;
426 }
427 
428 /* Writes the specified integer into the specified node.
429  */
430 int
_gnutls_x509_write_uint32(ASN1_TYPE node,const char * value,uint32_t num)431 _gnutls_x509_write_uint32(ASN1_TYPE node, const char *value, uint32_t num)
432 {
433 	uint8_t tmpstr[5];
434 	int result;
435 
436 	tmpstr[0] = 0;
437 	_gnutls_write_uint32(num, tmpstr+1);
438 
439 	if (tmpstr[1] > SCHAR_MAX) {
440 		result = asn1_write_value(node, value, tmpstr, 5);
441 	} else {
442 		result = asn1_write_value(node, value, tmpstr+1, 4);
443 	}
444 
445 	if (result != ASN1_SUCCESS) {
446 		gnutls_assert();
447 		return _gnutls_asn2err(result);
448 	}
449 
450 	return 0;
451 }
452