Coverage Report

Created: 2024-06-20 06:28

/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
    /* RSA and EdDSA do not use parameters */
138
0
    result = _gnutls_x509_read_value(asn, name, &tmp);
139
0
    if (pk_algorithm == GNUTLS_PK_RSA_PSS &&
140
0
        (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
141
0
         result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)) {
142
0
      goto skip_params;
143
0
    }
144
0
    if (result < 0) {
145
0
      gnutls_assert();
146
0
      goto error;
147
0
    }
148
149
0
    result = _gnutls_x509_read_pubkey_params(pk_algorithm, tmp.data,
150
0
               tmp.size, params);
151
0
    if (result < 0) {
152
0
      gnutls_assert();
153
0
      goto error;
154
0
    }
155
156
0
    _gnutls_free_datum(&tmp);
157
0
  }
158
159
0
skip_params:
160
  /* Now read the public key */
161
0
  _asnstr_append_name(name, sizeof(name), root, ".subjectPublicKey");
162
163
0
  result = _gnutls_x509_read_value(asn, name, &tmp);
164
0
  if (result < 0) {
165
0
    gnutls_assert();
166
0
    goto error;
167
0
  }
168
169
0
  if ((result = _gnutls_x509_read_pubkey(pk_algorithm, tmp.data, tmp.size,
170
0
                 params)) < 0) {
171
0
    gnutls_assert();
172
0
    goto error;
173
0
  }
174
175
0
  result = _gnutls_x509_check_pubkey_params(params);
176
0
  if (result < 0) {
177
0
    gnutls_assert();
178
0
    goto error;
179
0
  }
180
181
0
  result = 0;
182
183
0
error:
184
0
  if (result < 0)
185
0
    gnutls_pk_params_release(params);
186
0
  _gnutls_free_datum(&tmp);
187
0
  return result;
188
0
}
189
190
/* Extracts DSA and RSA parameters from a certificate.
191
 */
192
int _gnutls_x509_crt_get_mpis(gnutls_x509_crt_t cert,
193
            gnutls_pk_params_st *params)
194
0
{
195
  /* Read the algorithm's OID
196
   */
197
0
  return _gnutls_get_asn_mpis(
198
0
    cert->cert, "tbsCertificate.subjectPublicKeyInfo", params);
199
0
}
200
201
/* Extracts DSA and RSA parameters from a certificate.
202
 */
203
int _gnutls_x509_crq_get_mpis(gnutls_x509_crq_t cert,
204
            gnutls_pk_params_st *params)
205
0
{
206
  /* Read the algorithm's OID
207
   */
208
0
  return _gnutls_get_asn_mpis(
209
0
    cert->crq, "certificationRequestInfo.subjectPKInfo", params);
210
0
}
211
212
/*
213
 * This function reads and decodes the parameters for DSS or RSA keys.
214
 * This is the "signatureAlgorithm" fields.
215
 */
216
int _gnutls_x509_read_pkalgo_params(asn1_node src, const char *src_name,
217
            gnutls_x509_spki_st *spki, unsigned is_sig)
218
0
{
219
0
  int result;
220
0
  char name[128];
221
0
  char oid[MAX_OID_SIZE];
222
0
  int oid_size;
223
224
0
  memset(spki, 0, sizeof(*spki));
225
226
0
  _gnutls_str_cpy(name, sizeof(name), src_name);
227
0
  _gnutls_str_cat(name, sizeof(name), ".algorithm");
228
229
0
  oid_size = sizeof(oid);
230
0
  result = asn1_read_value(src, name, oid, &oid_size);
231
232
0
  if (result != ASN1_SUCCESS) {
233
0
    gnutls_assert();
234
0
    return _gnutls_asn2err(result);
235
0
  }
236
237
0
  if (strcmp(oid, PK_PKIX1_RSA_PSS_OID) == 0) {
238
0
    gnutls_datum_t tmp = { NULL, 0 };
239
240
0
    _gnutls_str_cpy(name, sizeof(name), src_name);
241
0
    _gnutls_str_cat(name, sizeof(name), ".parameters");
242
243
0
    result = _gnutls_x509_read_value(src, name, &tmp);
244
0
    if (result < 0) {
245
0
      if (!is_sig) {
246
0
        if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
247
0
            result != GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
248
          /* it is ok to not have parameters in SPKI, but
249
           * not in signatures */
250
0
          return 0;
251
0
        }
252
0
      }
253
254
0
      return gnutls_assert_val(result);
255
0
    }
256
257
0
    result = _gnutls_x509_read_rsa_pss_params(tmp.data, tmp.size,
258
0
                spki);
259
0
    _gnutls_free_datum(&tmp);
260
261
0
    if (result < 0)
262
0
      gnutls_assert();
263
264
0
    return result;
265
0
  }
266
267
0
  return 0;
268
0
}
269
270
static int write_oid_and_params(asn1_node dst, const char *dst_name,
271
        const char *oid, gnutls_x509_spki_st *params)
272
0
{
273
0
  int result;
274
0
  char name[128];
275
276
0
  if (params == NULL) {
277
0
    gnutls_assert();
278
0
    return GNUTLS_E_INVALID_REQUEST;
279
0
  }
280
281
0
  _gnutls_str_cpy(name, sizeof(name), dst_name);
282
0
  _gnutls_str_cat(name, sizeof(name), ".algorithm");
283
284
  /* write the OID.
285
   */
286
0
  result = asn1_write_value(dst, name, oid, 1);
287
0
  if (result != ASN1_SUCCESS) {
288
0
    gnutls_assert();
289
0
    return _gnutls_asn2err(result);
290
0
  }
291
292
0
  _gnutls_str_cpy(name, sizeof(name), dst_name);
293
0
  _gnutls_str_cat(name, sizeof(name), ".parameters");
294
295
0
  if (params->pk == GNUTLS_PK_RSA)
296
0
    result = asn1_write_value(dst, name, ASN1_NULL, ASN1_NULL_SIZE);
297
0
  else if (params->pk == GNUTLS_PK_RSA_PSS) {
298
0
    gnutls_datum_t tmp = { NULL, 0 };
299
300
0
    result = _gnutls_x509_write_rsa_pss_params(params, &tmp);
301
0
    if (result < 0)
302
0
      return gnutls_assert_val(result);
303
304
0
    result = asn1_write_value(dst, name, tmp.data, tmp.size);
305
0
    _gnutls_free_datum(&tmp);
306
0
  } else
307
0
    result = asn1_write_value(dst, name, NULL, 0);
308
309
0
  if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) {
310
    /* Here we ignore the element not found error, since this
311
     * may have been disabled before.
312
     */
313
0
    gnutls_assert();
314
0
    return _gnutls_asn2err(result);
315
0
  }
316
317
0
  return 0;
318
0
}
319
320
int _gnutls_x509_write_spki_params(asn1_node dst, const char *dst_name,
321
           gnutls_x509_spki_st *params)
322
0
{
323
0
  const char *oid;
324
325
0
  if (params->legacy && params->pk == GNUTLS_PK_RSA)
326
0
    oid = PK_PKIX1_RSA_OID;
327
0
  else if (params->pk == GNUTLS_PK_RSA_PSS)
328
0
    oid = PK_PKIX1_RSA_PSS_OID;
329
0
  else
330
0
    oid = gnutls_pk_get_oid(params->pk);
331
332
0
  if (oid == NULL) {
333
0
    gnutls_assert();
334
0
    _gnutls_debug_log(
335
0
      "Cannot find OID for public key algorithm %s\n",
336
0
      gnutls_pk_get_name(params->pk));
337
0
    return GNUTLS_E_INVALID_REQUEST;
338
0
  }
339
340
0
  return write_oid_and_params(dst, dst_name, oid, params);
341
0
}
342
343
int _gnutls_x509_write_sign_params(asn1_node dst, const char *dst_name,
344
           const gnutls_sign_entry_st *se,
345
           gnutls_x509_spki_st *params)
346
0
{
347
0
  const char *oid;
348
349
0
  if (params->legacy && params->pk == GNUTLS_PK_RSA)
350
0
    oid = PK_PKIX1_RSA_OID;
351
0
  else if (params->pk == GNUTLS_PK_RSA_PSS)
352
0
    oid = PK_PKIX1_RSA_PSS_OID;
353
0
  else
354
0
    oid = se->oid;
355
356
0
  if (oid == NULL) {
357
0
    gnutls_assert();
358
0
    _gnutls_debug_log("Cannot find OID for sign algorithm %s\n",
359
0
          se->name);
360
0
    return GNUTLS_E_INVALID_REQUEST;
361
0
  }
362
363
0
  return write_oid_and_params(dst, dst_name, oid, params);
364
0
}
365
366
/* this function reads a (small) unsigned integer
367
 * from asn1 structs. Combines the read and the conversion
368
 * steps.
369
 */
370
int _gnutls_x509_read_uint(asn1_node node, const char *value, unsigned int *ret)
371
0
{
372
0
  int len, result;
373
0
  uint8_t *tmpstr;
374
375
0
  len = 0;
376
0
  result = asn1_read_value(node, value, NULL, &len);
377
0
  if (result != ASN1_MEM_ERROR) {
378
0
    return _gnutls_asn2err(result);
379
0
  }
380
381
0
  tmpstr = gnutls_malloc(len);
382
0
  if (tmpstr == NULL) {
383
0
    gnutls_assert();
384
0
    return GNUTLS_E_MEMORY_ERROR;
385
0
  }
386
387
0
  result = asn1_read_value(node, value, tmpstr, &len);
388
389
0
  if (result != ASN1_SUCCESS) {
390
0
    gnutls_assert();
391
0
    gnutls_free(tmpstr);
392
0
    return _gnutls_asn2err(result);
393
0
  }
394
395
0
  if (len == 1)
396
0
    *ret = tmpstr[0];
397
0
  else if (len == 2)
398
0
    *ret = _gnutls_read_uint16(tmpstr);
399
0
  else if (len == 3)
400
0
    *ret = _gnutls_read_uint24(tmpstr);
401
0
  else if (len == 4)
402
0
    *ret = _gnutls_read_uint32(tmpstr);
403
0
  else {
404
0
    gnutls_assert();
405
0
    gnutls_free(tmpstr);
406
0
    return GNUTLS_E_INTERNAL_ERROR;
407
0
  }
408
409
0
  gnutls_free(tmpstr);
410
411
0
  return 0;
412
0
}
413
414
/* Writes the specified integer into the specified node.
415
 */
416
int _gnutls_x509_write_uint32(asn1_node node, const char *value, uint32_t num)
417
0
{
418
0
  uint8_t tmpstr[5];
419
0
  int result;
420
421
0
  tmpstr[0] = 0;
422
0
  _gnutls_write_uint32(num, tmpstr + 1);
423
424
0
  if (tmpstr[1] > SCHAR_MAX) {
425
0
    result = asn1_write_value(node, value, tmpstr, 5);
426
0
  } else {
427
0
    result = asn1_write_value(node, value, tmpstr + 1, 4);
428
0
  }
429
430
0
  if (result != ASN1_SUCCESS) {
431
0
    gnutls_assert();
432
0
    return _gnutls_asn2err(result);
433
0
  }
434
435
0
  return 0;
436
0
}