Coverage Report

Created: 2025-03-06 07:58

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