Coverage Report

Created: 2026-08-14 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/x509/extensions.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2003-2014 Free Software Foundation, Inc.
3
 *
4
 * Author: Nikos Mavrogiannopoulos
5
 *
6
 * This file is part of GnuTLS.
7
 *
8
 * The GnuTLS is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public License
10
 * as published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
20
 *
21
 */
22
23
/* Functions that relate to the X.509 extension parsing.
24
 */
25
26
#include "gnutls_int.h"
27
#include "errors.h"
28
#include "global.h"
29
#include <libtasn1.h>
30
#include "common.h"
31
#include <gnutls/x509-ext.h>
32
#include <gnutls/x509.h>
33
#include "x509_int.h"
34
#include "datum.h"
35
36
int _gnutls_get_extension(asn1_node asn, const char *root,
37
        const char *extension_id, int indx,
38
        gnutls_datum_t *ret, unsigned int *_critical)
39
0
{
40
0
  int k, result, len;
41
0
  char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
42
0
  char str_critical[10];
43
0
  int critical = 0;
44
0
  char extnID[MAX_OID_SIZE];
45
0
  gnutls_datum_t value;
46
0
  int indx_counter = 0;
47
48
0
  ret->data = NULL;
49
0
  ret->size = 0;
50
51
0
  k = 0;
52
0
  do {
53
0
    k++;
54
55
0
    snprintf(name, sizeof(name), "%s.?%d", root, k);
56
57
0
    _gnutls_str_cpy(name2, sizeof(name2), name);
58
0
    _gnutls_str_cat(name2, sizeof(name2), ".extnID");
59
60
0
    len = sizeof(extnID) - 1;
61
0
    result = asn1_read_value(asn, name2, extnID, &len);
62
63
0
    if (result == ASN1_ELEMENT_NOT_FOUND) {
64
0
      break;
65
0
    } else if (result != ASN1_SUCCESS) {
66
0
      gnutls_assert();
67
0
      return _gnutls_asn2err(result);
68
0
    }
69
70
    /* Handle Extension 
71
     */
72
0
    if (streq(extnID, extension_id) && indx == indx_counter++) {
73
      /* extension was found 
74
       */
75
76
      /* read the critical status.
77
       */
78
0
      _gnutls_str_cpy(name2, sizeof(name2), name);
79
0
      _gnutls_str_cat(name2, sizeof(name2), ".critical");
80
81
0
      len = sizeof(str_critical);
82
0
      result =
83
0
        asn1_read_value(asn, name2, str_critical, &len);
84
85
0
      if (result == ASN1_ELEMENT_NOT_FOUND) {
86
0
        gnutls_assert();
87
0
        break;
88
0
      } else if (result != ASN1_SUCCESS) {
89
0
        gnutls_assert();
90
0
        return _gnutls_asn2err(result);
91
0
      }
92
93
0
      if (str_critical[0] == 'T')
94
0
        critical = 1;
95
0
      else
96
0
        critical = 0;
97
98
      /* read the value.
99
       */
100
0
      _gnutls_str_cpy(name2, sizeof(name2), name);
101
0
      _gnutls_str_cat(name2, sizeof(name2), ".extnValue");
102
103
0
      result = _gnutls_x509_read_value(asn, name2, &value);
104
0
      if (result < 0) {
105
0
        gnutls_assert();
106
0
        return result;
107
0
      }
108
109
0
      ret->data = value.data;
110
0
      ret->size = value.size;
111
112
0
      if (_critical)
113
0
        *_critical = critical;
114
115
0
      return 0;
116
0
    }
117
0
  } while (1);
118
119
0
  if (result == ASN1_ELEMENT_NOT_FOUND) {
120
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
121
0
  } else {
122
0
    gnutls_assert();
123
0
    return _gnutls_asn2err(result);
124
0
  }
125
0
}
126
127
static int get_indx_extension(asn1_node asn, const char *root, int indx,
128
            gnutls_datum_t *out)
129
0
{
130
0
  char name[MAX_NAME_SIZE];
131
0
  int ret;
132
133
0
  out->data = NULL;
134
0
  out->size = 0;
135
136
0
  snprintf(name, sizeof(name), "%s.?%d.extnValue", root, indx + 1);
137
138
0
  ret = _gnutls_x509_read_value(asn, name, out);
139
0
  if (ret < 0)
140
0
    return gnutls_assert_val(ret);
141
142
0
  return 0;
143
0
}
144
145
int _gnutls_x509_crt_get_extension(gnutls_x509_crt_t cert,
146
           const char *extension_id, int indx,
147
           gnutls_datum_t *data, unsigned int *critical)
148
0
{
149
0
  return _gnutls_get_extension(cert->cert, "tbsCertificate.extensions",
150
0
             extension_id, indx, data, critical);
151
0
}
152
153
/**
154
 * gnutls_x509_crt_get_extension_data2:
155
 * @cert: should contain a #gnutls_x509_crt_t type
156
 * @indx: Specifies which extension OID to read. Use (0) to get the first one.
157
 * @data: will contain the extension DER-encoded data
158
 *
159
 * This function will return the requested by the index extension data in the
160
 * certificate.  The extension data will be allocated using
161
 * gnutls_malloc().
162
 *
163
 * Use gnutls_x509_crt_get_extension_info() to extract the OID.
164
 *
165
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
166
 *   otherwise a negative error code is returned.  If you have reached the
167
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
168
 *   will be returned.
169
 **/
170
int gnutls_x509_crt_get_extension_data2(gnutls_x509_crt_t cert, unsigned indx,
171
          gnutls_datum_t *data)
172
0
{
173
0
  return get_indx_extension(cert->cert, "tbsCertificate.extensions", indx,
174
0
          data);
175
0
}
176
177
int _gnutls_x509_crl_get_extension(gnutls_x509_crl_t crl,
178
           const char *extension_id, int indx,
179
           gnutls_datum_t *data, unsigned int *critical)
180
0
{
181
0
  return _gnutls_get_extension(crl->crl, "tbsCertList.crlExtensions",
182
0
             extension_id, indx, data, critical);
183
0
}
184
185
/**
186
 * gnutls_x509_crl_get_extension_data2:
187
 * @crl: should contain a #gnutls_x509_crl_t type
188
 * @indx: Specifies which extension OID to read. Use (0) to get the first one.
189
 * @data: will contain the extension DER-encoded data
190
 *
191
 * This function will return the requested by the index extension data in the
192
 * certificate revocation list.  The extension data will be allocated using
193
 * gnutls_malloc().
194
 *
195
 * Use gnutls_x509_crt_get_extension_info() to extract the OID.
196
 *
197
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
198
 *   otherwise a negative error code is returned.  If you have reached the
199
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
200
 *   will be returned.
201
 **/
202
int gnutls_x509_crl_get_extension_data2(gnutls_x509_crl_t crl, unsigned indx,
203
          gnutls_datum_t *data)
204
0
{
205
0
  return get_indx_extension(crl->crl, "tbsCertList.crlExtensions", indx,
206
0
          data);
207
0
}
208
209
/* This function will attempt to return the requested extension OID found in
210
 * the given X509v3 certificate. 
211
 *
212
 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
213
 * be returned.
214
 */
215
static int get_extension_oid(asn1_node asn, const char *root, unsigned indx,
216
           void *oid, size_t *sizeof_oid)
217
0
{
218
0
  int k, result, len;
219
0
  char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
220
0
  char extnID[MAX_OID_SIZE];
221
0
  unsigned indx_counter = 0;
222
223
0
  k = 0;
224
0
  do {
225
0
    k++;
226
227
0
    snprintf(name, sizeof(name), "%s.?%d", root, k);
228
229
0
    _gnutls_str_cpy(name2, sizeof(name2), name);
230
0
    _gnutls_str_cat(name2, sizeof(name2), ".extnID");
231
232
0
    len = sizeof(extnID) - 1;
233
0
    result = asn1_read_value(asn, name2, extnID, &len);
234
235
0
    if (result == ASN1_ELEMENT_NOT_FOUND) {
236
0
      gnutls_assert();
237
0
      break;
238
0
    } else if (result != ASN1_SUCCESS) {
239
0
      gnutls_assert();
240
0
      return _gnutls_asn2err(result);
241
0
    }
242
243
    /* Handle Extension 
244
     */
245
0
    if (indx == indx_counter++) {
246
0
      len = strlen(extnID) + 1;
247
248
0
      if (*sizeof_oid < (unsigned)len) {
249
0
        *sizeof_oid = len;
250
0
        gnutls_assert();
251
0
        return GNUTLS_E_SHORT_MEMORY_BUFFER;
252
0
      }
253
254
0
      memcpy(oid, extnID, len);
255
0
      *sizeof_oid = len - 1;
256
257
0
      return 0;
258
0
    }
259
260
0
  } while (1);
261
262
0
  if (result == ASN1_ELEMENT_NOT_FOUND) {
263
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
264
0
  } else {
265
0
    gnutls_assert();
266
0
    return _gnutls_asn2err(result);
267
0
  }
268
0
}
269
270
/* This function will attempt to return the requested extension OID found in
271
 * the given X509v3 certificate. 
272
 *
273
 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
274
 * be returned.
275
 */
276
int _gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert, int indx,
277
               void *oid, size_t *sizeof_oid)
278
0
{
279
0
  return get_extension_oid(cert->cert, "tbsCertificate.extensions", indx,
280
0
         oid, sizeof_oid);
281
0
}
282
283
int _gnutls_x509_crl_get_extension_oid(gnutls_x509_crl_t crl, int indx,
284
               void *oid, size_t *sizeof_oid)
285
0
{
286
0
  return get_extension_oid(crl->crl, "tbsCertList.crlExtensions", indx,
287
0
         oid, sizeof_oid);
288
0
}
289
290
/* This function will attempt to set the requested extension in
291
 * the given X509v3 certificate. 
292
 *
293
 * Critical will be either 0 or 1.
294
 */
295
static int add_extension(asn1_node asn, const char *root,
296
       const char *extension_id,
297
       const gnutls_datum_t *ext_data, unsigned int critical)
298
0
{
299
0
  int result;
300
0
  const char *str;
301
0
  char name[MAX_NAME_SIZE];
302
303
0
  snprintf(name, sizeof(name), "%s", root);
304
305
  /* Add a new extension in the list.
306
   */
307
0
  result = asn1_write_value(asn, name, "NEW", 1);
308
0
  if (result != ASN1_SUCCESS) {
309
0
    gnutls_assert();
310
0
    return _gnutls_asn2err(result);
311
0
  }
312
313
0
  if (root[0] != 0)
314
0
    snprintf(name, sizeof(name), "%s.?LAST.extnID", root);
315
0
  else
316
0
    snprintf(name, sizeof(name), "?LAST.extnID");
317
318
0
  result = asn1_write_value(asn, name, extension_id, 1);
319
0
  if (result != ASN1_SUCCESS) {
320
0
    gnutls_assert();
321
0
    return _gnutls_asn2err(result);
322
0
  }
323
324
0
  if (critical == 0)
325
0
    str = "FALSE";
326
0
  else
327
0
    str = "TRUE";
328
329
0
  if (root[0] != 0)
330
0
    snprintf(name, sizeof(name), "%s.?LAST.critical", root);
331
0
  else
332
0
    snprintf(name, sizeof(name), "?LAST.critical");
333
334
0
  result = asn1_write_value(asn, name, str, 1);
335
0
  if (result != ASN1_SUCCESS) {
336
0
    gnutls_assert();
337
0
    return _gnutls_asn2err(result);
338
0
  }
339
340
0
  if (root[0] != 0)
341
0
    snprintf(name, sizeof(name), "%s.?LAST.extnValue", root);
342
0
  else
343
0
    snprintf(name, sizeof(name), "?LAST.extnValue");
344
345
0
  result = _gnutls_x509_write_value(asn, name, ext_data);
346
0
  if (result < 0) {
347
0
    gnutls_assert();
348
0
    return result;
349
0
  }
350
351
0
  return 0;
352
0
}
353
354
/* Overwrite the given extension (using the index)
355
 * index here starts from one.
356
 */
357
static int overwrite_extension(asn1_node asn, const char *root,
358
             unsigned int indx,
359
             const gnutls_datum_t *ext_data,
360
             unsigned int critical)
361
0
{
362
0
  char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
363
0
  const char *str;
364
0
  int result;
365
366
0
  if (root[0] != 0)
367
0
    snprintf(name, sizeof(name), "%s.?%u", root, indx);
368
0
  else
369
0
    snprintf(name, sizeof(name), "?%u", indx);
370
371
0
  if (critical == 0)
372
0
    str = "FALSE";
373
0
  else
374
0
    str = "TRUE";
375
376
0
  _gnutls_str_cpy(name2, sizeof(name2), name);
377
0
  _gnutls_str_cat(name2, sizeof(name2), ".critical");
378
379
0
  result = asn1_write_value(asn, name2, str, 1);
380
0
  if (result != ASN1_SUCCESS) {
381
0
    gnutls_assert();
382
0
    return _gnutls_asn2err(result);
383
0
  }
384
385
0
  _gnutls_str_cpy(name2, sizeof(name2), name);
386
0
  _gnutls_str_cat(name2, sizeof(name2), ".extnValue");
387
388
0
  result = _gnutls_x509_write_value(asn, name2, ext_data);
389
0
  if (result < 0) {
390
0
    gnutls_assert();
391
0
    return result;
392
0
  }
393
394
0
  return 0;
395
0
}
396
397
int _gnutls_set_extension(asn1_node asn, const char *root, const char *ext_id,
398
        const gnutls_datum_t *ext_data, unsigned int critical)
399
0
{
400
0
  int result = 0;
401
0
  int k, len;
402
0
  char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
403
0
  char extnID[MAX_OID_SIZE];
404
405
  /* Find the index of the given extension.
406
   */
407
0
  k = 0;
408
0
  do {
409
0
    k++;
410
411
0
    if (root[0] != 0)
412
0
      snprintf(name, sizeof(name), "%s.?%d", root, k);
413
0
    else
414
0
      snprintf(name, sizeof(name), "?%d", k);
415
416
0
    len = sizeof(extnID) - 1;
417
0
    result = asn1_read_value(asn, name, extnID, &len);
418
419
    /* move to next
420
     */
421
422
0
    if (result == ASN1_ELEMENT_NOT_FOUND) {
423
0
      break;
424
0
    }
425
426
0
    do {
427
0
      _gnutls_str_cpy(name2, sizeof(name2), name);
428
0
      _gnutls_str_cat(name2, sizeof(name2), ".extnID");
429
430
0
      len = sizeof(extnID) - 1;
431
0
      result = asn1_read_value(asn, name2, extnID, &len);
432
433
0
      if (result == ASN1_ELEMENT_NOT_FOUND) {
434
0
        gnutls_assert();
435
0
        break;
436
0
      } else if (result != ASN1_SUCCESS) {
437
0
        gnutls_assert();
438
0
        return _gnutls_asn2err(result);
439
0
      }
440
441
      /* Handle Extension 
442
       */
443
0
      if (streq(extnID, ext_id)) {
444
        /* extension was found 
445
         */
446
0
        return overwrite_extension(asn, root, k,
447
0
                 ext_data, critical);
448
0
      }
449
450
0
    } while (0);
451
0
  } while (1);
452
453
0
  if (result == ASN1_ELEMENT_NOT_FOUND) {
454
0
    return add_extension(asn, root, ext_id, ext_data, critical);
455
0
  } else {
456
0
    gnutls_assert();
457
0
    return _gnutls_asn2err(result);
458
0
  }
459
460
0
  return 0;
461
0
}
462
463
/* This function will attempt to overwrite the requested extension with
464
 * the given one. 
465
 *
466
 * Critical will be either 0 or 1.
467
 */
468
int _gnutls_x509_crt_set_extension(gnutls_x509_crt_t cert, const char *ext_id,
469
           const gnutls_datum_t *ext_data,
470
           unsigned int critical)
471
0
{
472
0
  MODIFIED(cert);
473
0
  cert->use_extensions = 1;
474
475
0
  return _gnutls_set_extension(cert->cert, "tbsCertificate.extensions",
476
0
             ext_id, ext_data, critical);
477
0
}
478
479
int _gnutls_x509_crl_set_extension(gnutls_x509_crl_t crl, const char *ext_id,
480
           const gnutls_datum_t *ext_data,
481
           unsigned int critical)
482
0
{
483
0
  return _gnutls_set_extension(crl->crl, "tbsCertList.crlExtensions",
484
0
             ext_id, ext_data, critical);
485
0
}
486
487
int _gnutls_x509_crq_set_extension(gnutls_x509_crq_t crq, const char *ext_id,
488
           const gnutls_datum_t *ext_data,
489
           unsigned int critical)
490
0
{
491
0
  unsigned char *extensions = NULL;
492
0
  size_t extensions_size = 0;
493
0
  gnutls_datum_t der;
494
0
  asn1_node c2;
495
0
  int result;
496
497
0
  result = gnutls_x509_crq_get_attribute_by_oid(
498
0
    crq, "1.2.840.113549.1.9.14", 0, NULL, &extensions_size);
499
0
  if (result == GNUTLS_E_SHORT_MEMORY_BUFFER) {
500
0
    extensions = gnutls_malloc(extensions_size);
501
0
    if (extensions == NULL) {
502
0
      gnutls_assert();
503
0
      return GNUTLS_E_MEMORY_ERROR;
504
0
    }
505
506
0
    result = gnutls_x509_crq_get_attribute_by_oid(
507
0
      crq, "1.2.840.113549.1.9.14", 0, extensions,
508
0
      &extensions_size);
509
0
  }
510
0
  if (result < 0) {
511
0
    if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
512
0
      extensions_size = 0;
513
0
    } else {
514
0
      gnutls_assert();
515
0
      gnutls_free(extensions);
516
0
      return result;
517
0
    }
518
0
  }
519
520
0
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extensions",
521
0
             &c2);
522
0
  if (result != ASN1_SUCCESS) {
523
0
    gnutls_assert();
524
0
    gnutls_free(extensions);
525
0
    return _gnutls_asn2err(result);
526
0
  }
527
528
0
  if (extensions_size > 0) {
529
0
    result = _asn1_strict_der_decode(&c2, extensions,
530
0
             extensions_size, NULL);
531
0
    gnutls_free(extensions);
532
0
    if (result != ASN1_SUCCESS) {
533
0
      gnutls_assert();
534
0
      asn1_delete_structure(&c2);
535
0
      return _gnutls_asn2err(result);
536
0
    }
537
0
  }
538
539
0
  result = _gnutls_set_extension(c2, "", ext_id, ext_data, critical);
540
0
  if (result < 0) {
541
0
    gnutls_assert();
542
0
    asn1_delete_structure(&c2);
543
0
    return result;
544
0
  }
545
546
0
  result = _gnutls_x509_der_encode(c2, "", &der, 0);
547
548
0
  asn1_delete_structure(&c2);
549
550
0
  if (result < 0) {
551
0
    gnutls_assert();
552
0
    return result;
553
0
  }
554
555
0
  result = gnutls_x509_crq_set_attribute_by_oid(
556
0
    crq, "1.2.840.113549.1.9.14", der.data, der.size);
557
0
  gnutls_free(der.data);
558
0
  if (result < 0) {
559
0
    gnutls_assert();
560
0
    return result;
561
0
  }
562
563
0
  return 0;
564
0
}
565
566
/* extract an INTEGER from the DER encoded extension
567
 */
568
int _gnutls_x509_ext_extract_number(uint8_t *number, size_t *_nr_size,
569
            uint8_t *extnValue, int extnValueLen)
570
0
{
571
0
  asn1_node ext = NULL;
572
0
  int result;
573
0
  int nr_size = *_nr_size;
574
575
  /* here it doesn't matter so much that we use CertificateSerialNumber. It is equal
576
   * to using INTEGER.
577
   */
578
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
579
0
            "PKIX1.CertificateSerialNumber",
580
0
            &ext)) != ASN1_SUCCESS) {
581
0
    gnutls_assert();
582
0
    return _gnutls_asn2err(result);
583
0
  }
584
585
0
  result = _asn1_strict_der_decode(&ext, extnValue, extnValueLen, NULL);
586
0
  if (result != ASN1_SUCCESS) {
587
0
    gnutls_assert();
588
0
    asn1_delete_structure(&ext);
589
0
    return _gnutls_asn2err(result);
590
0
  }
591
592
  /* the default value of cA is false.
593
   */
594
0
  result = asn1_read_value(ext, "", number, &nr_size);
595
0
  if (result != ASN1_SUCCESS)
596
0
    result = _gnutls_asn2err(result);
597
0
  else
598
0
    result = 0;
599
600
0
  *_nr_size = nr_size;
601
602
0
  asn1_delete_structure(&ext);
603
604
0
  return result;
605
0
}
606
607
/* generate an INTEGER in a DER encoded extension
608
 */
609
int _gnutls_x509_ext_gen_number(const uint8_t *number, size_t nr_size,
610
        gnutls_datum_t *der_ext)
611
0
{
612
0
  asn1_node ext = NULL;
613
0
  int result;
614
615
0
  result = asn1_create_element(_gnutls_get_pkix(),
616
0
             "PKIX1.CertificateSerialNumber", &ext);
617
0
  if (result != ASN1_SUCCESS) {
618
0
    gnutls_assert();
619
0
    return _gnutls_asn2err(result);
620
0
  }
621
622
0
  result = asn1_write_value(ext, "", number, nr_size);
623
0
  if (result != ASN1_SUCCESS) {
624
0
    gnutls_assert();
625
0
    asn1_delete_structure(&ext);
626
0
    return _gnutls_asn2err(result);
627
0
  }
628
629
0
  result = _gnutls_x509_der_encode(ext, "", der_ext, 0);
630
631
0
  asn1_delete_structure(&ext);
632
633
0
  if (result < 0) {
634
0
    gnutls_assert();
635
0
    return result;
636
0
  }
637
638
0
  return 0;
639
0
}
640
641
int _gnutls_write_general_name(asn1_node ext, const char *ext_name,
642
             gnutls_x509_subject_alt_name_t type,
643
             const void *data, unsigned int data_size)
644
0
{
645
0
  const char *str;
646
0
  int result;
647
0
  char name[128];
648
649
0
  if (data == NULL) {
650
0
    if (data_size == 0)
651
0
      data = (void *)"";
652
0
    else
653
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
654
0
  }
655
656
0
  switch (type) {
657
0
  case GNUTLS_SAN_DNSNAME:
658
0
    str = "dNSName";
659
0
    break;
660
0
  case GNUTLS_SAN_RFC822NAME:
661
0
    str = "rfc822Name";
662
0
    break;
663
0
  case GNUTLS_SAN_URI:
664
0
    str = "uniformResourceIdentifier";
665
0
    break;
666
0
  case GNUTLS_SAN_IPADDRESS:
667
0
    str = "iPAddress";
668
0
    break;
669
0
  case GNUTLS_SAN_REGISTERED_ID:
670
0
    str = "registeredID";
671
0
    break;
672
0
  default:
673
0
    gnutls_assert();
674
0
    return GNUTLS_E_INTERNAL_ERROR;
675
0
  }
676
677
0
  result = asn1_write_value(ext, ext_name, str, 1);
678
0
  if (result != ASN1_SUCCESS) {
679
0
    gnutls_assert();
680
0
    return _gnutls_asn2err(result);
681
0
  }
682
683
0
  snprintf(name, sizeof(name), "%s.%s", ext_name, str);
684
685
0
  result = asn1_write_value(ext, name, data, data_size);
686
0
  if (result != ASN1_SUCCESS) {
687
0
    gnutls_assert();
688
0
    asn1_delete_structure(&ext);
689
0
    return _gnutls_asn2err(result);
690
0
  }
691
692
0
  return 0;
693
0
}
694
695
int _gnutls_write_new_general_name(asn1_node ext, const char *ext_name,
696
           gnutls_x509_subject_alt_name_t type,
697
           const void *data, unsigned int data_size)
698
0
{
699
0
  int result;
700
0
  char name[128];
701
702
0
  result = asn1_write_value(ext, ext_name, "NEW", 1);
703
0
  if (result != ASN1_SUCCESS) {
704
0
    gnutls_assert();
705
0
    return _gnutls_asn2err(result);
706
0
  }
707
708
0
  if (ext_name[0] == 0) { /* no dot */
709
0
    _gnutls_str_cpy(name, sizeof(name), "?LAST");
710
0
  } else {
711
0
    _gnutls_str_cpy(name, sizeof(name), ext_name);
712
0
    _gnutls_str_cat(name, sizeof(name), ".?LAST");
713
0
  }
714
715
0
  result = _gnutls_write_general_name(ext, name, type, data, data_size);
716
0
  if (result < 0) {
717
0
    gnutls_assert();
718
0
    return result;
719
0
  }
720
721
0
  return 0;
722
0
}
723
724
int _gnutls_write_new_othername(asn1_node ext, const char *ext_name,
725
        const char *oid, const void *data,
726
        unsigned int data_size)
727
0
{
728
0
  int result;
729
0
  char name[128];
730
0
  char name2[128];
731
732
0
  result = asn1_write_value(ext, ext_name, "NEW", 1);
733
0
  if (result != ASN1_SUCCESS) {
734
0
    gnutls_assert();
735
0
    return _gnutls_asn2err(result);
736
0
  }
737
738
0
  if (ext_name[0] == 0) { /* no dot */
739
0
    _gnutls_str_cpy(name, sizeof(name), "?LAST");
740
0
  } else {
741
0
    _gnutls_str_cpy(name, sizeof(name), ext_name);
742
0
    _gnutls_str_cat(name, sizeof(name), ".?LAST");
743
0
  }
744
745
0
  result = asn1_write_value(ext, name, "otherName", 1);
746
0
  if (result != ASN1_SUCCESS) {
747
0
    gnutls_assert();
748
0
    return _gnutls_asn2err(result);
749
0
  }
750
751
0
  snprintf(name2, sizeof(name2), "%s.otherName.type-id", name);
752
753
0
  result = asn1_write_value(ext, name2, oid, 1);
754
0
  if (result != ASN1_SUCCESS) {
755
0
    gnutls_assert();
756
0
    return _gnutls_asn2err(result);
757
0
  }
758
759
0
  snprintf(name2, sizeof(name2), "%s.otherName.value", name);
760
761
0
  result = asn1_write_value(ext, name2, data, data_size);
762
0
  if (result != ASN1_SUCCESS) {
763
0
    gnutls_assert();
764
0
    return _gnutls_asn2err(result);
765
0
  }
766
767
0
  return 0;
768
0
}
769
770
/* Convert the given name to GeneralNames in a DER encoded extension.
771
 * This is the same as subject alternative name.
772
 */
773
int _gnutls_x509_ext_gen_subject_alt_name(gnutls_x509_subject_alt_name_t type,
774
            const char *othername_oid,
775
            const void *data,
776
            unsigned int data_size,
777
            const gnutls_datum_t *prev_der_ext,
778
            gnutls_datum_t *der_ext)
779
0
{
780
0
  int ret;
781
0
  gnutls_subject_alt_names_t sans = NULL;
782
0
  gnutls_datum_t name;
783
784
0
  ret = gnutls_subject_alt_names_init(&sans);
785
0
  if (ret < 0) {
786
0
    gnutls_assert();
787
0
    return ret;
788
0
  }
789
790
0
  if (prev_der_ext && prev_der_ext->data != NULL &&
791
0
      prev_der_ext->size != 0) {
792
0
    ret = gnutls_x509_ext_import_subject_alt_names(prev_der_ext,
793
0
                     sans, 0);
794
0
    if (ret < 0) {
795
0
      gnutls_assert();
796
0
      goto cleanup;
797
0
    }
798
0
  }
799
800
0
  name.data = (void *)data;
801
0
  name.size = data_size;
802
0
  ret = gnutls_subject_alt_names_set(sans, type, &name, othername_oid);
803
0
  if (ret < 0) {
804
0
    gnutls_assert();
805
0
    goto cleanup;
806
0
  }
807
808
0
  ret = gnutls_x509_ext_export_subject_alt_names(sans, der_ext);
809
0
  if (ret < 0) {
810
0
    gnutls_assert();
811
0
    goto cleanup;
812
0
  }
813
814
0
  ret = 0;
815
0
cleanup:
816
0
  if (sans != NULL)
817
0
    gnutls_subject_alt_names_deinit(sans);
818
819
0
  return ret;
820
0
}
821
822
/* generate the AuthorityKeyID in a DER encoded extension
823
 */
824
int _gnutls_x509_ext_gen_auth_key_id(const void *id, size_t id_size,
825
             gnutls_datum_t *der_ext)
826
0
{
827
0
  gnutls_x509_aki_t aki;
828
0
  int ret;
829
0
  gnutls_datum_t l_id;
830
831
0
  ret = gnutls_x509_aki_init(&aki);
832
0
  if (ret < 0)
833
0
    return gnutls_assert_val(ret);
834
835
0
  l_id.data = (void *)id;
836
0
  l_id.size = id_size;
837
0
  ret = gnutls_x509_aki_set_id(aki, &l_id);
838
0
  if (ret < 0) {
839
0
    gnutls_assert();
840
0
    goto cleanup;
841
0
  }
842
843
0
  ret = gnutls_x509_ext_export_authority_key_id(aki, der_ext);
844
0
  if (ret < 0) {
845
0
    gnutls_assert();
846
0
    goto cleanup;
847
0
  }
848
849
0
  ret = 0;
850
851
0
cleanup:
852
0
  gnutls_x509_aki_deinit(aki);
853
0
  return ret;
854
0
}