Coverage Report

Created: 2026-02-14 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/x509/common.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2003-2014 Free Software Foundation, Inc.
3
 * Copyright (C) 2015-2016 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 <libtasn1.h>
26
#include "datum.h"
27
#include "global.h"
28
#include "errors.h"
29
#include "str.h"
30
#include "x509.h"
31
#include "num.h"
32
#include "x509_b64.h"
33
#include <c-strcase.h>
34
#include "intprops.h"
35
#include "x509_int.h"
36
#include "extras/hex.h"
37
#include "common.h"
38
39
static int data2hex(const void *data, size_t data_size, gnutls_datum_t *out);
40
41
#define ENTRY(oid, ldap, asn, etype) \
42
  { oid, sizeof(oid) - 1, ldap, sizeof(ldap) - 1, asn, etype }
43
44
/* when there is no name description */
45
#define ENTRY_ND(oid, asn, etype) { oid, sizeof(oid) - 1, NULL, 0, asn, etype }
46
47
/* This list contains all the OIDs that may be
48
 * contained in a rdnSequence and are printable.
49
 */
50
static const struct oid_to_string _oid2str[] = {
51
  /* PKIX
52
   */
53
  ENTRY("1.3.6.1.5.5.7.9.2", "placeOfBirth", "PKIX1.DirectoryString",
54
        ASN1_ETYPE_INVALID),
55
  ENTRY("1.3.6.1.5.5.7.9.3", "gender", NULL, ASN1_ETYPE_PRINTABLE_STRING),
56
  ENTRY("1.3.6.1.5.5.7.9.4", "countryOfCitizenship", NULL,
57
        ASN1_ETYPE_PRINTABLE_STRING),
58
  ENTRY("1.3.6.1.5.5.7.9.5", "countryOfResidence", NULL,
59
        ASN1_ETYPE_PRINTABLE_STRING),
60
61
  ENTRY("2.5.4.6", "C", NULL, ASN1_ETYPE_PRINTABLE_STRING),
62
  ENTRY("2.5.4.9", "street", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
63
  ENTRY("2.5.4.12", "title", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
64
  ENTRY("2.5.4.10", "O", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
65
  ENTRY("2.5.4.11", "OU", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
66
  ENTRY("2.5.4.3", "CN", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
67
  ENTRY("2.5.4.7", "L", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
68
  ENTRY("2.5.4.8", "ST", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
69
  ENTRY("2.5.4.13", "description", "PKIX1.DirectoryString",
70
        ASN1_ETYPE_INVALID),
71
72
  ENTRY("2.5.4.5", "serialNumber", NULL, ASN1_ETYPE_PRINTABLE_STRING),
73
  ENTRY("2.5.4.20", "telephoneNumber", NULL, ASN1_ETYPE_PRINTABLE_STRING),
74
  ENTRY("2.5.4.4", "surName", "PKIX1.DirectoryString",
75
        ASN1_ETYPE_INVALID),
76
  ENTRY("2.5.4.43", "initials", "PKIX1.DirectoryString",
77
        ASN1_ETYPE_INVALID),
78
  ENTRY("2.5.4.44", "generationQualifier", "PKIX1.DirectoryString",
79
        ASN1_ETYPE_INVALID),
80
  ENTRY("2.5.4.42", "givenName", "PKIX1.DirectoryString",
81
        ASN1_ETYPE_INVALID),
82
  ENTRY("2.5.4.65", "pseudonym", "PKIX1.DirectoryString",
83
        ASN1_ETYPE_INVALID),
84
  ENTRY("2.5.4.46", "dnQualifier", NULL, ASN1_ETYPE_PRINTABLE_STRING),
85
  ENTRY("2.5.4.17", "postalCode", "PKIX1.DirectoryString",
86
        ASN1_ETYPE_INVALID),
87
  ENTRY("2.5.4.41", "name", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
88
  ENTRY("2.5.4.15", "businessCategory", "PKIX1.DirectoryString",
89
        ASN1_ETYPE_INVALID),
90
91
  ENTRY("0.9.2342.19200300.100.1.25", "DC", NULL, ASN1_ETYPE_IA5_STRING),
92
  ENTRY("0.9.2342.19200300.100.1.1", "UID", "PKIX1.DirectoryString",
93
        ASN1_ETYPE_INVALID),
94
  ENTRY("1.2.840.113556.1.4.656", "userPrincipalName",
95
        "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
96
97
  /* Extended validation
98
   */
99
  ENTRY("1.3.6.1.4.1.311.60.2.1.1",
100
        "jurisdictionOfIncorporationLocalityName",
101
        "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
102
  ENTRY("1.3.6.1.4.1.311.60.2.1.2",
103
        "jurisdictionOfIncorporationStateOrProvinceName",
104
        "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
105
  ENTRY("1.3.6.1.4.1.311.60.2.1.3",
106
        "jurisdictionOfIncorporationCountryName", NULL,
107
        ASN1_ETYPE_PRINTABLE_STRING),
108
109
  /* PKCS #9
110
   */
111
  ENTRY("1.2.840.113549.1.9.1", "EMAIL", NULL, ASN1_ETYPE_IA5_STRING),
112
  ENTRY_ND("1.2.840.113549.1.9.7", "PKIX1.pkcs-9-challengePassword",
113
     ASN1_ETYPE_INVALID),
114
115
  /* friendly name */
116
  ENTRY_ND("1.2.840.113549.1.9.20", NULL, ASN1_ETYPE_BMP_STRING),
117
  /* local key id */
118
  ENTRY_ND("1.2.840.113549.1.9.21", NULL, ASN1_ETYPE_OCTET_STRING),
119
  ENTRY_ND("1.2.840.113549.1.9.4", NULL, ASN1_ETYPE_OCTET_STRING),
120
121
  /* rfc3920 section 5.1.1 */
122
  ENTRY("1.3.6.1.5.5.7.8.5", "XmppAddr", NULL, ASN1_ETYPE_UTF8_STRING),
123
124
  /* Russian things: https://cdnimg.rg.ru/pril/66/91/91/23041_pril.pdf */
125
  /* Main state registration number */
126
  ENTRY("1.2.643.100.1", "OGRN", NULL, ASN1_ETYPE_NUMERIC_STRING),
127
  /* Individual insurance account number */
128
  ENTRY("1.2.643.100.3", "SNILS", NULL, ASN1_ETYPE_NUMERIC_STRING),
129
  /* Main state registration number for individual enterpreneurs */
130
  ENTRY("1.2.643.100.5", "OGRNIP", NULL, ASN1_ETYPE_NUMERIC_STRING),
131
  /* VAT identification number */
132
  ENTRY("1.2.643.3.131.1.1", "INN", NULL, ASN1_ETYPE_NUMERIC_STRING),
133
134
  { NULL, 0, NULL, 0, NULL, 0 }
135
};
136
137
const struct oid_to_string *
138
_gnutls_oid_get_entry(const struct oid_to_string *ots, const char *oid)
139
0
{
140
0
  unsigned int i = 0;
141
0
  unsigned len = strlen(oid);
142
143
0
  do {
144
0
    if (len == ots[i].oid_size && strcmp(ots[i].oid, oid) == 0)
145
0
      return &ots[i];
146
0
    i++;
147
0
  } while (ots[i].oid != NULL);
148
149
0
  return NULL;
150
0
}
151
152
const char *_gnutls_oid_get_asn_desc(const char *oid)
153
0
{
154
0
  const struct oid_to_string *entry =
155
0
    _gnutls_oid_get_entry(_oid2str, oid);
156
0
  return entry ? entry->asn_desc : NULL;
157
0
}
158
159
const char *_gnutls_ldap_string_to_oid(const char *str, unsigned str_len)
160
0
{
161
0
  unsigned int i = 0;
162
163
0
  do {
164
0
    if ((_oid2str[i].name_desc != NULL) &&
165
0
        (str_len == _oid2str[i].name_desc_size) &&
166
0
        (c_strncasecmp(_oid2str[i].name_desc, str, str_len) == 0))
167
0
      return _oid2str[i].oid;
168
0
    i++;
169
0
  } while (_oid2str[i].oid != NULL);
170
171
0
  return NULL;
172
0
}
173
174
/* Escapes a string following the rules from RFC4514.
175
 */
176
static int str_escape(const gnutls_datum_t *str, gnutls_datum_t *escaped)
177
0
{
178
0
  unsigned int j, i;
179
0
  uint8_t *buffer = NULL;
180
0
  size_t size;
181
0
  int ret;
182
183
0
  if (str == NULL)
184
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
185
186
  /* the string will be at most twice the original */
187
0
  if (!INT_MULTIPLY_OK(str->size, 2, &size) ||
188
0
      !INT_ADD_OK(size, 2, &size))
189
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
190
191
0
  buffer = gnutls_malloc(size);
192
0
  if (buffer == NULL)
193
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
194
195
0
  for (i = j = 0; i < str->size; i++) {
196
0
    if (str->data[i] == 0) {
197
      /* this is handled earlier */
198
0
      ret = gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
199
0
      goto cleanup;
200
0
    }
201
202
0
    if (str->data[i] == ',' || str->data[i] == '+' ||
203
0
        str->data[i] == '"' || str->data[i] == '\\' ||
204
0
        str->data[i] == '<' || str->data[i] == '>' ||
205
0
        str->data[i] == ';' || str->data[i] == 0)
206
0
      buffer[j++] = '\\';
207
0
    else if (i == 0 && str->data[i] == '#')
208
0
      buffer[j++] = '\\';
209
0
    else if (i == 0 && str->data[i] == ' ')
210
0
      buffer[j++] = '\\';
211
0
    else if (i == (str->size - 1) && str->data[i] == ' ')
212
0
      buffer[j++] = '\\';
213
214
0
    buffer[j++] = str->data[i];
215
0
  }
216
217
  /* null terminate the string */
218
0
  buffer[j] = 0;
219
0
  escaped->data = buffer;
220
0
  escaped->size = j;
221
222
0
  return 0;
223
0
cleanup:
224
0
  gnutls_free(buffer);
225
0
  return ret;
226
0
}
227
228
/**
229
 * gnutls_x509_dn_oid_known:
230
 * @oid: holds an Object Identifier in a null terminated string
231
 *
232
 * This function will inform about known DN OIDs. This is useful since
233
 * functions like gnutls_x509_crt_set_dn_by_oid() use the information
234
 * on known OIDs to properly encode their input. Object Identifiers
235
 * that are not known are not encoded by these functions, and their
236
 * input is stored directly into the ASN.1 structure. In that case of
237
 * unknown OIDs, you have the responsibility of DER encoding your
238
 * data.
239
 *
240
 * Returns: 1 on known OIDs and 0 otherwise.
241
 **/
242
int gnutls_x509_dn_oid_known(const char *oid)
243
0
{
244
0
  return _gnutls_oid_get_entry(_oid2str, oid) != NULL;
245
0
}
246
247
/**
248
 * gnutls_x509_dn_oid_name:
249
 * @oid: holds an Object Identifier in a null terminated string
250
 * @flags: 0 or GNUTLS_X509_DN_OID_*
251
 *
252
 * This function will return the name of a known DN OID. If
253
 * %GNUTLS_X509_DN_OID_RETURN_OID is specified this function
254
 * will return the given OID if no descriptive name has been
255
 * found.
256
 *
257
 * Returns: A null terminated string or NULL otherwise.
258
 *
259
 * Since: 3.0
260
 **/
261
const char *gnutls_x509_dn_oid_name(const char *oid, unsigned int flags)
262
0
{
263
0
  const struct oid_to_string *entry =
264
0
    _gnutls_oid_get_entry(_oid2str, oid);
265
266
0
  if (entry && entry->name_desc)
267
0
    return entry->name_desc;
268
0
  if (flags & GNUTLS_X509_DN_OID_RETURN_OID)
269
0
    return oid;
270
0
  else
271
0
    return NULL;
272
0
}
273
274
static int make_printable_string(unsigned etype, const gnutls_datum_t *input,
275
         gnutls_datum_t *out)
276
0
{
277
0
  int printable = 0;
278
0
  int ret;
279
280
  /* empty input strings result to a null string */
281
0
  if (input->data == NULL || input->size == 0) {
282
0
    out->data = gnutls_calloc(1, 1);
283
0
    if (out->data == NULL)
284
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
285
0
    out->size = 0;
286
0
    return 0;
287
0
  }
288
289
0
  if (etype == ASN1_ETYPE_BMP_STRING) {
290
0
    ret = _gnutls_ucs2_to_utf8(input->data, input->size, out, 1);
291
0
    if (ret < 0) {
292
      /* could not convert. Handle it as non-printable */
293
0
      printable = 0;
294
0
    } else
295
0
      printable = 1;
296
0
  } else if (etype == ASN1_ETYPE_TELETEX_STRING) {
297
    /* HACK: if the teletex string contains only ascii
298
     * characters then treat it as printable.
299
     */
300
0
    if (_gnutls_str_is_print((char *)input->data, input->size)) {
301
0
      out->data = gnutls_malloc(input->size + 1);
302
0
      if (out->data == NULL)
303
0
        return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
304
305
0
      memcpy(out->data, input->data, input->size);
306
0
      out->size = input->size;
307
308
0
      out->data[out->size] = 0;
309
310
0
      printable = 1;
311
0
    }
312
0
  } else if (etype !=
313
0
       ASN1_ETYPE_UNIVERSAL_STRING) /* supported but not printable */
314
0
    return GNUTLS_E_INVALID_REQUEST;
315
316
0
  if (printable == 0) { /* need to allocate out */
317
0
    ret = data2hex(input->data, input->size, out);
318
0
    if (ret < 0) {
319
0
      gnutls_assert();
320
0
      return ret;
321
0
    }
322
0
  }
323
324
0
  return 0;
325
0
}
326
327
static int decode_complex_string(const struct oid_to_string *oentry,
328
         void *value, int value_size,
329
         gnutls_datum_t *out)
330
0
{
331
0
  char str[MAX_STRING_LEN], tmpname[128];
332
0
  int len = -1, result;
333
0
  asn1_node tmpasn = NULL;
334
0
  char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
335
0
  unsigned int etype;
336
0
  gnutls_datum_t td = { NULL, 0 };
337
338
0
  if (oentry->asn_desc == NULL) {
339
0
    gnutls_assert();
340
0
    return GNUTLS_E_INTERNAL_ERROR;
341
0
  }
342
343
0
  if ((result = asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc,
344
0
            &tmpasn)) != ASN1_SUCCESS) {
345
0
    gnutls_assert();
346
0
    return _gnutls_asn2err(result);
347
0
  }
348
349
0
  if ((result = _asn1_strict_der_decode(&tmpasn, value, value_size,
350
0
                asn1_err)) != ASN1_SUCCESS) {
351
0
    gnutls_assert();
352
0
    _gnutls_debug_log("_asn1_strict_der_decode: %s\n", asn1_err);
353
0
    asn1_delete_structure(&tmpasn);
354
0
    return _gnutls_asn2err(result);
355
0
  }
356
357
  /* Read the type of choice.
358
   */
359
0
  len = sizeof(str) - 1;
360
0
  if ((result = asn1_read_value(tmpasn, "", str, &len)) !=
361
0
      ASN1_SUCCESS) { /* CHOICE */
362
0
    gnutls_assert();
363
0
    asn1_delete_structure(&tmpasn);
364
0
    return _gnutls_asn2err(result);
365
0
  }
366
367
0
  str[len] = 0;
368
369
  /* We set the etype on the strings that may need
370
   * some conversion to UTF-8. The INVALID flag indicates
371
   * no conversion needed */
372
0
  if (strcmp(str, "teletexString") == 0)
373
0
    etype = ASN1_ETYPE_TELETEX_STRING;
374
0
  else if (strcmp(str, "bmpString") == 0)
375
0
    etype = ASN1_ETYPE_BMP_STRING;
376
0
  else if (strcmp(str, "universalString") == 0)
377
0
    etype = ASN1_ETYPE_UNIVERSAL_STRING;
378
0
  else
379
0
    etype = ASN1_ETYPE_INVALID;
380
381
0
  _gnutls_str_cpy(tmpname, sizeof(tmpname), str);
382
383
0
  result = _gnutls_x509_read_value(tmpasn, tmpname, &td);
384
0
  asn1_delete_structure(&tmpasn);
385
0
  if (result < 0)
386
0
    return gnutls_assert_val(result);
387
388
0
  if (etype != ASN1_ETYPE_INVALID) {
389
0
    result = make_printable_string(etype, &td, out);
390
391
0
    _gnutls_free_datum(&td);
392
393
0
    if (result < 0)
394
0
      return gnutls_assert_val(result);
395
0
  } else {
396
0
    out->data = td.data;
397
0
    out->size = td.size;
398
    /* _gnutls_x509_read_value always null terminates */
399
0
  }
400
401
0
  assert(out->data != NULL);
402
403
  /* Refuse to deal with strings containing NULs. */
404
0
  if (strlen((void *)out->data) != (size_t)out->size) {
405
0
    _gnutls_free_datum(out);
406
0
    return gnutls_assert_val(GNUTLS_E_ASN1_EMBEDDED_NULL_IN_STRING);
407
0
  }
408
409
0
  return 0;
410
0
}
411
412
/* This function will convert an attribute value, specified by the OID,
413
 * to a string. The result will be a null terminated string.
414
 *
415
 * res may be null. This will just return the res_size, needed to
416
 * hold the string.
417
 */
418
int _gnutls_x509_dn_to_string(const char *oid, void *value, int value_size,
419
            gnutls_datum_t *str)
420
0
{
421
0
  const struct oid_to_string *oentry;
422
0
  int ret;
423
0
  gnutls_datum_t tmp = { NULL, 0 };
424
425
0
  if (value == NULL || value_size <= 0) {
426
0
    gnutls_assert();
427
0
    return GNUTLS_E_INVALID_REQUEST;
428
0
  }
429
430
0
  oentry = _gnutls_oid_get_entry(_oid2str, oid);
431
0
  if (oentry == NULL) { /* unknown OID -> hex */
432
0
  unknown_oid:
433
0
    ret = data2hex(value, value_size, str);
434
0
    if (ret < 0) {
435
0
      gnutls_assert();
436
0
      return ret;
437
0
    }
438
0
    return 0;
439
0
  }
440
441
0
  if (oentry->asn_desc != NULL) { /* complex */
442
0
    ret = decode_complex_string(oentry, value, value_size, &tmp);
443
0
    if (ret < 0) {
444
      /* we failed decoding -> handle it as unknown OID */
445
0
      goto unknown_oid;
446
0
    }
447
0
  } else {
448
0
    ret = _gnutls_x509_decode_string(oentry->etype, value,
449
0
             value_size, &tmp, 0);
450
0
    if (ret < 0) {
451
      /* we failed decoding -> handle it as unknown OID */
452
0
      goto unknown_oid;
453
0
    }
454
0
  }
455
456
0
  ret = str_escape(&tmp, str);
457
0
  _gnutls_free_datum(&tmp);
458
459
0
  if (ret < 0)
460
0
    return gnutls_assert_val(ret);
461
462
0
  return 0;
463
0
}
464
465
/* Converts a data string to an LDAP rfc2253 hex string
466
 * something like '#01020304'
467
 */
468
static int data2hex(const void *data, size_t data_size, gnutls_datum_t *out)
469
0
{
470
0
  gnutls_datum_t tmp, td;
471
0
  int ret;
472
0
  size_t size;
473
474
0
  td.size = hex_str_size(data_size) + 1; /* +1 for '#' */
475
0
  td.data = gnutls_malloc(td.size);
476
0
  if (td.data == NULL)
477
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
478
479
0
  tmp.data = (void *)data;
480
0
  tmp.size = data_size;
481
482
0
  td.data[0] = '#';
483
0
  size = td.size - 1; /* don't include '#' */
484
0
  ret = gnutls_hex_encode(&tmp, (char *)&td.data[1], &size);
485
0
  if (ret < 0) {
486
0
    gnutls_assert();
487
0
    gnutls_free(td.data);
488
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
489
0
  }
490
491
0
  td.size--; /* don't include null */
492
493
0
  out->data = td.data;
494
0
  out->size = td.size;
495
496
0
  return 0;
497
0
}
498
499
gnutls_x509_subject_alt_name_t _gnutls_x509_san_find_type(char *str_type)
500
0
{
501
0
  if (strcmp(str_type, "dNSName") == 0)
502
0
    return GNUTLS_SAN_DNSNAME;
503
0
  if (strcmp(str_type, "rfc822Name") == 0)
504
0
    return GNUTLS_SAN_RFC822NAME;
505
0
  if (strcmp(str_type, "uniformResourceIdentifier") == 0)
506
0
    return GNUTLS_SAN_URI;
507
0
  if (strcmp(str_type, "iPAddress") == 0)
508
0
    return GNUTLS_SAN_IPADDRESS;
509
0
  if (strcmp(str_type, "otherName") == 0)
510
0
    return GNUTLS_SAN_OTHERNAME;
511
0
  if (strcmp(str_type, "directoryName") == 0)
512
0
    return GNUTLS_SAN_DN;
513
0
  if (strcmp(str_type, "registeredID") == 0)
514
0
    return GNUTLS_SAN_REGISTERED_ID;
515
516
0
  return (gnutls_x509_subject_alt_name_t)-1;
517
0
}
518
519
/* A generic export function. Will export the given ASN.1 encoded data
520
 * to PEM or DER raw data.
521
 */
522
int _gnutls_x509_export_int_named(asn1_node asn1_data, const char *name,
523
          gnutls_x509_crt_fmt_t format,
524
          const char *pem_header,
525
          unsigned char *output_data,
526
          size_t *output_data_size)
527
0
{
528
0
  int ret;
529
0
  gnutls_datum_t out = { NULL, 0 };
530
0
  size_t size;
531
532
0
  ret = _gnutls_x509_export_int_named2(asn1_data, name, format,
533
0
               pem_header, &out);
534
0
  if (ret < 0)
535
0
    return gnutls_assert_val(ret);
536
537
0
  if (format == GNUTLS_X509_FMT_PEM)
538
0
    size = out.size + 1;
539
0
  else
540
0
    size = out.size;
541
542
0
  if (*output_data_size < size) {
543
0
    *output_data_size = size;
544
0
    ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
545
0
    goto cleanup;
546
0
  }
547
548
0
  *output_data_size = (size_t)out.size;
549
0
  if (output_data) {
550
0
    if (out.size > 0) {
551
0
      memcpy(output_data, out.data, (size_t)out.size);
552
0
    }
553
0
    if (format == GNUTLS_X509_FMT_PEM)
554
0
      output_data[out.size] = 0;
555
0
  }
556
557
0
  ret = 0;
558
559
0
cleanup:
560
0
  gnutls_free(out.data);
561
562
0
  return ret;
563
0
}
564
565
/* A generic export function. Will export the given ASN.1 encoded data
566
 * to PEM or DER raw data.
567
 */
568
int _gnutls_x509_export_int_named2(asn1_node asn1_data, const char *name,
569
           gnutls_x509_crt_fmt_t format,
570
           const char *pem_header, gnutls_datum_t *out)
571
0
{
572
0
  int ret;
573
574
0
  if (format == GNUTLS_X509_FMT_DER) {
575
0
    ret = _gnutls_x509_der_encode(asn1_data, name, out, 0);
576
0
    if (ret < 0)
577
0
      return gnutls_assert_val(ret);
578
0
  } else { /* PEM */
579
0
    gnutls_datum_t tmp;
580
581
0
    ret = _gnutls_x509_der_encode(asn1_data, name, &tmp, 0);
582
0
    if (ret < 0)
583
0
      return gnutls_assert_val(ret);
584
585
0
    ret = _gnutls_fbase64_encode(pem_header, tmp.data, tmp.size,
586
0
               out);
587
0
    _gnutls_free_datum(&tmp);
588
589
0
    if (ret < 0)
590
0
      return gnutls_assert_val(ret);
591
0
  }
592
593
0
  return 0;
594
0
}
595
596
/* Decodes an octet string. The etype specifies the string type.
597
 * The returned string is always null terminated (but null is not
598
 * included in size).
599
 */
600
int _gnutls_x509_decode_string(unsigned int etype, const uint8_t *der,
601
             size_t der_size, gnutls_datum_t *output,
602
             unsigned allow_ber)
603
0
{
604
0
  long ret;
605
0
  uint8_t *str;
606
0
  unsigned int str_size, len;
607
0
  gnutls_datum_t td;
608
0
  int tag_len, len_len;
609
0
  unsigned char class;
610
0
  unsigned long tag;
611
612
0
  output->data = NULL;
613
0
  output->size = 0;
614
615
  /* asn1_decode_simple_{ber,der} don't accept empty string,
616
   * check it beforehand.
617
   */
618
0
  ret = asn1_get_tag_der(der, der_size, &class, &tag_len, &tag);
619
0
  if (ret != ASN1_SUCCESS) {
620
0
    gnutls_assert();
621
0
    ret = _gnutls_asn2err(ret);
622
0
    return ret;
623
0
  }
624
625
0
  if (allow_ber)
626
0
    ret = asn1_get_length_ber(der + tag_len, der_size - tag_len,
627
0
            &len_len);
628
0
  else
629
0
    ret = asn1_get_length_der(der + tag_len, der_size - tag_len,
630
0
            &len_len);
631
0
  if (ret == 0) {
632
0
    output->data = NULL;
633
0
    output->size = 0;
634
0
    return 0;
635
0
  }
636
637
0
  if (allow_ber)
638
0
    ret = asn1_decode_simple_ber(etype, der, der_size, &str,
639
0
               &str_size, NULL);
640
0
  else
641
0
    ret = asn1_decode_simple_der(etype, der, der_size,
642
0
               (const uint8_t **)&str, &str_size);
643
0
  if (ret != ASN1_SUCCESS) {
644
0
    gnutls_assert();
645
0
    ret = _gnutls_asn2err(ret);
646
0
    return ret;
647
0
  }
648
649
0
  td.size = str_size;
650
0
  td.data = gnutls_malloc(str_size + 1);
651
0
  if (td.data == NULL)
652
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
653
654
0
  if (str_size > 0)
655
0
    memcpy(td.data, str, str_size);
656
0
  td.data[str_size] = 0;
657
658
0
  if (allow_ber)
659
0
    free(str);
660
661
0
  ret = make_printable_string(etype, &td, output);
662
0
  if (ret == GNUTLS_E_INVALID_REQUEST) { /* unsupported etype */
663
0
    output->data = td.data;
664
0
    output->size = td.size;
665
0
    ret = 0;
666
0
  } else if (ret <= 0) {
667
0
    _gnutls_free_datum(&td);
668
0
  }
669
670
  /* Refuse to deal with strings containing NULs. */
671
0
  if (etype != ASN1_ETYPE_OCTET_STRING) {
672
0
    if (output->data)
673
0
      len = strlen((void *)output->data);
674
0
    else
675
0
      len = 0;
676
677
0
    if (len != (size_t)output->size) {
678
0
      _gnutls_free_datum(output);
679
0
      ret = gnutls_assert_val(
680
0
        GNUTLS_E_ASN1_EMBEDDED_NULL_IN_STRING);
681
0
    }
682
0
  }
683
684
0
  return ret;
685
0
}
686
687
/* Reads a value from an ASN1 tree, and puts the output
688
 * in an allocated variable in the given datum.
689
 *
690
 * Note that this function always allocates one plus
691
 * the required data size (and places a null byte).
692
 */
693
static int x509_read_value(asn1_node c, const char *root, gnutls_datum_t *ret,
694
         unsigned allow_null)
695
0
{
696
0
  int len = 0, result;
697
0
  uint8_t *tmp = NULL;
698
0
  unsigned int etype;
699
700
0
  result = asn1_read_value_type(c, root, NULL, &len, &etype);
701
0
  if (result == 0 && allow_null == 0 && len == 0) {
702
    /* don't allow null strings */
703
0
    return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
704
0
  } else if (result == 0 && allow_null == 0 &&
705
0
       etype == ASN1_ETYPE_OBJECT_ID && len == 1) {
706
0
    return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
707
0
  }
708
709
0
  if (result != ASN1_MEM_ERROR) {
710
0
    if (result != ASN1_SUCCESS || allow_null == 0 || len != 0) {
711
0
      result = _gnutls_asn2err(result);
712
0
      return result;
713
0
    }
714
0
  }
715
716
0
  if (etype == ASN1_ETYPE_BIT_STRING) {
717
0
    len = (len + 7) / 8;
718
0
  }
719
720
0
  tmp = gnutls_malloc((size_t)len + 1);
721
0
  if (tmp == NULL) {
722
0
    gnutls_assert();
723
0
    result = GNUTLS_E_MEMORY_ERROR;
724
0
    goto cleanup;
725
0
  }
726
727
0
  if (len > 0) {
728
0
    result = asn1_read_value(c, root, tmp, &len);
729
0
    if (result != ASN1_SUCCESS) {
730
0
      gnutls_assert();
731
0
      result = _gnutls_asn2err(result);
732
0
      goto cleanup;
733
0
    }
734
735
0
    switch (etype) {
736
0
    case ASN1_ETYPE_BIT_STRING:
737
0
      ret->size = (len + 7) / 8;
738
0
      break;
739
0
    case ASN1_ETYPE_OBJECT_ID:
740
0
      if (len > 0) {
741
0
        ret->size = len - 1;
742
0
      } else {
743
0
        result = gnutls_assert_val(
744
0
          GNUTLS_E_ASN1_DER_ERROR);
745
0
        goto cleanup;
746
0
      }
747
0
      break;
748
0
    default:
749
0
      ret->size = (unsigned)len;
750
0
      break;
751
0
    }
752
0
  } else {
753
0
    ret->size = 0;
754
0
  }
755
756
0
  tmp[ret->size] = 0;
757
0
  ret->data = tmp;
758
759
0
  return 0;
760
761
0
cleanup:
762
0
  gnutls_free(tmp);
763
0
  return result;
764
0
}
765
766
int _gnutls_x509_read_value(asn1_node c, const char *root, gnutls_datum_t *ret)
767
0
{
768
0
  return x509_read_value(c, root, ret, 0);
769
0
}
770
771
int _gnutls_x509_read_null_value(asn1_node c, const char *root,
772
         gnutls_datum_t *ret)
773
0
{
774
0
  return x509_read_value(c, root, ret, 1);
775
0
}
776
777
/* Reads a value from an ASN1 tree, then interprets it as the provided
778
 * type of string and returns the output in an allocated variable.
779
 *
780
 * Note that this function always places a null character
781
 * at the end of a readable string value (which is not accounted into size)
782
 */
783
int _gnutls_x509_read_string(asn1_node c, const char *root, gnutls_datum_t *ret,
784
           unsigned int etype, unsigned int allow_ber)
785
0
{
786
0
  int len = 0, result;
787
0
  size_t slen;
788
0
  uint8_t *tmp = NULL;
789
0
  unsigned rtype;
790
791
0
  result = asn1_read_value_type(c, root, NULL, &len, &rtype);
792
0
  if (result != ASN1_MEM_ERROR) {
793
0
    gnutls_assert();
794
0
    result = _gnutls_asn2err(result);
795
0
    return result;
796
0
  }
797
798
0
  if (rtype == ASN1_ETYPE_BIT_STRING)
799
0
    len /= 8;
800
801
0
  tmp = gnutls_malloc((size_t)len + 1);
802
0
  if (tmp == NULL) {
803
0
    gnutls_assert();
804
0
    result = GNUTLS_E_MEMORY_ERROR;
805
0
    goto cleanup;
806
0
  }
807
808
0
  result = asn1_read_value(c, root, tmp, &len);
809
0
  if (result != ASN1_SUCCESS) {
810
0
    gnutls_assert();
811
0
    result = _gnutls_asn2err(result);
812
0
    goto cleanup;
813
0
  }
814
815
0
  if (rtype == ASN1_ETYPE_BIT_STRING)
816
0
    len /= 8;
817
818
  /* Extract the STRING.
819
   */
820
0
  slen = (size_t)len;
821
822
0
  result = _gnutls_x509_decode_string(etype, tmp, slen, ret, allow_ber);
823
0
  if (result < 0) {
824
0
    gnutls_assert();
825
0
    goto cleanup;
826
0
  }
827
0
  gnutls_free(tmp);
828
829
0
  return 0;
830
831
0
cleanup:
832
0
  gnutls_free(tmp);
833
0
  return result;
834
0
}
835
836
/* The string type should be IA5String, UTF8String etc. Leave
837
 * null for octet string */
838
int _gnutls_x509_encode_string(unsigned int etype, const void *input_data,
839
             size_t input_size, gnutls_datum_t *output)
840
0
{
841
0
  uint8_t tl[ASN1_MAX_TL_SIZE];
842
0
  unsigned int tl_size;
843
0
  int ret;
844
845
0
  tl_size = sizeof(tl);
846
0
  ret = asn1_encode_simple_der(etype, input_data, input_size, tl,
847
0
             &tl_size);
848
0
  if (ret != ASN1_SUCCESS) {
849
0
    gnutls_assert();
850
0
    ret = _gnutls_asn2err(ret);
851
0
    return ret;
852
0
  }
853
854
0
  output->data = gnutls_malloc(tl_size + input_size);
855
0
  if (output->data == NULL)
856
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
857
858
0
  memcpy(output->data, tl, tl_size);
859
0
  memcpy(output->data + tl_size, input_data, input_size);
860
861
0
  output->size = tl_size + input_size;
862
863
0
  return 0;
864
0
}
865
866
/* DER Encodes the src asn1_node and stores it to
867
 * the given datum. If str is non zero then the data are encoded as
868
 * an OCTET STRING.
869
 */
870
int _gnutls_x509_der_encode(asn1_node src, const char *src_name,
871
          gnutls_datum_t *res, int str)
872
0
{
873
0
  int size, result;
874
0
  int asize;
875
0
  uint8_t *data = NULL;
876
0
  asn1_node c2 = NULL;
877
878
0
  size = 0;
879
0
  result = asn1_der_coding(src, src_name, NULL, &size, NULL);
880
  /* this check explicitly covers the case where size == 0 && result == 0 */
881
0
  if (result != ASN1_MEM_ERROR) {
882
0
    gnutls_assert();
883
0
    return _gnutls_asn2err(result);
884
0
  }
885
886
  /* allocate data for the der
887
   */
888
889
0
  if (str)
890
0
    size += 16; /* for later to include the octet tags */
891
0
  asize = size;
892
893
0
  data = gnutls_malloc((size_t)size);
894
0
  if (data == NULL) {
895
0
    gnutls_assert();
896
0
    return GNUTLS_E_MEMORY_ERROR;
897
0
  }
898
899
0
  result = asn1_der_coding(src, src_name, data, &size, NULL);
900
0
  if (result != ASN1_SUCCESS) {
901
0
    gnutls_assert();
902
0
    result = _gnutls_asn2err(result);
903
0
    goto cleanup;
904
0
  }
905
906
0
  if (str) {
907
0
    if ((result = asn1_create_element(_gnutls_get_pkix(),
908
0
              "PKIX1.pkcs-7-Data", &c2)) !=
909
0
        ASN1_SUCCESS) {
910
0
      gnutls_assert();
911
0
      result = _gnutls_asn2err(result);
912
0
      goto cleanup;
913
0
    }
914
915
0
    result = asn1_write_value(c2, "", data, size);
916
0
    if (result != ASN1_SUCCESS) {
917
0
      gnutls_assert();
918
0
      result = _gnutls_asn2err(result);
919
0
      goto cleanup;
920
0
    }
921
922
0
    result = asn1_der_coding(c2, "", data, &asize, NULL);
923
0
    if (result != ASN1_SUCCESS) {
924
0
      gnutls_assert();
925
0
      result = _gnutls_asn2err(result);
926
0
      goto cleanup;
927
0
    }
928
929
0
    size = asize;
930
931
0
    asn1_delete_structure(&c2);
932
0
  }
933
934
0
  res->data = data;
935
0
  res->size = (unsigned)size;
936
0
  return 0;
937
938
0
cleanup:
939
0
  gnutls_free(data);
940
0
  asn1_delete_structure(&c2);
941
0
  return result;
942
0
}
943
944
/* DER Encodes the src asn1_node and stores it to
945
 * dest in dest_name. Useful to encode something and store it
946
 * as OCTET. If str is non null then the data are encoded as
947
 * an OCTET STRING.
948
 */
949
int _gnutls_x509_der_encode_and_copy(asn1_node src, const char *src_name,
950
             asn1_node dest, const char *dest_name,
951
             int str)
952
0
{
953
0
  int result;
954
0
  gnutls_datum_t encoded = { NULL, 0 };
955
956
0
  result = _gnutls_x509_der_encode(src, src_name, &encoded, str);
957
958
0
  if (result < 0) {
959
0
    gnutls_assert();
960
0
    return result;
961
0
  }
962
963
  /* Write the data.
964
   */
965
0
  result = asn1_write_value(dest, dest_name, encoded.data,
966
0
          (int)encoded.size);
967
968
0
  _gnutls_free_datum(&encoded);
969
970
0
  if (result != ASN1_SUCCESS) {
971
0
    gnutls_assert();
972
0
    return _gnutls_asn2err(result);
973
0
  }
974
975
0
  return 0;
976
0
}
977
978
/* Writes the value of the datum in the given asn1_node.
979
 */
980
int _gnutls_x509_write_value(asn1_node c, const char *root,
981
           const gnutls_datum_t *data)
982
0
{
983
0
  int ret;
984
985
  /* Write the data.
986
   */
987
0
  ret = asn1_write_value(c, root, data->data, data->size);
988
0
  if (ret != ASN1_SUCCESS) {
989
0
    gnutls_assert();
990
0
    return _gnutls_asn2err(ret);
991
0
  }
992
993
0
  return 0;
994
0
}
995
996
/* Writes the value of the datum in the given asn1_node as a string.
997
 */
998
int _gnutls_x509_write_string(asn1_node c, const char *root,
999
            const gnutls_datum_t *data, unsigned int etype)
1000
0
{
1001
0
  int ret;
1002
0
  gnutls_datum_t val = { NULL, 0 };
1003
1004
0
  ret = _gnutls_x509_encode_string(etype, data->data, data->size, &val);
1005
0
  if (ret < 0)
1006
0
    return gnutls_assert_val(ret);
1007
1008
  /* Write the data.
1009
   */
1010
0
  ret = asn1_write_value(c, root, val.data, val.size);
1011
0
  if (ret != ASN1_SUCCESS) {
1012
0
    gnutls_assert();
1013
0
    ret = _gnutls_asn2err(ret);
1014
0
    goto cleanup;
1015
0
  }
1016
1017
0
  ret = 0;
1018
1019
0
cleanup:
1020
0
  _gnutls_free_datum(&val);
1021
0
  return ret;
1022
0
}
1023
1024
void _asnstr_append_name(char *name, size_t name_size, const char *part1,
1025
       const char *part2)
1026
0
{
1027
0
  if (part1[0] != 0) {
1028
0
    _gnutls_str_cpy(name, name_size, part1);
1029
0
    _gnutls_str_cat(name, name_size, part2);
1030
0
  } else
1031
0
    _gnutls_str_cpy(name, name_size,
1032
0
        part2 + 1 /* remove initial dot */);
1033
0
}
1034
1035
/* Encodes and copies the private key parameters into a
1036
 * subjectPublicKeyInfo structure.
1037
 *
1038
 */
1039
int _gnutls_x509_encode_and_copy_PKI_params(asn1_node dst, const char *dst_name,
1040
              const gnutls_pk_params_st *params)
1041
0
{
1042
0
  const char *oid;
1043
0
  gnutls_datum_t der = { NULL, 0 };
1044
0
  int result;
1045
0
  char name[128];
1046
1047
0
  oid = gnutls_pk_get_oid(params->algo);
1048
0
  if (oid == NULL) {
1049
0
    gnutls_assert();
1050
0
    return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1051
0
  }
1052
1053
  /* write the OID
1054
   */
1055
0
  _asnstr_append_name(name, sizeof(name), dst_name,
1056
0
          ".algorithm.algorithm");
1057
1058
0
  result = asn1_write_value(dst, name, oid, 1);
1059
0
  if (result != ASN1_SUCCESS) {
1060
0
    gnutls_assert();
1061
0
    return _gnutls_asn2err(result);
1062
0
  }
1063
1064
0
  result = _gnutls_x509_write_pubkey_params(params, &der);
1065
0
  if (result < 0) {
1066
0
    gnutls_assert();
1067
0
    return result;
1068
0
  }
1069
1070
0
  _asnstr_append_name(name, sizeof(name), dst_name,
1071
0
          ".algorithm.parameters");
1072
1073
0
  result = asn1_write_value(dst, name, der.data, der.size);
1074
0
  _gnutls_free_datum(&der);
1075
1076
0
  if (result != ASN1_SUCCESS) {
1077
0
    gnutls_assert();
1078
0
    return _gnutls_asn2err(result);
1079
0
  }
1080
1081
0
  result = _gnutls_x509_write_pubkey(params, &der);
1082
0
  if (result < 0) {
1083
0
    gnutls_assert();
1084
0
    return result;
1085
0
  }
1086
1087
  /* Write the DER parameters. (in bits)
1088
   */
1089
0
  _asnstr_append_name(name, sizeof(name), dst_name, ".subjectPublicKey");
1090
0
  result = asn1_write_value(dst, name, der.data, der.size * 8);
1091
0
  _gnutls_free_datum(&der);
1092
1093
0
  if (result != ASN1_SUCCESS) {
1094
0
    gnutls_assert();
1095
0
    return _gnutls_asn2err(result);
1096
0
  }
1097
1098
0
  return 0;
1099
0
}
1100
1101
/* Encodes and public key parameters into a
1102
 * subjectPublicKeyInfo structure and stores it in der.
1103
 */
1104
int _gnutls_x509_encode_PKI_params(gnutls_datum_t *der,
1105
           const gnutls_pk_params_st *params)
1106
0
{
1107
0
  int ret;
1108
0
  asn1_node tmp;
1109
1110
0
  ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Certificate",
1111
0
          &tmp);
1112
0
  if (ret != ASN1_SUCCESS) {
1113
0
    gnutls_assert();
1114
0
    return _gnutls_asn2err(ret);
1115
0
  }
1116
1117
0
  ret = _gnutls_x509_encode_and_copy_PKI_params(
1118
0
    tmp, "tbsCertificate.subjectPublicKeyInfo", params);
1119
0
  if (ret != ASN1_SUCCESS) {
1120
0
    gnutls_assert();
1121
0
    ret = _gnutls_asn2err(ret);
1122
0
    goto cleanup;
1123
0
  }
1124
1125
0
  ret = _gnutls_x509_der_encode(
1126
0
    tmp, "tbsCertificate.subjectPublicKeyInfo", der, 0);
1127
1128
0
cleanup:
1129
0
  asn1_delete_structure(&tmp);
1130
1131
0
  return ret;
1132
0
}
1133
1134
/* Reads and returns the PK algorithm of the given certificate-like
1135
 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
1136
 */
1137
int _gnutls_x509_get_pk_algorithm(asn1_node src, const char *src_name,
1138
          gnutls_ecc_curve_t *curve, unsigned int *bits)
1139
0
{
1140
0
  int result;
1141
0
  int algo;
1142
0
  char oid[64];
1143
0
  int len;
1144
0
  gnutls_ecc_curve_t lcurve = GNUTLS_ECC_CURVE_INVALID;
1145
0
  char name[128];
1146
1147
0
  _asnstr_append_name(name, sizeof(name), src_name,
1148
0
          ".algorithm.algorithm");
1149
0
  len = sizeof(oid);
1150
0
  result = asn1_read_value(src, name, oid, &len);
1151
1152
0
  if (result != ASN1_SUCCESS) {
1153
0
    gnutls_assert();
1154
0
    return _gnutls_asn2err(result);
1155
0
  }
1156
1157
0
  algo = _gnutls_oid_to_pk_and_curve(oid, &lcurve);
1158
0
  if (algo == GNUTLS_PK_UNKNOWN) {
1159
0
    _gnutls_debug_log("%s: unknown public key algorithm: %s\n",
1160
0
          __func__, oid);
1161
0
  }
1162
1163
0
  if (curve)
1164
0
    *curve = lcurve;
1165
1166
0
  if (bits == NULL) {
1167
0
    return algo;
1168
0
  }
1169
1170
  /* Now read the parameters' bits
1171
   */
1172
0
  if (lcurve != GNUTLS_ECC_CURVE_INVALID) { /* curve present */
1173
0
    bits[0] = gnutls_ecc_curve_get_size(lcurve) * 8;
1174
0
  } else {
1175
0
    gnutls_pk_params_st params;
1176
0
    gnutls_pk_params_init(&params);
1177
1178
0
    result = _gnutls_get_asn_mpis(src, src_name, &params);
1179
0
    if (result < 0)
1180
0
      return gnutls_assert_val(result);
1181
1182
0
    bits[0] = pubkey_to_bits(&params);
1183
0
    gnutls_pk_params_release(&params);
1184
0
  }
1185
1186
0
  return algo;
1187
0
}
1188
1189
/* Reads the DER signed data from the certificate and allocates space and
1190
 * returns them into signed_data.
1191
 */
1192
int _gnutls_x509_get_signed_data(asn1_node src, const gnutls_datum_t *der,
1193
         const char *src_name,
1194
         gnutls_datum_t *signed_data)
1195
0
{
1196
0
  int start, end, result;
1197
1198
0
  if (der == NULL || der->size == 0) {
1199
0
    return _gnutls_x509_der_encode(src, src_name, signed_data, 0);
1200
0
  }
1201
1202
  /* Get the signed data
1203
   */
1204
0
  result = asn1_der_decoding_startEnd(src, der->data, der->size, src_name,
1205
0
              &start, &end);
1206
0
  if (result != ASN1_SUCCESS) {
1207
0
    result = _gnutls_asn2err(result);
1208
0
    gnutls_assert();
1209
0
    goto cleanup;
1210
0
  }
1211
1212
0
  result = _gnutls_set_datum(signed_data, &der->data[start],
1213
0
           end - start + 1);
1214
1215
0
  if (result < 0) {
1216
0
    gnutls_assert();
1217
0
    goto cleanup;
1218
0
  }
1219
1220
0
  result = 0;
1221
1222
0
cleanup:
1223
0
  return result;
1224
0
}
1225
1226
/*-
1227
 * gnutls_x509_get_signature_algorithm:
1228
 * @src: should contain an asn1_node structure
1229
 * @src_name: the description of the signature field
1230
 *
1231
 * This function will return a value of the #gnutls_sign_algorithm_t
1232
 * enumeration that is the signature algorithm that has been used to
1233
 * sign this certificate.
1234
 *
1235
 * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
1236
 *   error.
1237
 -*/
1238
int _gnutls_x509_get_signature_algorithm(asn1_node src, const char *src_name)
1239
0
{
1240
0
  int result;
1241
0
  char name[128];
1242
0
  gnutls_datum_t sa = { NULL, 0 };
1243
1244
0
  _gnutls_str_cpy(name, sizeof(name), src_name);
1245
0
  _gnutls_str_cat(name, sizeof(name), ".algorithm");
1246
1247
  /* Read the signature algorithm */
1248
0
  result = _gnutls_x509_read_value(src, name, &sa);
1249
1250
0
  if (result < 0) {
1251
0
    gnutls_assert();
1252
0
    return result;
1253
0
  }
1254
1255
  /* Read the signature parameters. Unless the algorithm is
1256
   * RSA-PSS, parameters are not read. They will be read from
1257
   * the issuer's certificate if needed.
1258
   */
1259
0
  if (sa.data && strcmp((char *)sa.data, PK_PKIX1_RSA_PSS_OID) == 0) {
1260
0
    gnutls_datum_t der = { NULL, 0 };
1261
0
    gnutls_x509_spki_st params;
1262
1263
0
    _gnutls_str_cpy(name, sizeof(name), src_name);
1264
0
    _gnutls_str_cat(name, sizeof(name), ".parameters");
1265
1266
0
    result = _gnutls_x509_read_value(src, name, &der);
1267
0
    if (result < 0) {
1268
0
      _gnutls_free_datum(&sa);
1269
0
      return gnutls_assert_val(result);
1270
0
    }
1271
1272
0
    result = _gnutls_x509_read_rsa_pss_params(der.data, der.size,
1273
0
                &params);
1274
0
    _gnutls_free_datum(&der);
1275
1276
0
    if (result == 0)
1277
0
      result = gnutls_pk_to_sign(params.pk,
1278
0
               params.rsa_pss_dig);
1279
0
  } else if (sa.data) {
1280
0
    result = gnutls_oid_to_sign((char *)sa.data);
1281
0
  } else {
1282
0
    result = GNUTLS_E_UNKNOWN_ALGORITHM;
1283
0
  }
1284
1285
0
  _gnutls_free_datum(&sa);
1286
1287
0
  if (result == GNUTLS_SIGN_UNKNOWN)
1288
0
    result = GNUTLS_E_UNKNOWN_ALGORITHM;
1289
1290
0
  return result;
1291
0
}
1292
1293
/* Reads the DER signature from the certificate and allocates space and
1294
 * returns them into signed_data.
1295
 */
1296
int _gnutls_x509_get_signature(asn1_node src, const char *src_name,
1297
             gnutls_datum_t *signature)
1298
0
{
1299
0
  int result, len;
1300
0
  int bits;
1301
1302
0
  signature->data = NULL;
1303
0
  signature->size = 0;
1304
1305
  /* Read the signature
1306
   */
1307
0
  len = 0;
1308
0
  result = asn1_read_value(src, src_name, NULL, &len);
1309
1310
0
  if (result != ASN1_MEM_ERROR) {
1311
0
    result = _gnutls_asn2err(result);
1312
0
    gnutls_assert();
1313
0
    goto cleanup;
1314
0
  }
1315
1316
0
  bits = len;
1317
0
  if (bits % 8 != 0 || bits < 8) {
1318
0
    gnutls_assert();
1319
0
    result = GNUTLS_E_CERTIFICATE_ERROR;
1320
0
    goto cleanup;
1321
0
  }
1322
1323
0
  len = bits / 8;
1324
1325
0
  signature->data = gnutls_malloc(len);
1326
0
  if (signature->data == NULL) {
1327
0
    gnutls_assert();
1328
0
    result = GNUTLS_E_MEMORY_ERROR;
1329
0
    return result;
1330
0
  }
1331
1332
  /* read the bit string of the signature
1333
   */
1334
0
  bits = len;
1335
0
  result = asn1_read_value(src, src_name, signature->data, &bits);
1336
1337
0
  if (result != ASN1_SUCCESS) {
1338
0
    result = _gnutls_asn2err(result);
1339
0
    gnutls_assert();
1340
0
    goto cleanup;
1341
0
  }
1342
1343
0
  signature->size = len;
1344
1345
0
  return 0;
1346
1347
0
cleanup:
1348
0
  gnutls_free(signature->data);
1349
0
  return result;
1350
0
}
1351
1352
/* ASN.1 PrintableString rules */
1353
static int is_printable(char p)
1354
0
{
1355
0
  if ((p >= 'a' && p <= 'z') || (p >= 'A' && p <= 'Z') ||
1356
0
      (p >= '0' && p <= '9') || p == ' ' || p == '(' || p == ')' ||
1357
0
      p == '+' || p == ',' || p == '-' || p == '.' || p == '/' ||
1358
0
      p == ':' || p == '=' || p == '?')
1359
0
    return 1;
1360
1361
0
  return 0;
1362
0
}
1363
1364
static int write_complex_string(asn1_node asn_struct, const char *where,
1365
        const struct oid_to_string *oentry,
1366
        const uint8_t *data, size_t data_size)
1367
0
{
1368
0
  char tmp[128];
1369
0
  asn1_node c2;
1370
0
  int result;
1371
0
  const char *string_type;
1372
0
  unsigned int i;
1373
1374
0
  result = asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc, &c2);
1375
0
  if (result != ASN1_SUCCESS) {
1376
0
    gnutls_assert();
1377
0
    return _gnutls_asn2err(result);
1378
0
  }
1379
1380
0
  tmp[0] = 0;
1381
1382
0
  string_type = "printableString";
1383
1384
  /* Check if the data is ASN.1 printable, and use
1385
   * the UTF8 string type if not.
1386
   */
1387
0
  for (i = 0; i < data_size; i++) {
1388
0
    if (!is_printable(data[i])) {
1389
0
      string_type = "utf8String";
1390
0
      break;
1391
0
    }
1392
0
  }
1393
1394
  /* if the type is a CHOICE then write the
1395
   * type we'll use.
1396
   */
1397
0
  result = asn1_write_value(c2, "", string_type, 1);
1398
0
  if (result != ASN1_SUCCESS) {
1399
0
    gnutls_assert();
1400
0
    result = _gnutls_asn2err(result);
1401
0
    goto error;
1402
0
  }
1403
1404
0
  _gnutls_str_cpy(tmp, sizeof(tmp), string_type);
1405
1406
0
  result = asn1_write_value(c2, tmp, data, data_size);
1407
0
  if (result != ASN1_SUCCESS) {
1408
0
    gnutls_assert();
1409
0
    result = _gnutls_asn2err(result);
1410
0
    goto error;
1411
0
  }
1412
1413
0
  result = _gnutls_x509_der_encode_and_copy(c2, "", asn_struct, where, 0);
1414
0
  if (result < 0) {
1415
0
    gnutls_assert();
1416
0
    goto error;
1417
0
  }
1418
1419
0
  result = 0;
1420
1421
0
error:
1422
0
  asn1_delete_structure(&c2);
1423
0
  return result;
1424
0
}
1425
1426
/* This will encode and write the AttributeTypeAndValue field.
1427
 * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
1428
 * In all cases only one value is written.
1429
 */
1430
int _gnutls_x509_encode_and_write_attribute(const char *given_oid,
1431
              asn1_node asn1_struct,
1432
              const char *where,
1433
              const void *_data, int data_size,
1434
              int multi)
1435
0
{
1436
0
  const uint8_t *data = _data;
1437
0
  char tmp[128];
1438
0
  int result;
1439
0
  const struct oid_to_string *oentry;
1440
1441
0
  oentry = _gnutls_oid_get_entry(_oid2str, given_oid);
1442
0
  if (oentry == NULL) {
1443
0
    gnutls_assert();
1444
0
    _gnutls_debug_log("Cannot find OID: %s\n", given_oid);
1445
0
    return GNUTLS_E_X509_UNSUPPORTED_OID;
1446
0
  }
1447
1448
  /* write the data (value)
1449
   */
1450
1451
0
  _gnutls_str_cpy(tmp, sizeof(tmp), where);
1452
0
  _gnutls_str_cat(tmp, sizeof(tmp), ".value");
1453
1454
0
  if (multi !=
1455
0
      0) { /* if not writing an AttributeTypeAndValue, but an Attribute */
1456
0
    _gnutls_str_cat(tmp, sizeof(tmp), "s"); /* values */
1457
1458
0
    result = asn1_write_value(asn1_struct, tmp, "NEW", 1);
1459
0
    if (result != ASN1_SUCCESS) {
1460
0
      gnutls_assert();
1461
0
      result = _gnutls_asn2err(result);
1462
0
      goto error;
1463
0
    }
1464
1465
0
    _gnutls_str_cat(tmp, sizeof(tmp), ".?LAST");
1466
0
  }
1467
1468
0
  if (oentry->asn_desc != NULL) { /* write a complex string API */
1469
0
    result = write_complex_string(asn1_struct, tmp, oentry, data,
1470
0
                data_size);
1471
0
    if (result < 0)
1472
0
      return gnutls_assert_val(result);
1473
0
  } else { /* write a simple string */
1474
1475
0
    gnutls_datum_t td;
1476
1477
0
    td.data = (void *)data;
1478
0
    td.size = data_size;
1479
0
    result = _gnutls_x509_write_string(asn1_struct, tmp, &td,
1480
0
               oentry->etype);
1481
0
    if (result < 0) {
1482
0
      gnutls_assert();
1483
0
      goto error;
1484
0
    }
1485
0
  }
1486
1487
  /* write the type
1488
   */
1489
0
  _gnutls_str_cpy(tmp, sizeof(tmp), where);
1490
0
  _gnutls_str_cat(tmp, sizeof(tmp), ".type");
1491
1492
0
  result = asn1_write_value(asn1_struct, tmp, given_oid, 1);
1493
0
  if (result != ASN1_SUCCESS) {
1494
0
    gnutls_assert();
1495
0
    result = _gnutls_asn2err(result);
1496
0
    goto error;
1497
0
  }
1498
1499
0
  result = 0;
1500
1501
0
error:
1502
0
  return result;
1503
0
}
1504
1505
/* copies a datum to a buffer. If it doesn't fit it returns
1506
 * GNUTLS_E_SHORT_MEMORY_BUFFER. It always deinitializes the datum
1507
 * after the copy.
1508
 *
1509
 * The buffer will always be null terminated.
1510
 */
1511
int _gnutls_strdatum_to_buf(gnutls_datum_t *d, void *buf, size_t *buf_size)
1512
0
{
1513
0
  int ret;
1514
0
  uint8_t *_buf = buf;
1515
1516
0
  if (buf == NULL || *buf_size < d->size + 1) {
1517
0
    *buf_size = d->size + 1;
1518
0
    ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
1519
0
    goto cleanup;
1520
0
  }
1521
0
  memcpy(buf, d->data, d->size);
1522
0
  _buf[d->size] = 0;
1523
1524
0
  *buf_size = d->size;
1525
0
  ret = 0;
1526
1527
0
cleanup:
1528
0
  _gnutls_free_datum(d);
1529
1530
0
  return ret;
1531
0
}
1532
1533
int _gnutls_x509_get_raw_field2(asn1_node c2, const gnutls_datum_t *raw,
1534
        const char *whom, gnutls_datum_t *dn)
1535
0
{
1536
0
  int result, len1;
1537
0
  int start1, end1;
1538
0
  result = asn1_der_decoding_startEnd(c2, raw->data, raw->size, whom,
1539
0
              &start1, &end1);
1540
1541
0
  if (result != ASN1_SUCCESS) {
1542
0
    gnutls_assert();
1543
0
    result = _gnutls_asn2err(result);
1544
0
    goto cleanup;
1545
0
  }
1546
1547
0
  len1 = end1 - start1 + 1;
1548
1549
0
  dn->data = &raw->data[start1];
1550
0
  dn->size = len1;
1551
0
  result = 0;
1552
1553
0
cleanup:
1554
0
  return result;
1555
0
}
1556
1557
int _gnutls_copy_string(const gnutls_datum_t *str, uint8_t *out,
1558
      size_t *out_size)
1559
0
{
1560
0
  unsigned size_to_check;
1561
1562
0
  size_to_check = str->size + 1;
1563
1564
0
  if ((unsigned)size_to_check > *out_size) {
1565
0
    gnutls_assert();
1566
0
    (*out_size) = size_to_check;
1567
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
1568
0
  }
1569
1570
0
  if (out != NULL && str->data != NULL) {
1571
0
    memcpy(out, str->data, str->size);
1572
0
    out[str->size] = 0;
1573
0
  } else if (out != NULL) {
1574
0
    out[0] = 0;
1575
0
  }
1576
0
  *out_size = str->size;
1577
1578
0
  return 0;
1579
0
}
1580
1581
int _gnutls_copy_data(const gnutls_datum_t *str, uint8_t *out, size_t *out_size)
1582
0
{
1583
0
  if ((unsigned)str->size > *out_size) {
1584
0
    gnutls_assert();
1585
0
    (*out_size) = str->size;
1586
0
    return GNUTLS_E_SHORT_MEMORY_BUFFER;
1587
0
  }
1588
1589
0
  if (out != NULL && str->data != NULL) {
1590
0
    memcpy(out, str->data, str->size);
1591
0
  }
1592
0
  *out_size = str->size;
1593
1594
0
  return 0;
1595
0
}
1596
1597
/* Converts an X.509 certificate to subjectPublicKeyInfo */
1598
int x509_crt_to_raw_pubkey(gnutls_x509_crt_t crt, gnutls_datum_t *rpubkey)
1599
0
{
1600
0
  gnutls_pubkey_t pubkey = NULL;
1601
0
  int ret;
1602
1603
0
  ret = gnutls_pubkey_init(&pubkey);
1604
0
  if (ret < 0)
1605
0
    return gnutls_assert_val(ret);
1606
1607
0
  ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
1608
0
  if (ret < 0) {
1609
0
    gnutls_assert();
1610
0
    goto cleanup;
1611
0
  }
1612
1613
0
  ret = gnutls_pubkey_export2(pubkey, GNUTLS_X509_FMT_DER, rpubkey);
1614
0
  if (ret < 0) {
1615
0
    gnutls_assert();
1616
0
    goto cleanup;
1617
0
  }
1618
1619
0
  ret = 0;
1620
1621
0
cleanup:
1622
0
  gnutls_pubkey_deinit(pubkey);
1623
0
  return ret;
1624
0
}
1625
1626
/* Converts an X.509 certificate to subjectPublicKeyInfo */
1627
int _gnutls_x509_raw_crt_to_raw_pubkey(const gnutls_datum_t *cert,
1628
               gnutls_datum_t *rpubkey)
1629
0
{
1630
0
  gnutls_x509_crt_t crt = NULL;
1631
0
  int ret;
1632
1633
0
  ret = gnutls_x509_crt_init(&crt);
1634
0
  if (ret < 0)
1635
0
    return gnutls_assert_val(ret);
1636
1637
0
  ret = gnutls_x509_crt_import(crt, cert, GNUTLS_X509_FMT_DER);
1638
0
  if (ret < 0) {
1639
0
    gnutls_assert();
1640
0
    goto cleanup;
1641
0
  }
1642
1643
0
  ret = x509_crt_to_raw_pubkey(crt, rpubkey);
1644
0
cleanup:
1645
0
  gnutls_x509_crt_deinit(crt);
1646
1647
0
  return ret;
1648
0
}
1649
1650
unsigned _gnutls_check_valid_key_id(const gnutls_datum_t *key_id,
1651
            gnutls_x509_crt_t cert, time_t now,
1652
            unsigned *has_ski)
1653
0
{
1654
0
  uint8_t id[MAX_KEY_ID_SIZE];
1655
0
  size_t id_size;
1656
0
  unsigned result = 0;
1657
1658
0
  if (has_ski)
1659
0
    *has_ski = 0;
1660
1661
0
  if (now > gnutls_x509_crt_get_expiration_time(cert) ||
1662
0
      now < gnutls_x509_crt_get_activation_time(cert)) {
1663
    /* don't bother, certificate is not yet activated or expired */
1664
0
    gnutls_assert();
1665
0
    goto out;
1666
0
  }
1667
1668
0
  id_size = sizeof(id);
1669
0
  if (gnutls_x509_crt_get_subject_key_id(cert, id, &id_size, NULL) < 0) {
1670
0
    gnutls_assert();
1671
0
    goto out;
1672
0
  }
1673
1674
0
  if (has_ski)
1675
0
    *has_ski = 1;
1676
1677
0
  if (id_size == key_id->size && !memcmp(id, key_id->data, id_size))
1678
0
    result = 1;
1679
1680
0
out:
1681
0
  return result;
1682
0
}
1683
1684
/* Sort a certificate list in place with subject, issuer order. @clist_size must
1685
 * be equal to or less than %DEFAULT_MAX_VERIFY_DEPTH.
1686
 *
1687
 * Returns the index in clist where the initial contiguous segment ends. If the
1688
 * chain contains multiple segments separated by gaps (e.g., missing issuers),
1689
 * the caller shall call this function multiple times.
1690
 *
1691
 * For example, suppose we want the following certificate chain as a result of
1692
 * sorting:
1693
 *
1694
 *   A -> (B) -> C -> D -> E -> (F) -> G -> H -> I
1695
 *
1696
 * from the input [A, C, E, D, G, I, H] (B and F are missing).
1697
 *
1698
 * On the first call of this function:
1699
 *
1700
 *   _gnutls_sort_clist(clist, clist_size)
1701
 *
1702
 * it returns 1, meaning that the first segment only contains A.  The content of
1703
 * @clist will remain the same [A, C, E, D, G, I, H].
1704
 *
1705
 * Then the caller will call this function again, starting from the second
1706
 * element:
1707
 *
1708
 *   _gnutls_sort_clist(&clist[1], clist_size - 1)
1709
 *
1710
 * This time it returns 3, meaning that the first segment contains [C, D, E].
1711
 * The content of @clist will be [A, C, D, E, G, I, H].
1712
 *
1713
 * Finally, after calling the function on the remaining elements:
1714
 *
1715
 *   _gnutls_sort_clist(&clist[1 + 3], clist_size - (1 + 3))
1716
 *
1717
 * It will return 3, meaning that the first segment contains [G, H, I].  At this
1718
 * point, sorting of @clist is complete.
1719
 */
1720
unsigned int _gnutls_sort_clist(gnutls_x509_crt_t *clist,
1721
        unsigned int clist_size)
1722
0
{
1723
0
  int prev;
1724
0
  unsigned int i, j, k;
1725
0
  int issuer[DEFAULT_MAX_VERIFY_DEPTH]; /* contain the index of the issuers */
1726
0
  bool insorted[DEFAULT_MAX_VERIFY_DEPTH]; /* non zero if clist[i] used in sorted list */
1727
0
  gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH];
1728
1729
  /* Limit the number of certificates in the chain, to avoid DoS
1730
   * because of the O(n^2) sorting below.  FIXME: Switch to a
1731
   * topological sort algorithm which should be linear to the
1732
   * number of certificates and subject-issuer relationships.
1733
   */
1734
0
  if (clist_size > DEFAULT_MAX_VERIFY_DEPTH) {
1735
0
    _gnutls_debug_log("too many certificates; skipping sorting\n");
1736
0
    return 1;
1737
0
  }
1738
1739
0
  for (i = 0; i < DEFAULT_MAX_VERIFY_DEPTH; i++) {
1740
0
    issuer[i] = -1;
1741
0
    insorted[i] = 0;
1742
0
  }
1743
1744
  /* Find the issuer of each certificate and store it
1745
   * in issuer array. O(n^2) so consider that before
1746
   * increasing DEFAULT_MAX_VERIFY_DEPTH.
1747
   */
1748
0
  for (i = 0; i < clist_size; i++) {
1749
    /* Self-signed certificate found in the chain; skip it
1750
     * as it should only appear in the trusted set.
1751
     */
1752
0
    if (gnutls_x509_crt_check_issuer(clist[i], clist[i])) {
1753
0
      _gnutls_cert_log("self-signed cert found", clist[i]);
1754
0
      continue;
1755
0
    }
1756
1757
0
    for (j = 1; j < clist_size; j++) {
1758
0
      if (i == j)
1759
0
        continue;
1760
1761
0
      if (gnutls_x509_crt_check_issuer(clist[i], clist[j])) {
1762
0
        issuer[i] = j;
1763
0
        break;
1764
0
      }
1765
0
    }
1766
0
  }
1767
1768
0
  sorted[0] = clist[0];
1769
0
  insorted[0] = 1;
1770
1771
0
  prev = 0;
1772
0
  for (i = 1; i < clist_size; i++) {
1773
0
    prev = issuer[prev];
1774
0
    if (prev < 0) { /* no issuer */
1775
0
      break;
1776
0
    }
1777
1778
0
    if (insorted[prev]) { /* loop detected */
1779
0
      break;
1780
0
    }
1781
1782
0
    sorted[i] = clist[prev];
1783
0
    insorted[prev] = 1;
1784
0
  }
1785
1786
  /* append the remaining certs */
1787
0
  for (j = 1, k = i; j < clist_size; j++) {
1788
0
    if (!insorted[j]) {
1789
0
      sorted[k++] = clist[j];
1790
0
    }
1791
0
  }
1792
1793
  /* write out the sorted list */
1794
0
  assert(k == clist_size);
1795
0
  for (j = 0; j < clist_size; j++) {
1796
0
    clist[j] = sorted[j];
1797
0
  }
1798
1799
0
  return i;
1800
0
}
1801
1802
int _gnutls_check_if_sorted(gnutls_x509_crt_t *crt, int nr)
1803
0
{
1804
0
  int i, ret;
1805
1806
  /* check if the X.509 list is ordered */
1807
0
  if (nr > 1) {
1808
0
    for (i = 0; i < nr; i++) {
1809
0
      if (i > 0) {
1810
0
        if (!_gnutls_x509_compare_raw_dn(
1811
0
              &crt[i]->raw_dn,
1812
0
              &crt[i - 1]->raw_issuer_dn)) {
1813
0
          ret = gnutls_assert_val(
1814
0
            GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
1815
0
          goto cleanup;
1816
0
        }
1817
0
      }
1818
0
    }
1819
0
  }
1820
0
  ret = 0;
1821
1822
0
cleanup:
1823
0
  return ret;
1824
0
}
1825
1826
/**
1827
 * gnutls_gost_paramset_get_name:
1828
 * @param: is a GOST 28147 param set
1829
 *
1830
 * Convert a #gnutls_gost_paramset_t value to a string.
1831
 *
1832
 * Returns: a string that contains the name of the specified GOST param set,
1833
 *   or %NULL.
1834
 *
1835
 * Since: 3.6.3
1836
 **/
1837
const char *gnutls_gost_paramset_get_name(gnutls_gost_paramset_t param)
1838
0
{
1839
0
  switch (param) {
1840
0
  case GNUTLS_GOST_PARAMSET_TC26_Z:
1841
0
    return "TC26-Z";
1842
0
  case GNUTLS_GOST_PARAMSET_CP_A:
1843
0
    return "CryptoPro-A";
1844
0
  case GNUTLS_GOST_PARAMSET_CP_B:
1845
0
    return "CryptoPro-B";
1846
0
  case GNUTLS_GOST_PARAMSET_CP_C:
1847
0
    return "CryptoPro-C";
1848
0
  case GNUTLS_GOST_PARAMSET_CP_D:
1849
0
    return "CryptoPro-D";
1850
0
  default:
1851
0
    gnutls_assert();
1852
0
    return "Unknown";
1853
0
  }
1854
0
}
1855
1856
/**
1857
 * gnutls_gost_paramset_get_oid:
1858
 * @param: is a GOST 28147 param set
1859
 *
1860
 * Convert a #gnutls_gost_paramset_t value to its object identifier.
1861
 *
1862
 * Returns: a string that contains the object identifier of the specified GOST
1863
 *   param set, or %NULL.
1864
 *
1865
 * Since: 3.6.3
1866
 **/
1867
const char *gnutls_gost_paramset_get_oid(gnutls_gost_paramset_t param)
1868
0
{
1869
0
  switch (param) {
1870
0
  case GNUTLS_GOST_PARAMSET_TC26_Z:
1871
0
    return GOST28147_89_TC26Z_OID;
1872
0
  case GNUTLS_GOST_PARAMSET_CP_A:
1873
0
    return GOST28147_89_CPA_OID;
1874
0
  case GNUTLS_GOST_PARAMSET_CP_B:
1875
0
    return GOST28147_89_CPB_OID;
1876
0
  case GNUTLS_GOST_PARAMSET_CP_C:
1877
0
    return GOST28147_89_CPC_OID;
1878
0
  case GNUTLS_GOST_PARAMSET_CP_D:
1879
0
    return GOST28147_89_CPD_OID;
1880
0
  default:
1881
0
    gnutls_assert();
1882
0
    return NULL;
1883
0
  }
1884
0
}
1885
1886
/**
1887
 * gnutls_oid_to_gost_paramset:
1888
 * @oid: is an object identifier
1889
 *
1890
 * Converts a textual object identifier to a #gnutls_gost_paramset_t value.
1891
 *
1892
 * Returns: a #gnutls_gost_paramset_get_oid of the specified GOST 28147
1893
 *   param st, or %GNUTLS_GOST_PARAMSET_UNKNOWN on failure.
1894
 *
1895
 * Since: 3.6.3
1896
 **/
1897
gnutls_gost_paramset_t gnutls_oid_to_gost_paramset(const char *oid)
1898
0
{
1899
0
  if (!strcmp(oid, GOST28147_89_TC26Z_OID))
1900
0
    return GNUTLS_GOST_PARAMSET_TC26_Z;
1901
0
  else if (!strcmp(oid, GOST28147_89_CPA_OID))
1902
0
    return GNUTLS_GOST_PARAMSET_CP_A;
1903
0
  else if (!strcmp(oid, GOST28147_89_CPB_OID))
1904
0
    return GNUTLS_GOST_PARAMSET_CP_B;
1905
0
  else if (!strcmp(oid, GOST28147_89_CPC_OID))
1906
0
    return GNUTLS_GOST_PARAMSET_CP_C;
1907
0
  else if (!strcmp(oid, GOST28147_89_CPD_OID))
1908
0
    return GNUTLS_GOST_PARAMSET_CP_D;
1909
0
  else
1910
0
    return gnutls_assert_val(GNUTLS_GOST_PARAMSET_UNKNOWN);
1911
0
}
1912
1913
int _gnutls_x509_get_version(asn1_node root, const char *name)
1914
0
{
1915
0
  uint8_t version[8];
1916
0
  int len, result;
1917
1918
0
  len = sizeof(version);
1919
0
  result = asn1_read_value(root, name, version, &len);
1920
0
  if (result != ASN1_SUCCESS) {
1921
0
    if (result == ASN1_ELEMENT_NOT_FOUND)
1922
0
      return 1; /* the DEFAULT version */
1923
0
    gnutls_assert();
1924
0
    return _gnutls_asn2err(result);
1925
0
  }
1926
1927
0
  if (len != 1 || version[0] >= 0x80)
1928
0
    return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
1929
1930
0
  return (int)version[0] + 1;
1931
0
}