Coverage Report

Created: 2025-03-18 06:55

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