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