Coverage Report

Created: 2023-03-26 07:33

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