Coverage Report

Created: 2023-03-26 07:33

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