Coverage Report

Created: 2025-07-23 07:16

/src/gnutls/lib/x509/x509_ext.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2014-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2016 Red Hat, Inc.
4
 *
5
 * This file is part of GnuTLS.
6
 *
7
 * The GnuTLS is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public License
9
 * as published by the Free Software Foundation; either version 2.1 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
19
 *
20
 */
21
22
/* This file contains functions to handle X.509 certificate extensions (the x509-ext API)
23
 */
24
25
#include "gnutls_int.h"
26
#include "datum.h"
27
#include "errors.h"
28
#include "common.h"
29
#include "x509.h"
30
#include "x509_b64.h"
31
#include "x509_ext_int.h"
32
#include "virt-san.h"
33
#include <gnutls/x509-ext.h>
34
#include "intprops.h"
35
36
0
#define MAX_ENTRIES 64
37
38
/**
39
 * gnutls_subject_alt_names_init:
40
 * @sans: The alternative names
41
 *
42
 * This function will initialize an alternative names structure.
43
 *
44
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
45
 *
46
 * Since: 3.3.0
47
 **/
48
int gnutls_subject_alt_names_init(gnutls_subject_alt_names_t *sans)
49
0
{
50
0
  *sans = gnutls_calloc(1, sizeof(struct gnutls_subject_alt_names_st));
51
0
  if (*sans == NULL) {
52
0
    gnutls_assert();
53
0
    return GNUTLS_E_MEMORY_ERROR;
54
0
  }
55
56
0
  return 0;
57
0
}
58
59
static void subject_alt_names_deinit(gnutls_subject_alt_names_t sans)
60
0
{
61
0
  unsigned int i;
62
63
0
  for (i = 0; i < sans->size; i++) {
64
0
    gnutls_free(sans->names[i].san.data);
65
0
    gnutls_free(sans->names[i].othername_oid.data);
66
0
  }
67
0
  gnutls_free(sans->names);
68
0
}
69
70
/**
71
 * gnutls_subject_alt_names_deinit:
72
 * @sans: The alternative names
73
 *
74
 * This function will deinitialize an alternative names structure.
75
 *
76
 * Since: 3.3.0
77
 **/
78
void gnutls_subject_alt_names_deinit(gnutls_subject_alt_names_t sans)
79
0
{
80
0
  subject_alt_names_deinit(sans);
81
0
  gnutls_free(sans);
82
0
}
83
84
/**
85
 * gnutls_subject_alt_names_get:
86
 * @sans: The alternative names
87
 * @seq: The index of the name to get
88
 * @san_type: Will hold the type of the name (of %gnutls_subject_alt_names_t)
89
 * @san: The alternative name data (should be treated as constant)
90
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME (should be treated as constant)
91
 *
92
 * This function will return a specific alternative name as stored in
93
 * the @sans type. The returned values should be treated as constant
94
 * and valid for the lifetime of @sans.
95
 *
96
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
97
 * if the index is out of bounds, otherwise a negative error value.
98
 *
99
 * Since: 3.3.0
100
 **/
101
int gnutls_subject_alt_names_get(gnutls_subject_alt_names_t sans,
102
         unsigned int seq, unsigned int *san_type,
103
         gnutls_datum_t *san,
104
         gnutls_datum_t *othername_oid)
105
0
{
106
0
  if (seq >= sans->size)
107
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
108
109
0
  if (san) {
110
0
    memcpy(san, &sans->names[seq].san, sizeof(gnutls_datum_t));
111
0
  }
112
113
0
  if (san_type)
114
0
    *san_type = sans->names[seq].type;
115
116
0
  if (othername_oid != NULL &&
117
0
      sans->names[seq].type == GNUTLS_SAN_OTHERNAME) {
118
0
    othername_oid->data = sans->names[seq].othername_oid.data;
119
0
    othername_oid->size = sans->names[seq].othername_oid.size;
120
0
  }
121
122
0
  return 0;
123
0
}
124
125
/* This is the same as gnutls_subject_alt_names_set() but will not
126
 * copy the strings. It expects all the provided input to be already
127
 * allocated by gnutls. */
128
static int subject_alt_names_set(struct name_st **names, unsigned int *size,
129
         unsigned int san_type, gnutls_datum_t *san,
130
         char *othername_oid, unsigned raw)
131
0
{
132
0
  void *tmp;
133
0
  int ret;
134
135
0
  if (unlikely(INT_ADD_OVERFLOW(*size, 1))) {
136
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
137
0
  }
138
139
0
  tmp = _gnutls_reallocarray(*names, *size + 1, sizeof((*names)[0]));
140
0
  if (tmp == NULL) {
141
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
142
0
  }
143
0
  *names = tmp;
144
145
0
  ret = _gnutls_alt_name_assign_virt_type(&(*names)[*size], san_type, san,
146
0
            othername_oid, raw);
147
0
  if (ret < 0)
148
0
    return gnutls_assert_val(ret);
149
150
0
  (*size)++;
151
0
  return 0;
152
0
}
153
154
/**
155
 * gnutls_subject_alt_names_set:
156
 * @sans: The alternative names
157
 * @san_type: The type of the name (of %gnutls_subject_alt_names_t)
158
 * @san: The alternative name data
159
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
160
 *
161
 * This function will store the specified alternative name in
162
 * the @sans.
163
 *
164
 * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
165
 * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
166
 *
167
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
168
 *
169
 * Since: 3.3.0
170
 **/
171
int gnutls_subject_alt_names_set(gnutls_subject_alt_names_t sans,
172
         unsigned int san_type,
173
         const gnutls_datum_t *san,
174
         const char *othername_oid)
175
0
{
176
0
  int ret;
177
0
  gnutls_datum_t copy;
178
0
  char *ooc;
179
180
0
  ret = _gnutls_set_strdatum(&copy, san->data, san->size);
181
0
  if (ret < 0)
182
0
    return gnutls_assert_val(ret);
183
184
0
  if (othername_oid != NULL)
185
0
    ooc = gnutls_strdup(othername_oid);
186
0
  else
187
0
    ooc = NULL;
188
0
  ret = subject_alt_names_set(&sans->names, &sans->size, san_type, &copy,
189
0
            ooc, 0);
190
0
  if (ret < 0) {
191
0
    gnutls_free(ooc);
192
0
    gnutls_free(copy.data);
193
0
    return gnutls_assert_val(ret);
194
0
  }
195
196
0
  return 0;
197
0
}
198
199
/**
200
 * gnutls_x509_ext_import_subject_alt_names:
201
 * @ext: The DER-encoded extension data
202
 * @sans: The alternative names
203
 * @flags: should be zero
204
 *
205
 * This function will export the alternative names in the provided DER-encoded
206
 * SubjectAltName PKIX extension, to a %gnutls_subject_alt_names_t type. @sans
207
 * must be initialized.
208
 *
209
 * This function will succeed even if there no subject alternative names
210
 * in the structure.
211
 *
212
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
213
 *
214
 * Since: 3.3.0
215
 **/
216
int gnutls_x509_ext_import_subject_alt_names(const gnutls_datum_t *ext,
217
               gnutls_subject_alt_names_t sans,
218
               unsigned int flags)
219
0
{
220
0
  asn1_node c2 = NULL;
221
0
  int result, ret;
222
0
  unsigned int i;
223
0
  gnutls_datum_t san, othername_oid;
224
0
  unsigned type;
225
226
0
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.GeneralNames",
227
0
             &c2);
228
0
  if (result != ASN1_SUCCESS) {
229
0
    gnutls_assert();
230
0
    return _gnutls_asn2err(result);
231
0
  }
232
233
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
234
0
  if (result != ASN1_SUCCESS) {
235
0
    gnutls_assert();
236
0
    ret = _gnutls_asn2err(result);
237
0
    goto cleanup;
238
0
  }
239
240
0
  for (i = 0;; i++) {
241
0
    san.data = NULL;
242
0
    san.size = 0;
243
0
    othername_oid.data = NULL;
244
245
0
    ret = _gnutls_parse_general_name2(c2, "", i, &san, &type, 0);
246
0
    if (ret < 0)
247
0
      break;
248
249
0
    if (type == GNUTLS_SAN_OTHERNAME) {
250
0
      ret = _gnutls_parse_general_name2(
251
0
        c2, "", i, &othername_oid, NULL, 1);
252
0
      if (ret < 0)
253
0
        break;
254
255
0
    } else if (san.size == 0 || san.data == NULL) {
256
0
      ret = gnutls_assert_val(GNUTLS_E_X509_UNKNOWN_SAN);
257
0
      break;
258
0
    }
259
260
0
    ret = subject_alt_names_set(&sans->names, &sans->size, type,
261
0
              &san, (char *)othername_oid.data,
262
0
              1);
263
0
    if (ret < 0)
264
0
      break;
265
0
  }
266
267
0
  sans->size = i;
268
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
269
0
    gnutls_free(san.data);
270
0
    gnutls_free(othername_oid.data);
271
0
    gnutls_assert();
272
0
    goto cleanup;
273
0
  }
274
275
0
  ret = 0;
276
0
cleanup:
277
0
  asn1_delete_structure(&c2);
278
0
  return ret;
279
0
}
280
281
/**
282
 * gnutls_x509_ext_export_subject_alt_names:
283
 * @sans: The alternative names
284
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
285
 *
286
 * This function will convert the provided alternative names structure to a
287
 * DER-encoded SubjectAltName PKIX extension. The output data in @ext will be allocated using
288
 * gnutls_malloc().
289
 *
290
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
291
 *
292
 * Since: 3.3.0
293
 **/
294
int gnutls_x509_ext_export_subject_alt_names(gnutls_subject_alt_names_t sans,
295
               gnutls_datum_t *ext)
296
0
{
297
0
  asn1_node c2 = NULL;
298
0
  int result, ret;
299
0
  unsigned i;
300
301
0
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.GeneralNames",
302
0
             &c2);
303
0
  if (result != ASN1_SUCCESS) {
304
0
    gnutls_assert();
305
0
    return _gnutls_asn2err(result);
306
0
  }
307
308
0
  for (i = 0; i < sans->size; i++) {
309
0
    if (sans->names[i].type == GNUTLS_SAN_OTHERNAME) {
310
0
      ret = _gnutls_write_new_othername(
311
0
        c2, "",
312
0
        (char *)sans->names[i].othername_oid.data,
313
0
        sans->names[i].san.data,
314
0
        sans->names[i].san.size);
315
0
    } else {
316
0
      ret = _gnutls_write_new_general_name(
317
0
        c2, "", sans->names[i].type,
318
0
        sans->names[i].san.data,
319
0
        sans->names[i].san.size);
320
0
    }
321
322
0
    if (ret < 0) {
323
0
      gnutls_assert();
324
0
      goto cleanup;
325
0
    }
326
0
  }
327
328
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
329
0
  if (ret < 0) {
330
0
    gnutls_assert();
331
0
    goto cleanup;
332
0
  }
333
334
0
  ret = 0;
335
336
0
cleanup:
337
0
  asn1_delete_structure(&c2);
338
0
  return ret;
339
0
}
340
341
/**
342
 * gnutls_x509_ext_import_name_constraints:
343
 * @ext: a DER encoded extension
344
 * @nc: The nameconstraints
345
 * @flags: zero or %GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND
346
 *
347
 * This function will return an intermediate type containing
348
 * the name constraints of the provided NameConstraints extension. That
349
 * can be used in combination with gnutls_x509_name_constraints_check()
350
 * to verify whether a server's name is in accordance with the constraints.
351
 *
352
 * When the @flags is set to %GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND, then if 
353
 * the @nc type is empty this function will behave identically as if the flag was not set.
354
 * Otherwise if there are elements in the @nc structure then the
355
 * constraints will be merged with the existing constraints following
356
 * RFC5280 p6.1.4 (excluded constraints will be appended, permitted
357
 * will be intersected).
358
 *
359
 * Note that @nc must be initialized prior to calling this function.
360
 *
361
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
362
 * if the extension is not present, otherwise a negative error value.
363
 *
364
 * Since: 3.3.0
365
 **/
366
int gnutls_x509_ext_import_name_constraints(const gnutls_datum_t *ext,
367
              gnutls_x509_name_constraints_t nc,
368
              unsigned int flags)
369
0
{
370
0
  int result, ret;
371
0
  asn1_node c2 = NULL;
372
0
  gnutls_x509_name_constraints_t nc2 = NULL;
373
374
0
  result = asn1_create_element(_gnutls_get_pkix(),
375
0
             "PKIX1.NameConstraints", &c2);
376
0
  if (result != ASN1_SUCCESS) {
377
0
    gnutls_assert();
378
0
    return _gnutls_asn2err(result);
379
0
  }
380
381
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
382
0
  if (result != ASN1_SUCCESS) {
383
0
    gnutls_assert();
384
0
    ret = _gnutls_asn2err(result);
385
0
    goto cleanup;
386
0
  }
387
388
0
  if (flags & GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND &&
389
0
      !_gnutls_x509_name_constraints_is_empty(nc, 0)) {
390
0
    ret = gnutls_x509_name_constraints_init(&nc2);
391
0
    if (ret < 0) {
392
0
      gnutls_assert();
393
0
      goto cleanup;
394
0
    }
395
396
0
    ret = _gnutls_x509_name_constraints_extract(
397
0
      c2, "permittedSubtrees", "excludedSubtrees", nc2);
398
0
    if (ret < 0) {
399
0
      gnutls_assert();
400
0
      goto cleanup;
401
0
    }
402
403
0
    ret = _gnutls_x509_name_constraints_merge(nc, nc2);
404
0
    if (ret < 0) {
405
0
      gnutls_assert();
406
0
      goto cleanup;
407
0
    }
408
0
  } else {
409
0
    _gnutls_x509_name_constraints_clear(nc);
410
411
0
    ret = _gnutls_x509_name_constraints_extract(
412
0
      c2, "permittedSubtrees", "excludedSubtrees", nc);
413
0
    if (ret < 0) {
414
0
      gnutls_assert();
415
0
      goto cleanup;
416
0
    }
417
0
  }
418
419
0
  ret = 0;
420
421
0
cleanup:
422
0
  asn1_delete_structure(&c2);
423
0
  if (nc2)
424
0
    gnutls_x509_name_constraints_deinit(nc2);
425
426
0
  return ret;
427
0
}
428
429
/**
430
 * gnutls_x509_ext_export_name_constraints:
431
 * @nc: The nameconstraints
432
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
433
 *
434
 * This function will convert the provided name constraints type to a
435
 * DER-encoded PKIX NameConstraints (2.5.29.30) extension. The output data in 
436
 * @ext will be allocated using gnutls_malloc().
437
 *
438
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
439
 *
440
 * Since: 3.3.0
441
 **/
442
int gnutls_x509_ext_export_name_constraints(gnutls_x509_name_constraints_t nc,
443
              gnutls_datum_t *ext)
444
0
{
445
0
  int ret, result;
446
0
  uint8_t null = 0;
447
0
  asn1_node c2 = NULL;
448
0
  unsigned rtype;
449
0
  gnutls_datum_t rname;
450
451
0
  if (_gnutls_x509_name_constraints_is_empty(nc, 0))
452
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
453
454
0
  result = asn1_create_element(_gnutls_get_pkix(),
455
0
             "PKIX1.NameConstraints", &c2);
456
0
  if (result != ASN1_SUCCESS) {
457
0
    gnutls_assert();
458
0
    return _gnutls_asn2err(result);
459
0
  }
460
461
0
  ret = gnutls_x509_name_constraints_get_permitted(nc, 0, &rtype, &rname);
462
0
  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
463
0
    (void)asn1_write_value(c2, "permittedSubtrees", NULL, 0);
464
0
  } else {
465
0
    for (unsigned i = 0;; i++) {
466
0
      ret = gnutls_x509_name_constraints_get_permitted(
467
0
        nc, i, &rtype, &rname);
468
0
      if (ret < 0) {
469
0
        if (ret ==
470
0
            GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
471
0
          break;
472
0
        gnutls_assert();
473
0
        goto cleanup;
474
0
      }
475
0
      result = asn1_write_value(c2, "permittedSubtrees",
476
0
              "NEW", 1);
477
0
      if (result != ASN1_SUCCESS) {
478
0
        gnutls_assert();
479
0
        ret = _gnutls_asn2err(result);
480
0
        goto cleanup;
481
0
      }
482
483
0
      result = asn1_write_value(
484
0
        c2, "permittedSubtrees.?LAST.maximum", NULL, 0);
485
0
      if (result != ASN1_SUCCESS) {
486
0
        gnutls_assert();
487
0
        ret = _gnutls_asn2err(result);
488
0
        goto cleanup;
489
0
      }
490
491
0
      result = asn1_write_value(
492
0
        c2, "permittedSubtrees.?LAST.minimum", &null,
493
0
        1);
494
0
      if (result != ASN1_SUCCESS) {
495
0
        gnutls_assert();
496
0
        ret = _gnutls_asn2err(result);
497
0
        goto cleanup;
498
0
      }
499
500
0
      ret = _gnutls_write_general_name(
501
0
        c2, "permittedSubtrees.?LAST.base", rtype,
502
0
        rname.data, rname.size);
503
0
      if (ret < 0) {
504
0
        gnutls_assert();
505
0
        goto cleanup;
506
0
      }
507
0
    }
508
0
  }
509
510
0
  ret = gnutls_x509_name_constraints_get_excluded(nc, 0, &rtype, &rname);
511
0
  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
512
0
    (void)asn1_write_value(c2, "excludedSubtrees", NULL, 0);
513
0
  } else {
514
0
    for (unsigned i = 0;; i++) {
515
0
      ret = gnutls_x509_name_constraints_get_excluded(
516
0
        nc, i, &rtype, &rname);
517
0
      if (ret < 0) {
518
0
        if (ret ==
519
0
            GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
520
0
          break;
521
0
        gnutls_assert();
522
0
        goto cleanup;
523
0
      }
524
0
      result = asn1_write_value(c2, "excludedSubtrees", "NEW",
525
0
              1);
526
0
      if (result != ASN1_SUCCESS) {
527
0
        gnutls_assert();
528
0
        ret = _gnutls_asn2err(result);
529
0
        goto cleanup;
530
0
      }
531
532
0
      result = asn1_write_value(
533
0
        c2, "excludedSubtrees.?LAST.maximum", NULL, 0);
534
0
      if (result != ASN1_SUCCESS) {
535
0
        gnutls_assert();
536
0
        ret = _gnutls_asn2err(result);
537
0
        goto cleanup;
538
0
      }
539
540
0
      result = asn1_write_value(
541
0
        c2, "excludedSubtrees.?LAST.minimum", &null, 1);
542
0
      if (result != ASN1_SUCCESS) {
543
0
        gnutls_assert();
544
0
        ret = _gnutls_asn2err(result);
545
0
        goto cleanup;
546
0
      }
547
548
0
      ret = _gnutls_write_general_name(
549
0
        c2, "excludedSubtrees.?LAST.base", rtype,
550
0
        rname.data, rname.size);
551
0
      if (ret < 0) {
552
0
        gnutls_assert();
553
0
        goto cleanup;
554
0
      }
555
0
    }
556
0
  }
557
558
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
559
0
  if (ret < 0) {
560
0
    gnutls_assert();
561
0
    goto cleanup;
562
0
  }
563
564
0
  ret = 0;
565
566
0
cleanup:
567
0
  asn1_delete_structure(&c2);
568
0
  return ret;
569
0
}
570
571
/**
572
 * gnutls_x509_ext_import_subject_key_id:
573
 * @ext: a DER encoded extension
574
 * @id: will contain the subject key ID
575
 *
576
 * This function will return the subject key ID stored in the provided
577
 * SubjectKeyIdentifier extension. The ID will be allocated using
578
 * gnutls_malloc().
579
 *
580
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
581
 * if the extension is not present, otherwise a negative error value.
582
 *
583
 * Since: 3.3.0
584
 **/
585
int gnutls_x509_ext_import_subject_key_id(const gnutls_datum_t *ext,
586
            gnutls_datum_t *id)
587
0
{
588
0
  int result, ret;
589
0
  asn1_node c2 = NULL;
590
591
0
  if (ext->size == 0 || ext->data == NULL) {
592
0
    gnutls_assert();
593
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
594
0
  }
595
596
0
  result = asn1_create_element(_gnutls_get_pkix(),
597
0
             "PKIX1.SubjectKeyIdentifier", &c2);
598
0
  if (result != ASN1_SUCCESS) {
599
0
    gnutls_assert();
600
0
    return _gnutls_asn2err(result);
601
0
  }
602
603
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
604
0
  if (result != ASN1_SUCCESS) {
605
0
    gnutls_assert();
606
0
    ret = _gnutls_asn2err(result);
607
0
    goto cleanup;
608
0
  }
609
610
0
  ret = _gnutls_x509_read_value(c2, "", id);
611
0
  if (ret < 0) {
612
0
    gnutls_assert();
613
0
    goto cleanup;
614
0
  }
615
616
0
  ret = 0;
617
0
cleanup:
618
0
  asn1_delete_structure(&c2);
619
620
0
  return ret;
621
0
}
622
623
/**
624
 * gnutls_x509_ext_export_subject_key_id:
625
 * @id: The key identifier
626
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
627
 *
628
 * This function will convert the provided key identifier to a
629
 * DER-encoded PKIX SubjectKeyIdentifier extension. 
630
 * The output data in @ext will be allocated using
631
 * gnutls_malloc().
632
 *
633
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
634
 *
635
 * Since: 3.3.0
636
 **/
637
int gnutls_x509_ext_export_subject_key_id(const gnutls_datum_t *id,
638
            gnutls_datum_t *ext)
639
0
{
640
0
  asn1_node c2 = NULL;
641
0
  int ret, result;
642
643
0
  result = asn1_create_element(_gnutls_get_pkix(),
644
0
             "PKIX1.SubjectKeyIdentifier", &c2);
645
0
  if (result != ASN1_SUCCESS) {
646
0
    gnutls_assert();
647
0
    return _gnutls_asn2err(result);
648
0
  }
649
650
0
  result = asn1_write_value(c2, "", id->data, id->size);
651
0
  if (result != ASN1_SUCCESS) {
652
0
    gnutls_assert();
653
0
    ret = _gnutls_asn2err(result);
654
0
    goto cleanup;
655
0
  }
656
657
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
658
0
  if (ret < 0) {
659
0
    gnutls_assert();
660
0
    goto cleanup;
661
0
  }
662
663
0
  ret = 0;
664
0
cleanup:
665
0
  asn1_delete_structure(&c2);
666
0
  return ret;
667
0
}
668
669
struct gnutls_x509_aki_st {
670
  gnutls_datum_t id;
671
  struct gnutls_subject_alt_names_st cert_issuer;
672
  gnutls_datum_t serial;
673
};
674
675
/**
676
 * gnutls_x509_aki_init:
677
 * @aki: The authority key ID type
678
 *
679
 * This function will initialize an authority key ID.
680
 *
681
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
682
 *
683
 * Since: 3.3.0
684
 **/
685
int gnutls_x509_aki_init(gnutls_x509_aki_t *aki)
686
0
{
687
0
  *aki = gnutls_calloc(1, sizeof(struct gnutls_x509_aki_st));
688
0
  if (*aki == NULL)
689
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
690
691
0
  return 0;
692
0
}
693
694
/**
695
 * gnutls_x509_aki_deinit:
696
 * @aki: The authority key identifier type
697
 *
698
 * This function will deinitialize an authority key identifier.
699
 *
700
 * Since: 3.3.0
701
 **/
702
void gnutls_x509_aki_deinit(gnutls_x509_aki_t aki)
703
0
{
704
0
  gnutls_free(aki->serial.data);
705
0
  gnutls_free(aki->id.data);
706
0
  subject_alt_names_deinit(&aki->cert_issuer);
707
0
  gnutls_free(aki);
708
0
}
709
710
/**
711
 * gnutls_x509_aki_get_id:
712
 * @aki: The authority key ID
713
 * @id: Will hold the identifier
714
 *
715
 * This function will return the key identifier as stored in
716
 * the @aki type. The identifier should be treated as constant.
717
 *
718
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
719
 * if the index is out of bounds, otherwise a negative error value.
720
 *
721
 * Since: 3.3.0
722
 **/
723
int gnutls_x509_aki_get_id(gnutls_x509_aki_t aki, gnutls_datum_t *id)
724
0
{
725
0
  if (aki->id.size == 0)
726
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
727
728
0
  memcpy(id, &aki->id, sizeof(gnutls_datum_t));
729
0
  return 0;
730
0
}
731
732
/**
733
 * gnutls_x509_aki_set_id:
734
 * @aki: The authority key ID
735
 * @id: the key identifier
736
 *
737
 * This function will set the keyIdentifier to be stored in the @aki
738
 * type.
739
 *
740
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
741
 *
742
 * Since: 3.3.0
743
 **/
744
int gnutls_x509_aki_set_id(gnutls_x509_aki_t aki, const gnutls_datum_t *id)
745
0
{
746
0
  return _gnutls_set_datum(&aki->id, id->data, id->size);
747
0
}
748
749
/**
750
 * gnutls_x509_aki_set_cert_issuer:
751
 * @aki: The authority key ID
752
 * @san_type: the type of the name (of %gnutls_subject_alt_names_t), may be null
753
 * @san: The alternative name data
754
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
755
 * @serial: The authorityCertSerialNumber number (may be null)
756
 *
757
 * This function will set the authorityCertIssuer name and the authorityCertSerialNumber 
758
 * to be stored in the @aki type. When storing multiple names, the serial
759
 * should be set on the first call, and subsequent calls should use a %NULL serial.
760
 *
761
 * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
762
 * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
763
 *
764
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
765
 *
766
 * Since: 3.3.0
767
 **/
768
int gnutls_x509_aki_set_cert_issuer(gnutls_x509_aki_t aki,
769
            unsigned int san_type,
770
            const gnutls_datum_t *san,
771
            const char *othername_oid,
772
            const gnutls_datum_t *serial)
773
0
{
774
0
  int ret;
775
0
  gnutls_datum_t t_san, t_othername_oid = { NULL, 0 };
776
777
0
  ret = _gnutls_set_datum(&aki->serial, serial->data, serial->size);
778
0
  if (ret < 0)
779
0
    return gnutls_assert_val(ret);
780
781
0
  aki->cert_issuer.names[aki->cert_issuer.size].type = san_type;
782
783
0
  ret = _gnutls_set_strdatum(&t_san, san->data, san->size);
784
0
  if (ret < 0)
785
0
    return gnutls_assert_val(ret);
786
787
0
  if (othername_oid) {
788
0
    t_othername_oid.data = (uint8_t *)gnutls_strdup(othername_oid);
789
0
    if (t_othername_oid.data == NULL) {
790
0
      gnutls_free(t_san.data);
791
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
792
0
    }
793
0
    t_othername_oid.size = strlen(othername_oid);
794
0
  }
795
796
0
  ret = subject_alt_names_set(&aki->cert_issuer.names,
797
0
            &aki->cert_issuer.size, san_type, &t_san,
798
0
            (char *)t_othername_oid.data, 0);
799
0
  if (ret < 0) {
800
0
    gnutls_free(t_othername_oid.data);
801
0
    gnutls_free(t_san.data);
802
0
    gnutls_assert();
803
0
    return ret;
804
0
  }
805
806
0
  return 0;
807
0
}
808
809
/**
810
 * gnutls_x509_aki_get_cert_issuer:
811
 * @aki: The authority key ID
812
 * @seq: The index of the name to get
813
 * @san_type: Will hold the type of the name (of %gnutls_subject_alt_names_t)
814
 * @san: The alternative name data
815
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
816
 * @serial: The authorityCertSerialNumber number
817
 *
818
 * This function will return a specific authorityCertIssuer name as stored in
819
 * the @aki type, as well as the authorityCertSerialNumber. All the returned
820
 * values should be treated as constant, and may be set to %NULL when are not required.
821
 *
822
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
823
 * if the index is out of bounds, otherwise a negative error value.
824
 *
825
 * Since: 3.3.0
826
 **/
827
int gnutls_x509_aki_get_cert_issuer(gnutls_x509_aki_t aki, unsigned int seq,
828
            unsigned int *san_type, gnutls_datum_t *san,
829
            gnutls_datum_t *othername_oid,
830
            gnutls_datum_t *serial)
831
0
{
832
0
  if (seq >= aki->cert_issuer.size)
833
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
834
835
0
  if (aki->serial.size == 0)
836
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
837
838
0
  if (serial)
839
0
    memcpy(serial, &aki->serial, sizeof(gnutls_datum_t));
840
841
0
  if (san) {
842
0
    memcpy(san, &aki->cert_issuer.names[seq].san,
843
0
           sizeof(gnutls_datum_t));
844
0
  }
845
846
0
  if (othername_oid != NULL &&
847
0
      aki->cert_issuer.names[seq].type == GNUTLS_SAN_OTHERNAME) {
848
0
    othername_oid->data =
849
0
      aki->cert_issuer.names[seq].othername_oid.data;
850
0
    othername_oid->size =
851
0
      aki->cert_issuer.names[seq].othername_oid.size;
852
0
  }
853
854
0
  if (san_type)
855
0
    *san_type = aki->cert_issuer.names[seq].type;
856
857
0
  return 0;
858
0
}
859
860
/**
861
 * gnutls_x509_ext_import_authority_key_id:
862
 * @ext: a DER encoded extension
863
 * @aki: An initialized authority key identifier type
864
 * @flags: should be zero
865
 *
866
 * This function will return the subject key ID stored in the provided
867
 * AuthorityKeyIdentifier extension.
868
 *
869
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
870
 * if the extension is not present, otherwise a negative error value.
871
 *
872
 * Since: 3.3.0
873
 **/
874
int gnutls_x509_ext_import_authority_key_id(const gnutls_datum_t *ext,
875
              gnutls_x509_aki_t aki,
876
              unsigned int flags)
877
0
{
878
0
  int ret;
879
0
  unsigned i;
880
0
  asn1_node c2 = NULL;
881
0
  gnutls_datum_t san, othername_oid;
882
0
  unsigned type;
883
884
0
  ret = asn1_create_element(_gnutls_get_pkix(),
885
0
          "PKIX1.AuthorityKeyIdentifier", &c2);
886
0
  if (ret != ASN1_SUCCESS) {
887
0
    gnutls_assert();
888
0
    return _gnutls_asn2err(ret);
889
0
  }
890
891
0
  ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
892
0
  if (ret != ASN1_SUCCESS) {
893
0
    gnutls_assert();
894
0
    ret = _gnutls_asn2err(ret);
895
0
    goto cleanup;
896
0
  }
897
898
  /* Read authorityCertIssuer */
899
0
  for (i = 0;; i++) {
900
0
    san.data = NULL;
901
0
    san.size = 0;
902
0
    othername_oid.data = NULL;
903
904
0
    ret = _gnutls_parse_general_name2(c2, "authorityCertIssuer", i,
905
0
              &san, &type, 0);
906
0
    if (ret < 0)
907
0
      break;
908
909
0
    if (type == GNUTLS_SAN_OTHERNAME) {
910
0
      ret = _gnutls_parse_general_name2(c2,
911
0
                "authorityCertIssuer",
912
0
                i, &othername_oid,
913
0
                NULL, 1);
914
0
      if (ret < 0)
915
0
        break;
916
0
    }
917
918
0
    ret = subject_alt_names_set(&aki->cert_issuer.names,
919
0
              &aki->cert_issuer.size, type, &san,
920
0
              (char *)othername_oid.data, 1);
921
0
    if (ret < 0)
922
0
      break;
923
0
  }
924
925
0
  assert(ret < 0);
926
0
  aki->cert_issuer.size = i;
927
0
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE &&
928
0
      ret != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
929
0
    gnutls_assert();
930
0
    gnutls_free(san.data);
931
0
    gnutls_free(othername_oid.data);
932
0
    goto cleanup;
933
0
  }
934
935
  /* Read the serial number */
936
0
  ret = _gnutls_x509_read_value(c2, "authorityCertSerialNumber",
937
0
              &aki->serial);
938
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE &&
939
0
      ret != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
940
0
    gnutls_assert();
941
0
    goto cleanup;
942
0
  }
943
944
  /* Read the key identifier */
945
0
  ret = _gnutls_x509_read_value(c2, "keyIdentifier", &aki->id);
946
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE &&
947
0
      ret != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
948
0
    gnutls_assert();
949
0
    goto cleanup;
950
0
  }
951
952
0
  ret = 0;
953
954
0
cleanup:
955
0
  asn1_delete_structure(&c2);
956
957
0
  return ret;
958
0
}
959
960
/**
961
 * gnutls_x509_ext_export_authority_key_id:
962
 * @aki: An initialized authority key identifier
963
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
964
 *
965
 * This function will convert the provided key identifier to a
966
 * DER-encoded PKIX AuthorityKeyIdentifier extension. 
967
 * The output data in @ext will be allocated using
968
 * gnutls_malloc().
969
 *
970
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
971
 *
972
 * Since: 3.3.0
973
 **/
974
int gnutls_x509_ext_export_authority_key_id(gnutls_x509_aki_t aki,
975
              gnutls_datum_t *ext)
976
0
{
977
0
  asn1_node c2 = NULL;
978
0
  unsigned i;
979
0
  int result, ret;
980
981
0
  result = asn1_create_element(_gnutls_get_pkix(),
982
0
             "PKIX1.AuthorityKeyIdentifier", &c2);
983
0
  if (result != ASN1_SUCCESS) {
984
0
    gnutls_assert();
985
0
    return _gnutls_asn2err(result);
986
0
  }
987
988
0
  if (aki->id.data != NULL) {
989
0
    result = asn1_write_value(c2, "keyIdentifier", aki->id.data,
990
0
            aki->id.size);
991
0
    if (result != ASN1_SUCCESS) {
992
0
      gnutls_assert();
993
0
      ret = _gnutls_asn2err(result);
994
0
      goto cleanup;
995
0
    }
996
0
  } else {
997
0
    (void)asn1_write_value(c2, "keyIdentifier", NULL, 0);
998
0
  }
999
1000
0
  if (aki->serial.data != NULL) {
1001
0
    result = asn1_write_value(c2, "authorityCertSerialNumber",
1002
0
            aki->serial.data, aki->serial.size);
1003
0
    if (result != ASN1_SUCCESS) {
1004
0
      gnutls_assert();
1005
0
      ret = _gnutls_asn2err(result);
1006
0
      goto cleanup;
1007
0
    }
1008
0
  } else {
1009
0
    (void)asn1_write_value(c2, "authorityCertSerialNumber", NULL,
1010
0
               0);
1011
0
  }
1012
1013
0
  if (aki->cert_issuer.size == 0) {
1014
0
    (void)asn1_write_value(c2, "authorityCertIssuer", NULL, 0);
1015
0
  } else {
1016
0
    for (i = 0; i < aki->cert_issuer.size; i++) {
1017
0
      ret = _gnutls_write_new_general_name(
1018
0
        c2, "authorityCertIssuer",
1019
0
        aki->cert_issuer.names[i].type,
1020
0
        aki->cert_issuer.names[i].san.data,
1021
0
        aki->cert_issuer.names[i].san.size);
1022
0
      if (ret < 0) {
1023
0
        gnutls_assert();
1024
0
        goto cleanup;
1025
0
      }
1026
0
    }
1027
0
  }
1028
1029
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
1030
0
  if (ret < 0) {
1031
0
    gnutls_assert();
1032
0
    goto cleanup;
1033
0
  }
1034
1035
0
  ret = 0;
1036
0
cleanup:
1037
0
  asn1_delete_structure(&c2);
1038
0
  return ret;
1039
0
}
1040
1041
/**
1042
 * gnutls_x509_ext_import_key_usage:
1043
 * @ext: the DER encoded extension data
1044
 * @key_usage: where the key usage bits will be stored
1045
 *
1046
 * This function will return certificate's key usage, by reading the DER
1047
 * data of the keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1048
 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1049
 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1050
 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1051
 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1052
 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1053
 *
1054
 * Returns: the certificate key usage, or a negative error code in case of
1055
 *   parsing error.  If the certificate does not contain the keyUsage
1056
 *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1057
 *   returned.
1058
 *
1059
 * Since: 3.3.0
1060
 **/
1061
int gnutls_x509_ext_import_key_usage(const gnutls_datum_t *ext,
1062
             unsigned int *key_usage)
1063
0
{
1064
0
  asn1_node c2 = NULL;
1065
0
  int len, result;
1066
0
  uint8_t str[2];
1067
1068
0
  str[0] = str[1] = 0;
1069
0
  *key_usage = 0;
1070
1071
0
  if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.KeyUsage",
1072
0
            &c2)) != ASN1_SUCCESS) {
1073
0
    gnutls_assert();
1074
0
    return _gnutls_asn2err(result);
1075
0
  }
1076
1077
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1078
0
  if (result != ASN1_SUCCESS) {
1079
0
    gnutls_assert();
1080
0
    asn1_delete_structure(&c2);
1081
0
    return _gnutls_asn2err(result);
1082
0
  }
1083
1084
0
  len = sizeof(str);
1085
0
  result = asn1_read_value(c2, "", str, &len);
1086
0
  if (result != ASN1_SUCCESS) {
1087
0
    gnutls_assert();
1088
0
    asn1_delete_structure(&c2);
1089
0
    return _gnutls_asn2err(result);
1090
0
  }
1091
1092
0
  *key_usage = str[0] | (str[1] << 8);
1093
1094
0
  asn1_delete_structure(&c2);
1095
1096
0
  return 0;
1097
0
}
1098
1099
static int _last_key_usage_set_bit(int usage)
1100
0
{
1101
  /* the byte ordering is a bit strange here, see how GNUTLS_KEY_* is laid out, and how 
1102
 * asn1_write_value() writes out BIT STRING objects.
1103
 */
1104
0
  if (usage & GNUTLS_KEY_DECIPHER_ONLY)
1105
0
    return 9;
1106
0
  else if (usage & GNUTLS_KEY_ENCIPHER_ONLY)
1107
0
    return 8;
1108
0
  else if (usage & GNUTLS_KEY_CRL_SIGN)
1109
0
    return 7;
1110
0
  else if (usage & GNUTLS_KEY_KEY_CERT_SIGN)
1111
0
    return 6;
1112
0
  else if (usage & GNUTLS_KEY_KEY_AGREEMENT)
1113
0
    return 5;
1114
0
  else if (usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
1115
0
    return 4;
1116
0
  else if (usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
1117
0
    return 3;
1118
0
  else if (usage & GNUTLS_KEY_NON_REPUDIATION)
1119
0
    return 2;
1120
0
  else if (usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
1121
0
    return 1;
1122
0
  else
1123
0
    return 0;
1124
0
}
1125
1126
/**
1127
 * gnutls_x509_ext_export_key_usage:
1128
 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
1129
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1130
 *
1131
 * This function will convert the keyUsage bit string to a DER
1132
 * encoded PKIX extension. The @ext data will be allocated using
1133
 * gnutls_malloc().
1134
 *
1135
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1136
 *   negative error value.
1137
 *
1138
 * Since: 3.3.0
1139
 **/
1140
int gnutls_x509_ext_export_key_usage(unsigned int usage, gnutls_datum_t *ext)
1141
0
{
1142
0
  asn1_node c2 = NULL;
1143
0
  int result;
1144
0
  uint8_t str[2];
1145
1146
0
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.KeyUsage", &c2);
1147
0
  if (result != ASN1_SUCCESS) {
1148
0
    gnutls_assert();
1149
0
    return _gnutls_asn2err(result);
1150
0
  }
1151
1152
0
  str[0] = usage & 0xff;
1153
0
  str[1] = usage >> 8;
1154
1155
  /* Since KeyUsage is a BIT STRING, the input to asn1_write_value
1156
   * is the number of bits to be written/read. */
1157
0
  result = asn1_write_value(c2, "", str, _last_key_usage_set_bit(usage));
1158
0
  if (result != ASN1_SUCCESS) {
1159
0
    gnutls_assert();
1160
0
    asn1_delete_structure(&c2);
1161
0
    return _gnutls_asn2err(result);
1162
0
  }
1163
1164
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
1165
1166
0
  asn1_delete_structure(&c2);
1167
1168
0
  if (result < 0) {
1169
0
    gnutls_assert();
1170
0
    return result;
1171
0
  }
1172
1173
0
  return 0;
1174
0
}
1175
1176
/**
1177
 * gnutls_x509_ext_import_inhibit_anypolicy:
1178
 * @ext: the DER encoded extension data
1179
 * @skipcerts: will hold the number of certificates after which anypolicy is no longer acceptable.
1180
 *
1181
 * This function will return certificate's value of SkipCerts,
1182
 * by reading the DER data of the Inhibit anyPolicy X.509 extension (2.5.29.54).
1183
 *
1184
 * The @skipcerts value is the number of additional certificates that
1185
 * may appear in the path before the anyPolicy (%GNUTLS_X509_OID_POLICY_ANY)
1186
 * is no longer acceptable.
1187
 *
1188
 * Returns: zero, or a negative error code in case of
1189
 *   parsing error.  If the certificate does not contain the Inhibit anyPolicy
1190
 *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1191
 *   returned.
1192
 *
1193
 * Since: 3.6.0
1194
 **/
1195
int gnutls_x509_ext_import_inhibit_anypolicy(const gnutls_datum_t *ext,
1196
               unsigned int *skipcerts)
1197
0
{
1198
0
  int ret;
1199
1200
0
  ret = _gnutls_x509_read_der_uint(ext->data, ext->size, skipcerts);
1201
0
  if (ret < 0) {
1202
0
    gnutls_assert();
1203
0
  }
1204
1205
0
  return ret;
1206
0
}
1207
1208
/**
1209
 * gnutls_x509_ext_export_inhibit_anypolicy:
1210
 * @skipcerts: number of certificates after which anypolicy is no longer acceptable.
1211
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1212
 *
1213
 * This function will convert the @skipcerts value to a DER
1214
 * encoded Inhibit AnyPolicy PKIX extension. The @ext data will be allocated using
1215
 * gnutls_malloc().
1216
 *
1217
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1218
 *   negative error value.
1219
 *
1220
 * Since: 3.6.0
1221
 **/
1222
int gnutls_x509_ext_export_inhibit_anypolicy(unsigned int skipcerts,
1223
               gnutls_datum_t *ext)
1224
0
{
1225
0
  asn1_node c2 = NULL;
1226
0
  int result, ret;
1227
1228
0
  result = asn1_create_element(_gnutls_get_gnutls_asn(),
1229
0
             "GNUTLS.DSAPublicKey", &c2);
1230
0
  if (result != ASN1_SUCCESS) {
1231
0
    gnutls_assert();
1232
0
    return _gnutls_asn2err(result);
1233
0
  }
1234
1235
0
  ret = _gnutls_x509_write_uint32(c2, "", skipcerts);
1236
0
  if (ret < 0) {
1237
0
    gnutls_assert();
1238
0
    goto cleanup;
1239
0
  }
1240
1241
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
1242
0
  if (ret < 0) {
1243
0
    gnutls_assert();
1244
0
    goto cleanup;
1245
0
  }
1246
1247
0
  ret = 0;
1248
1249
0
cleanup:
1250
0
  asn1_delete_structure(&c2);
1251
1252
0
  return ret;
1253
0
}
1254
1255
/**
1256
 * gnutls_x509_ext_import_private_key_usage_period:
1257
 * @ext: the DER encoded extension data
1258
 * @activation: Will hold the activation time
1259
 * @expiration: Will hold the expiration time
1260
 *
1261
 * This function will return the expiration and activation
1262
 * times of the private key as written in the
1263
 * PKIX extension 2.5.29.16.
1264
 *
1265
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1266
 *   negative error value.
1267
 *
1268
 * Since: 3.3.0
1269
 **/
1270
int gnutls_x509_ext_import_private_key_usage_period(const gnutls_datum_t *ext,
1271
                time_t *activation,
1272
                time_t *expiration)
1273
0
{
1274
0
  int result, ret;
1275
0
  asn1_node c2 = NULL;
1276
1277
0
  result = asn1_create_element(_gnutls_get_pkix(),
1278
0
             "PKIX1.PrivateKeyUsagePeriod", &c2);
1279
0
  if (result != ASN1_SUCCESS) {
1280
0
    gnutls_assert();
1281
0
    ret = _gnutls_asn2err(result);
1282
0
    goto cleanup;
1283
0
  }
1284
1285
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1286
0
  if (result != ASN1_SUCCESS) {
1287
0
    gnutls_assert();
1288
0
    ret = _gnutls_asn2err(result);
1289
0
    goto cleanup;
1290
0
  }
1291
1292
0
  if (activation)
1293
0
    *activation = _gnutls_x509_get_time(c2, "notBefore", 1);
1294
1295
0
  if (expiration)
1296
0
    *expiration = _gnutls_x509_get_time(c2, "notAfter", 1);
1297
1298
0
  ret = 0;
1299
1300
0
cleanup:
1301
0
  asn1_delete_structure(&c2);
1302
1303
0
  return ret;
1304
0
}
1305
1306
/**
1307
 * gnutls_x509_ext_export_private_key_usage_period:
1308
 * @activation: The activation time
1309
 * @expiration: The expiration time
1310
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1311
 *
1312
 * This function will convert the periods provided to a private key
1313
 * usage DER encoded extension (2.5.29.16).
1314
 (
1315
 * The @ext data will be allocated using
1316
 * gnutls_malloc().
1317
 *
1318
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1319
 *   negative error value.
1320
 *
1321
 * Since: 3.3.0
1322
 **/
1323
int gnutls_x509_ext_export_private_key_usage_period(time_t activation,
1324
                time_t expiration,
1325
                gnutls_datum_t *ext)
1326
0
{
1327
0
  int result;
1328
0
  asn1_node c2 = NULL;
1329
1330
0
  result = asn1_create_element(_gnutls_get_pkix(),
1331
0
             "PKIX1.PrivateKeyUsagePeriod", &c2);
1332
0
  if (result != ASN1_SUCCESS) {
1333
0
    gnutls_assert();
1334
0
    return _gnutls_asn2err(result);
1335
0
  }
1336
1337
0
  result = _gnutls_x509_set_time(c2, "notBefore", activation, 1);
1338
0
  if (result < 0) {
1339
0
    gnutls_assert();
1340
0
    goto cleanup;
1341
0
  }
1342
1343
0
  result = _gnutls_x509_set_time(c2, "notAfter", expiration, 1);
1344
0
  if (result < 0) {
1345
0
    gnutls_assert();
1346
0
    goto cleanup;
1347
0
  }
1348
1349
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
1350
0
  if (result < 0) {
1351
0
    gnutls_assert();
1352
0
    goto cleanup;
1353
0
  }
1354
1355
0
cleanup:
1356
0
  asn1_delete_structure(&c2);
1357
1358
0
  return result;
1359
0
}
1360
1361
/**
1362
 * gnutls_x509_ext_import_basic_constraints:
1363
 * @ext: the DER encoded extension data
1364
 * @ca: will be non zero if the CA status is true
1365
 * @pathlen: the path length constraint; will be set to -1 for no limit
1366
 *
1367
 * This function will return the CA status and path length constraint
1368
 * as written in the PKIX extension 2.5.29.19.
1369
 *
1370
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1371
 *   negative error value.
1372
 *
1373
 * Since: 3.3.0
1374
 **/
1375
int gnutls_x509_ext_import_basic_constraints(const gnutls_datum_t *ext,
1376
               unsigned int *ca, int *pathlen)
1377
0
{
1378
0
  asn1_node c2 = NULL;
1379
0
  char str[128] = "";
1380
0
  int len, result;
1381
1382
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
1383
0
            "PKIX1.BasicConstraints", &c2)) !=
1384
0
      ASN1_SUCCESS) {
1385
0
    gnutls_assert();
1386
0
    return _gnutls_asn2err(result);
1387
0
  }
1388
1389
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1390
0
  if (result != ASN1_SUCCESS) {
1391
0
    gnutls_assert();
1392
0
    result = _gnutls_asn2err(result);
1393
0
    goto cleanup;
1394
0
  }
1395
1396
0
  if (pathlen) {
1397
0
    result = _gnutls_x509_read_uint(c2, "pathLenConstraint",
1398
0
            (unsigned int *)pathlen);
1399
0
    if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1400
0
      *pathlen = -1;
1401
0
    else if (result != GNUTLS_E_SUCCESS) {
1402
0
      gnutls_assert();
1403
0
      result = _gnutls_asn2err(result);
1404
0
      goto cleanup;
1405
0
    }
1406
0
  }
1407
1408
  /* the default value of cA is false.
1409
   */
1410
0
  len = sizeof(str) - 1;
1411
0
  result = asn1_read_value(c2, "cA", str, &len);
1412
0
  if (result == ASN1_SUCCESS && strcmp(str, "TRUE") == 0)
1413
0
    *ca = 1;
1414
0
  else
1415
0
    *ca = 0;
1416
1417
0
  result = 0;
1418
0
cleanup:
1419
0
  asn1_delete_structure(&c2);
1420
1421
0
  return result;
1422
0
}
1423
1424
/**
1425
 * gnutls_x509_ext_export_basic_constraints:
1426
 * @ca: non-zero for a CA
1427
 * @pathlen: The path length constraint (set to -1 for no constraint)
1428
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1429
 *
1430
 * This function will convert the parameters provided to a basic constraints
1431
 * DER encoded extension (2.5.29.19).
1432
 (
1433
 * The @ext data will be allocated using
1434
 * gnutls_malloc().
1435
 *
1436
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1437
 *   negative error value.
1438
 *
1439
 * Since: 3.3.0
1440
 **/
1441
int gnutls_x509_ext_export_basic_constraints(unsigned int ca, int pathlen,
1442
               gnutls_datum_t *ext)
1443
0
{
1444
0
  asn1_node c2 = NULL;
1445
0
  const char *str;
1446
0
  int result;
1447
1448
0
  if (ca == 0)
1449
0
    str = "FALSE";
1450
0
  else
1451
0
    str = "TRUE";
1452
1453
0
  result = asn1_create_element(_gnutls_get_pkix(),
1454
0
             "PKIX1.BasicConstraints", &c2);
1455
0
  if (result != ASN1_SUCCESS) {
1456
0
    gnutls_assert();
1457
0
    result = _gnutls_asn2err(result);
1458
0
    goto cleanup;
1459
0
  }
1460
1461
0
  result = asn1_write_value(c2, "cA", str, 1);
1462
0
  if (result != ASN1_SUCCESS) {
1463
0
    gnutls_assert();
1464
0
    result = _gnutls_asn2err(result);
1465
0
    goto cleanup;
1466
0
  }
1467
1468
0
  if (pathlen < 0) {
1469
0
    result = asn1_write_value(c2, "pathLenConstraint", NULL, 0);
1470
0
    if (result != ASN1_SUCCESS)
1471
0
      result = _gnutls_asn2err(result);
1472
0
  } else
1473
0
    result = _gnutls_x509_write_uint32(c2, "pathLenConstraint",
1474
0
               pathlen);
1475
0
  if (result < 0) {
1476
0
    gnutls_assert();
1477
0
    goto cleanup;
1478
0
  }
1479
1480
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
1481
0
  if (result < 0) {
1482
0
    gnutls_assert();
1483
0
    goto cleanup;
1484
0
  }
1485
1486
0
  result = 0;
1487
1488
0
cleanup:
1489
0
  asn1_delete_structure(&c2);
1490
0
  return result;
1491
0
}
1492
1493
/**
1494
 * gnutls_x509_ext_import_proxy:
1495
 * @ext: the DER encoded extension data
1496
 * @pathlen: pointer to output integer indicating path length (may be
1497
 *   NULL), non-negative error codes indicate a present pCPathLenConstraint
1498
 *   field and the actual value, -1 indicate that the field is absent.
1499
 * @policyLanguage: output variable with OID of policy language
1500
 * @policy: output variable with policy data
1501
 * @sizeof_policy: output variable with size of policy data
1502
 *
1503
 * This function will return the information from a proxy certificate
1504
 * extension. It reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1505
 * The @policyLanguage and @policy values must be deinitialized using gnutls_free() after use.
1506
 *
1507
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1508
 *   negative error value.
1509
 *
1510
 * Since: 3.3.0
1511
 **/
1512
int gnutls_x509_ext_import_proxy(const gnutls_datum_t *ext, int *pathlen,
1513
         char **policyLanguage, char **policy,
1514
         size_t *sizeof_policy)
1515
0
{
1516
0
  asn1_node c2 = NULL;
1517
0
  int result;
1518
0
  gnutls_datum_t value1 = { NULL, 0 };
1519
0
  gnutls_datum_t value2 = { NULL, 0 };
1520
1521
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
1522
0
            "PKIX1.ProxyCertInfo", &c2)) !=
1523
0
      ASN1_SUCCESS) {
1524
0
    gnutls_assert();
1525
0
    return _gnutls_asn2err(result);
1526
0
  }
1527
1528
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1529
0
  if (result != ASN1_SUCCESS) {
1530
0
    gnutls_assert();
1531
0
    result = _gnutls_asn2err(result);
1532
0
    goto cleanup;
1533
0
  }
1534
1535
0
  if (pathlen) {
1536
0
    result = _gnutls_x509_read_uint(c2, "pCPathLenConstraint",
1537
0
            (unsigned int *)pathlen);
1538
0
    if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1539
0
      *pathlen = -1;
1540
0
    else if (result != GNUTLS_E_SUCCESS) {
1541
0
      gnutls_assert();
1542
0
      result = _gnutls_asn2err(result);
1543
0
      goto cleanup;
1544
0
    }
1545
0
  }
1546
1547
0
  result = _gnutls_x509_read_value(c2, "proxyPolicy.policyLanguage",
1548
0
           &value1);
1549
0
  if (result < 0) {
1550
0
    gnutls_assert();
1551
0
    goto cleanup;
1552
0
  }
1553
1554
0
  result = _gnutls_x509_read_value(c2, "proxyPolicy.policy", &value2);
1555
0
  if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
1556
0
    if (policy)
1557
0
      *policy = NULL;
1558
0
    if (sizeof_policy)
1559
0
      *sizeof_policy = 0;
1560
0
  } else if (result < 0) {
1561
0
    gnutls_assert();
1562
0
    goto cleanup;
1563
0
  } else {
1564
0
    if (policy) {
1565
0
      *policy = (char *)value2.data;
1566
0
      value2.data = NULL;
1567
0
    }
1568
0
    if (sizeof_policy)
1569
0
      *sizeof_policy = value2.size;
1570
0
  }
1571
1572
0
  if (policyLanguage) {
1573
0
    *policyLanguage = (char *)value1.data;
1574
0
    value1.data = NULL;
1575
0
  }
1576
1577
0
  result = 0;
1578
0
cleanup:
1579
0
  gnutls_free(value1.data);
1580
0
  gnutls_free(value2.data);
1581
0
  asn1_delete_structure(&c2);
1582
1583
0
  return result;
1584
0
}
1585
1586
/**
1587
 * gnutls_x509_ext_export_proxy:
1588
 * @pathLenConstraint: A negative value will remove the path length constraint,
1589
 *   while non-negative values will be set as the length of the pathLenConstraints field.
1590
 * @policyLanguage: OID describing the language of @policy.
1591
 * @policy: uint8_t byte array with policy language, can be %NULL
1592
 * @sizeof_policy: size of @policy.
1593
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1594
 *
1595
 * This function will convert the parameters provided to a proxyCertInfo extension.
1596
 *
1597
 * The @ext data will be allocated using gnutls_malloc().
1598
 *
1599
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1600
 *   negative error value.
1601
 *
1602
 * Since: 3.3.0
1603
 **/
1604
int gnutls_x509_ext_export_proxy(int pathLenConstraint,
1605
         const char *policyLanguage, const char *policy,
1606
         size_t sizeof_policy, gnutls_datum_t *ext)
1607
0
{
1608
0
  asn1_node c2 = NULL;
1609
0
  int result;
1610
1611
0
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.ProxyCertInfo",
1612
0
             &c2);
1613
0
  if (result != ASN1_SUCCESS) {
1614
0
    gnutls_assert();
1615
0
    return _gnutls_asn2err(result);
1616
0
  }
1617
1618
0
  if (pathLenConstraint < 0) {
1619
0
    result = asn1_write_value(c2, "pCPathLenConstraint", NULL, 0);
1620
0
    if (result != ASN1_SUCCESS) {
1621
0
      gnutls_assert();
1622
0
      result = _gnutls_asn2err(result);
1623
0
      goto cleanup;
1624
0
    }
1625
0
  } else {
1626
0
    result = _gnutls_x509_write_uint32(c2, "pCPathLenConstraint",
1627
0
               pathLenConstraint);
1628
1629
0
    if (result < 0) {
1630
0
      gnutls_assert();
1631
0
      goto cleanup;
1632
0
    }
1633
0
  }
1634
1635
0
  result = asn1_write_value(c2, "proxyPolicy.policyLanguage",
1636
0
          policyLanguage, 1);
1637
0
  if (result != ASN1_SUCCESS) {
1638
0
    gnutls_assert();
1639
0
    result = _gnutls_asn2err(result);
1640
0
    goto cleanup;
1641
0
  }
1642
1643
0
  result = asn1_write_value(c2, "proxyPolicy.policy", policy,
1644
0
          sizeof_policy);
1645
0
  if (result != ASN1_SUCCESS) {
1646
0
    gnutls_assert();
1647
0
    result = _gnutls_asn2err(result);
1648
0
    goto cleanup;
1649
0
  }
1650
1651
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
1652
0
  if (result < 0) {
1653
0
    gnutls_assert();
1654
0
    goto cleanup;
1655
0
  }
1656
1657
0
  result = 0;
1658
0
cleanup:
1659
0
  asn1_delete_structure(&c2);
1660
0
  return result;
1661
0
}
1662
1663
static int decode_user_notice(const void *data, size_t size,
1664
            gnutls_datum_t *txt)
1665
0
{
1666
0
  asn1_node c2 = NULL;
1667
0
  int ret, len;
1668
0
  char choice_type[64];
1669
0
  char name[128];
1670
0
  gnutls_datum_t td = { NULL, 0 }, utd;
1671
1672
0
  ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.UserNotice", &c2);
1673
0
  if (ret != ASN1_SUCCESS) {
1674
0
    gnutls_assert();
1675
0
    ret = GNUTLS_E_PARSING_ERROR;
1676
0
    goto cleanup;
1677
0
  }
1678
1679
0
  ret = _asn1_strict_der_decode(&c2, data, size, NULL);
1680
0
  if (ret != ASN1_SUCCESS) {
1681
0
    gnutls_assert();
1682
0
    ret = GNUTLS_E_PARSING_ERROR;
1683
0
    goto cleanup;
1684
0
  }
1685
1686
0
  len = sizeof(choice_type);
1687
0
  ret = asn1_read_value(c2, "explicitText", choice_type, &len);
1688
0
  if (ret != ASN1_SUCCESS) {
1689
0
    gnutls_assert();
1690
0
    ret = GNUTLS_E_PARSING_ERROR;
1691
0
    goto cleanup;
1692
0
  }
1693
1694
0
  if (strcmp(choice_type, "utf8String") != 0 &&
1695
0
      strcmp(choice_type, "ia5String") != 0 &&
1696
0
      strcmp(choice_type, "bmpString") != 0 &&
1697
0
      strcmp(choice_type, "visibleString") != 0) {
1698
0
    gnutls_assert();
1699
0
    ret = GNUTLS_E_PARSING_ERROR;
1700
0
    goto cleanup;
1701
0
  }
1702
1703
0
  snprintf(name, sizeof(name), "explicitText.%s", choice_type);
1704
1705
0
  ret = _gnutls_x509_read_value(c2, name, &td);
1706
0
  if (ret < 0) {
1707
0
    gnutls_assert();
1708
0
    goto cleanup;
1709
0
  }
1710
1711
0
  if (strcmp(choice_type, "bmpString") == 0) { /* convert to UTF-8 */
1712
0
    ret = _gnutls_ucs2_to_utf8(td.data, td.size, &utd, 1);
1713
0
    _gnutls_free_datum(&td);
1714
0
    if (ret < 0) {
1715
0
      gnutls_assert();
1716
0
      goto cleanup;
1717
0
    }
1718
1719
0
    td.data = utd.data;
1720
0
    td.size = utd.size;
1721
0
  } else {
1722
    /* _gnutls_x509_read_value allows that */
1723
0
    td.data[td.size] = 0;
1724
0
  }
1725
1726
0
  txt->data = (void *)td.data;
1727
0
  txt->size = td.size;
1728
0
  ret = 0;
1729
1730
0
cleanup:
1731
0
  asn1_delete_structure(&c2);
1732
0
  return ret;
1733
0
}
1734
1735
struct gnutls_x509_policies_st {
1736
  struct gnutls_x509_policy_st policy[MAX_ENTRIES];
1737
  unsigned int size;
1738
};
1739
1740
/**
1741
 * gnutls_x509_policies_init:
1742
 * @policies: The authority key ID
1743
 *
1744
 * This function will initialize an authority key ID type.
1745
 *
1746
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
1747
 *
1748
 * Since: 3.3.0
1749
 **/
1750
int gnutls_x509_policies_init(gnutls_x509_policies_t *policies)
1751
0
{
1752
0
  *policies = gnutls_calloc(1, sizeof(struct gnutls_x509_policies_st));
1753
0
  if (*policies == NULL)
1754
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1755
1756
0
  return 0;
1757
0
}
1758
1759
/**
1760
 * gnutls_x509_policies_deinit:
1761
 * @policies: The authority key identifier
1762
 *
1763
 * This function will deinitialize an authority key identifier type.
1764
 *
1765
 * Since: 3.3.0
1766
 **/
1767
void gnutls_x509_policies_deinit(gnutls_x509_policies_t policies)
1768
0
{
1769
0
  unsigned i;
1770
1771
0
  for (i = 0; i < policies->size; i++) {
1772
0
    gnutls_x509_policy_release(&policies->policy[i]);
1773
0
  }
1774
0
  gnutls_free(policies);
1775
0
}
1776
1777
/**
1778
 * gnutls_x509_policies_get:
1779
 * @policies: The policies
1780
 * @seq: The index of the name to get
1781
 * @policy: Will hold the policy
1782
 *
1783
 * This function will return a specific policy as stored in
1784
 * the @policies type. The returned values should be treated as constant
1785
 * and valid for the lifetime of @policies.
1786
 *
1787
 * The any policy OID is available as the %GNUTLS_X509_OID_POLICY_ANY macro.
1788
 *
1789
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1790
 * if the index is out of bounds, otherwise a negative error value.
1791
 *
1792
 * Since: 3.3.0
1793
 **/
1794
int gnutls_x509_policies_get(gnutls_x509_policies_t policies, unsigned int seq,
1795
           struct gnutls_x509_policy_st *policy)
1796
0
{
1797
0
  if (seq >= policies->size)
1798
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1799
1800
0
  if (policy) {
1801
0
    memcpy(policy, &policies->policy[seq],
1802
0
           sizeof(struct gnutls_x509_policy_st));
1803
0
  }
1804
1805
0
  return 0;
1806
0
}
1807
1808
void _gnutls_x509_policies_erase(gnutls_x509_policies_t policies,
1809
         unsigned int seq)
1810
0
{
1811
0
  if (seq >= policies->size)
1812
0
    return;
1813
1814
0
  memset(&policies->policy[seq], 0, sizeof(struct gnutls_x509_policy_st));
1815
0
}
1816
1817
/**
1818
 * gnutls_x509_policies_set:
1819
 * @policies: An initialized policies
1820
 * @seq: The index of the name to get
1821
 * @policy: Contains the policy to set
1822
 *
1823
 * This function will store the specified policy in
1824
 * the provided @policies.
1825
 *
1826
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
1827
 *
1828
 * Since: 3.3.0
1829
 **/
1830
int gnutls_x509_policies_set(gnutls_x509_policies_t policies,
1831
           const struct gnutls_x509_policy_st *policy)
1832
0
{
1833
0
  unsigned i;
1834
1835
0
  if (policies->size + 1 > MAX_ENTRIES)
1836
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1837
1838
0
  policies->policy[policies->size].oid = gnutls_strdup(policy->oid);
1839
0
  if (policies->policy[policies->size].oid == NULL)
1840
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1841
1842
0
  for (i = 0; i < policy->qualifiers; i++) {
1843
0
    policies->policy[policies->size].qualifier[i].type =
1844
0
      policy->qualifier[i].type;
1845
0
    policies->policy[policies->size].qualifier[i].size =
1846
0
      policy->qualifier[i].size;
1847
0
    policies->policy[policies->size].qualifier[i].data =
1848
0
      gnutls_malloc(policy->qualifier[i].size + 1);
1849
0
    if (policies->policy[policies->size].qualifier[i].data == NULL)
1850
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1851
0
    memcpy(policies->policy[policies->size].qualifier[i].data,
1852
0
           policy->qualifier[i].data, policy->qualifier[i].size);
1853
0
    policies->policy[policies->size]
1854
0
      .qualifier[i]
1855
0
      .data[policy->qualifier[i].size] = 0;
1856
0
  }
1857
1858
0
  policies->policy[policies->size].qualifiers = policy->qualifiers;
1859
0
  policies->size++;
1860
1861
0
  return 0;
1862
0
}
1863
1864
/**
1865
 * gnutls_x509_ext_import_policies:
1866
 * @ext: the DER encoded extension data
1867
 * @policies: A pointer to an initialized policies.
1868
 * @flags: should be zero
1869
 *
1870
 * This function will extract the certificate policy extension (2.5.29.32) 
1871
 * and store it the provided policies.
1872
 *
1873
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
1874
 *
1875
 * Since: 3.3.0
1876
 **/
1877
int gnutls_x509_ext_import_policies(const gnutls_datum_t *ext,
1878
            gnutls_x509_policies_t policies,
1879
            unsigned int flags)
1880
0
{
1881
0
  asn1_node c2 = NULL;
1882
0
  char tmpstr[128];
1883
0
  char tmpoid[MAX_OID_SIZE];
1884
0
  gnutls_datum_t tmpd = { NULL, 0 };
1885
0
  int ret, len;
1886
0
  unsigned i, j, current = 0;
1887
1888
0
  ret = asn1_create_element(_gnutls_get_pkix(),
1889
0
          "PKIX1.certificatePolicies", &c2);
1890
0
  if (ret != ASN1_SUCCESS) {
1891
0
    gnutls_assert();
1892
0
    ret = _gnutls_asn2err(ret);
1893
0
    goto cleanup;
1894
0
  }
1895
1896
0
  ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1897
0
  if (ret != ASN1_SUCCESS) {
1898
0
    gnutls_assert();
1899
0
    ret = _gnutls_asn2err(ret);
1900
0
    goto cleanup;
1901
0
  }
1902
1903
0
  for (j = 0;; j++) {
1904
0
    if (j >= MAX_ENTRIES)
1905
0
      break;
1906
1907
0
    memset(&policies->policy[j], 0,
1908
0
           sizeof(struct gnutls_x509_policy_st));
1909
1910
    /* create a string like "?1"
1911
     */
1912
0
    snprintf(tmpstr, sizeof(tmpstr), "?%u.policyIdentifier", j + 1);
1913
0
    current = j + 1;
1914
1915
0
    ret = _gnutls_x509_read_value(c2, tmpstr, &tmpd);
1916
0
    if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1917
0
      break;
1918
1919
0
    if (ret < 0) {
1920
0
      gnutls_assert();
1921
0
      goto full_cleanup;
1922
0
    }
1923
1924
0
    policies->policy[j].oid = (void *)tmpd.data;
1925
0
    tmpd.data = NULL;
1926
1927
0
    for (i = 0; i < GNUTLS_MAX_QUALIFIERS; i++) {
1928
0
      gnutls_datum_t td;
1929
1930
0
      snprintf(tmpstr, sizeof(tmpstr),
1931
0
         "?%u.policyQualifiers.?%u.policyQualifierId",
1932
0
         j + 1, i + 1);
1933
1934
0
      len = sizeof(tmpoid);
1935
0
      ret = asn1_read_value(c2, tmpstr, tmpoid, &len);
1936
1937
0
      if (ret == ASN1_ELEMENT_NOT_FOUND)
1938
0
        break; /* finished */
1939
1940
0
      if (ret != ASN1_SUCCESS) {
1941
0
        gnutls_assert();
1942
0
        ret = _gnutls_asn2err(ret);
1943
0
        goto full_cleanup;
1944
0
      }
1945
1946
0
      if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.1") == 0) {
1947
0
        snprintf(tmpstr, sizeof(tmpstr),
1948
0
           "?%u.policyQualifiers.?%u.qualifier",
1949
0
           j + 1, i + 1);
1950
1951
0
        ret = _gnutls_x509_read_string(
1952
0
          c2, tmpstr, &td, ASN1_ETYPE_IA5_STRING,
1953
0
          0);
1954
0
        if (ret < 0) {
1955
0
          gnutls_assert();
1956
0
          goto full_cleanup;
1957
0
        }
1958
1959
0
        policies->policy[j].qualifier[i].data =
1960
0
          (void *)td.data;
1961
0
        policies->policy[j].qualifier[i].size = td.size;
1962
0
        td.data = NULL;
1963
0
        policies->policy[j].qualifier[i].type =
1964
0
          GNUTLS_X509_QUALIFIER_URI;
1965
0
      } else if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.2") == 0) {
1966
0
        gnutls_datum_t txt = { NULL, 0 };
1967
1968
0
        snprintf(tmpstr, sizeof(tmpstr),
1969
0
           "?%u.policyQualifiers.?%u.qualifier",
1970
0
           j + 1, i + 1);
1971
1972
0
        ret = _gnutls_x509_read_value(c2, tmpstr, &td);
1973
0
        if (ret < 0) {
1974
0
          gnutls_assert();
1975
0
          goto full_cleanup;
1976
0
        }
1977
1978
0
        ret = decode_user_notice(td.data, td.size,
1979
0
               &txt);
1980
0
        gnutls_free(td.data);
1981
1982
0
        if (ret < 0) {
1983
0
          gnutls_assert();
1984
0
          goto full_cleanup;
1985
0
        }
1986
1987
0
        policies->policy[j].qualifier[i].data =
1988
0
          (void *)txt.data;
1989
0
        policies->policy[j].qualifier[i].size =
1990
0
          txt.size;
1991
0
        policies->policy[j].qualifier[i].type =
1992
0
          GNUTLS_X509_QUALIFIER_NOTICE;
1993
0
      } else
1994
0
        policies->policy[j].qualifier[i].type =
1995
0
          GNUTLS_X509_QUALIFIER_UNKNOWN;
1996
1997
0
      policies->policy[j].qualifiers++;
1998
0
    }
1999
0
  }
2000
2001
0
  policies->size = j;
2002
2003
0
  ret = 0;
2004
0
  goto cleanup;
2005
2006
0
full_cleanup:
2007
0
  for (j = 0; j < current; j++)
2008
0
    gnutls_x509_policy_release(&policies->policy[j]);
2009
2010
0
cleanup:
2011
0
  _gnutls_free_datum(&tmpd);
2012
0
  asn1_delete_structure(&c2);
2013
0
  return ret;
2014
0
}
2015
2016
static int encode_user_notice(const gnutls_datum_t *txt,
2017
            gnutls_datum_t *der_data)
2018
0
{
2019
0
  int result;
2020
0
  asn1_node c2 = NULL;
2021
2022
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
2023
0
            "PKIX1.UserNotice", &c2)) !=
2024
0
      ASN1_SUCCESS) {
2025
0
    gnutls_assert();
2026
0
    result = _gnutls_asn2err(result);
2027
0
    goto error;
2028
0
  }
2029
2030
  /* delete noticeRef */
2031
0
  result = asn1_write_value(c2, "noticeRef", NULL, 0);
2032
0
  if (result != ASN1_SUCCESS) {
2033
0
    gnutls_assert();
2034
0
    result = _gnutls_asn2err(result);
2035
0
    goto error;
2036
0
  }
2037
2038
0
  result = asn1_write_value(c2, "explicitText", "utf8String", 1);
2039
0
  if (result != ASN1_SUCCESS) {
2040
0
    gnutls_assert();
2041
0
    result = _gnutls_asn2err(result);
2042
0
    goto error;
2043
0
  }
2044
2045
0
  result = asn1_write_value(c2, "explicitText.utf8String", txt->data,
2046
0
          txt->size);
2047
0
  if (result != ASN1_SUCCESS) {
2048
0
    gnutls_assert();
2049
0
    result = _gnutls_asn2err(result);
2050
0
    goto error;
2051
0
  }
2052
2053
0
  result = _gnutls_x509_der_encode(c2, "", der_data, 0);
2054
0
  if (result < 0) {
2055
0
    gnutls_assert();
2056
0
    goto error;
2057
0
  }
2058
2059
0
  result = 0;
2060
2061
0
error:
2062
0
  asn1_delete_structure(&c2);
2063
0
  return result;
2064
0
}
2065
2066
/**
2067
 * gnutls_x509_ext_export_policies:
2068
 * @policies: A pointer to an initialized policies.
2069
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
2070
 *
2071
 * This function will convert the provided policies, to a certificate policy
2072
 * DER encoded extension (2.5.29.32).
2073
 *
2074
 * The @ext data will be allocated using gnutls_malloc().
2075
 *
2076
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2077
 *
2078
 * Since: 3.3.0
2079
 **/
2080
int gnutls_x509_ext_export_policies(gnutls_x509_policies_t policies,
2081
            gnutls_datum_t *ext)
2082
0
{
2083
0
  int result;
2084
0
  unsigned i, j;
2085
0
  gnutls_datum_t der_data = { NULL, 0 }, tmpd;
2086
0
  asn1_node c2 = NULL;
2087
0
  const char *oid;
2088
2089
0
  result = asn1_create_element(_gnutls_get_pkix(),
2090
0
             "PKIX1.certificatePolicies", &c2);
2091
0
  if (result != ASN1_SUCCESS) {
2092
0
    gnutls_assert();
2093
0
    result = _gnutls_asn2err(result);
2094
0
    goto cleanup;
2095
0
  }
2096
2097
0
  for (j = 0; j < policies->size; j++) {
2098
    /* 1. write a new policy */
2099
0
    result = asn1_write_value(c2, "", "NEW", 1);
2100
0
    if (result != ASN1_SUCCESS) {
2101
0
      gnutls_assert();
2102
0
      result = _gnutls_asn2err(result);
2103
0
      goto cleanup;
2104
0
    }
2105
2106
    /* 2. Add the OID.
2107
     */
2108
0
    result = asn1_write_value(c2, "?LAST.policyIdentifier",
2109
0
            policies->policy[j].oid, 1);
2110
0
    if (result != ASN1_SUCCESS) {
2111
0
      gnutls_assert();
2112
0
      result = _gnutls_asn2err(result);
2113
0
      goto cleanup;
2114
0
    }
2115
2116
0
    if (policies->policy[j].qualifiers == 0) {
2117
      /* remove the optional policyQualifiers if none are present. */
2118
0
      result = asn1_write_value(c2, "?LAST.policyQualifiers",
2119
0
              NULL, 0);
2120
0
      if (result != ASN1_SUCCESS) {
2121
0
        gnutls_assert();
2122
0
        result = _gnutls_asn2err(result);
2123
0
        goto cleanup;
2124
0
      }
2125
0
    }
2126
2127
0
    for (i = 0; i < MIN(policies->policy[j].qualifiers,
2128
0
            GNUTLS_MAX_QUALIFIERS);
2129
0
         i++) {
2130
0
      result = asn1_write_value(c2, "?LAST.policyQualifiers",
2131
0
              "NEW", 1);
2132
0
      if (result != ASN1_SUCCESS) {
2133
0
        gnutls_assert();
2134
0
        result = _gnutls_asn2err(result);
2135
0
        goto cleanup;
2136
0
      }
2137
2138
0
      if (policies->policy[j].qualifier[i].type ==
2139
0
          GNUTLS_X509_QUALIFIER_URI)
2140
0
        oid = "1.3.6.1.5.5.7.2.1";
2141
0
      else if (policies->policy[j].qualifier[i].type ==
2142
0
         GNUTLS_X509_QUALIFIER_NOTICE)
2143
0
        oid = "1.3.6.1.5.5.7.2.2";
2144
0
      else {
2145
0
        result = gnutls_assert_val(
2146
0
          GNUTLS_E_INVALID_REQUEST);
2147
0
        goto cleanup;
2148
0
      }
2149
2150
0
      result = asn1_write_value(
2151
0
        c2,
2152
0
        "?LAST.policyQualifiers.?LAST.policyQualifierId",
2153
0
        oid, 1);
2154
0
      if (result != ASN1_SUCCESS) {
2155
0
        gnutls_assert();
2156
0
        result = _gnutls_asn2err(result);
2157
0
        goto cleanup;
2158
0
      }
2159
2160
0
      if (policies->policy[j].qualifier[i].type ==
2161
0
          GNUTLS_X509_QUALIFIER_URI) {
2162
0
        tmpd.data = (void *)policies->policy[j]
2163
0
                .qualifier[i]
2164
0
                .data;
2165
0
        tmpd.size =
2166
0
          policies->policy[j].qualifier[i].size;
2167
0
        result = _gnutls_x509_write_string(
2168
0
          c2,
2169
0
          "?LAST.policyQualifiers.?LAST.qualifier",
2170
0
          &tmpd, ASN1_ETYPE_IA5_STRING);
2171
0
        if (result < 0) {
2172
0
          gnutls_assert();
2173
0
          goto cleanup;
2174
0
        }
2175
0
      } else if (policies->policy[j].qualifier[i].type ==
2176
0
           GNUTLS_X509_QUALIFIER_NOTICE) {
2177
0
        tmpd.data = (void *)policies->policy[j]
2178
0
                .qualifier[i]
2179
0
                .data;
2180
0
        tmpd.size =
2181
0
          policies->policy[j].qualifier[i].size;
2182
2183
0
        if (tmpd.size > 200) {
2184
0
          gnutls_assert();
2185
0
          result = GNUTLS_E_INVALID_REQUEST;
2186
0
          goto cleanup;
2187
0
        }
2188
2189
0
        result = encode_user_notice(&tmpd, &der_data);
2190
0
        if (result < 0) {
2191
0
          gnutls_assert();
2192
0
          goto cleanup;
2193
0
        }
2194
2195
0
        result = _gnutls_x509_write_value(
2196
0
          c2,
2197
0
          "?LAST.policyQualifiers.?LAST.qualifier",
2198
0
          &der_data);
2199
0
        _gnutls_free_datum(&der_data);
2200
0
        if (result < 0) {
2201
0
          gnutls_assert();
2202
0
          goto cleanup;
2203
0
        }
2204
0
      }
2205
0
    }
2206
0
  }
2207
2208
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
2209
0
  if (result < 0) {
2210
0
    gnutls_assert();
2211
0
    goto cleanup;
2212
0
  }
2213
2214
0
cleanup:
2215
0
  asn1_delete_structure(&c2);
2216
2217
0
  return result;
2218
0
}
2219
2220
struct crl_dist_point_st {
2221
  unsigned int type;
2222
  gnutls_datum_t san;
2223
  unsigned int reasons;
2224
};
2225
2226
struct gnutls_x509_crl_dist_points_st {
2227
  struct crl_dist_point_st *points;
2228
  unsigned int size;
2229
};
2230
2231
/**
2232
 * gnutls_x509_crl_dist_points_init:
2233
 * @cdp: The CRL distribution points
2234
 *
2235
 * This function will initialize a CRL distribution points type.
2236
 *
2237
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2238
 *
2239
 * Since: 3.3.0
2240
 **/
2241
int gnutls_x509_crl_dist_points_init(gnutls_x509_crl_dist_points_t *cdp)
2242
0
{
2243
0
  *cdp = gnutls_calloc(1, sizeof(struct gnutls_x509_crl_dist_points_st));
2244
0
  if (*cdp == NULL)
2245
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2246
2247
0
  return 0;
2248
0
}
2249
2250
/**
2251
 * gnutls_x509_crl_dist_points_deinit:
2252
 * @cdp: The CRL distribution points
2253
 *
2254
 * This function will deinitialize a CRL distribution points type.
2255
 *
2256
 * Since: 3.3.0
2257
 **/
2258
void gnutls_x509_crl_dist_points_deinit(gnutls_x509_crl_dist_points_t cdp)
2259
0
{
2260
0
  unsigned i;
2261
2262
0
  for (i = 0; i < cdp->size; i++) {
2263
0
    gnutls_free(cdp->points[i].san.data);
2264
0
  }
2265
0
  gnutls_free(cdp->points);
2266
0
  gnutls_free(cdp);
2267
0
}
2268
2269
/**
2270
 * gnutls_x509_crl_dist_points_get:
2271
 * @cdp: The CRL distribution points
2272
 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2273
 * @type: The name type of the corresponding name (gnutls_x509_subject_alt_name_t)
2274
 * @san: The distribution point names (to be treated as constant)
2275
 * @reasons: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
2276
 *
2277
 * This function retrieves the individual CRL distribution points (2.5.29.31),
2278
 * contained in provided type. 
2279
 *
2280
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2281
 * if the index is out of bounds, otherwise a negative error value.
2282
 **/
2283
2284
int gnutls_x509_crl_dist_points_get(gnutls_x509_crl_dist_points_t cdp,
2285
            unsigned int seq, unsigned int *type,
2286
            gnutls_datum_t *san, unsigned int *reasons)
2287
0
{
2288
0
  if (seq >= cdp->size)
2289
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2290
2291
0
  if (reasons)
2292
0
    *reasons = cdp->points[seq].reasons;
2293
2294
0
  if (type)
2295
0
    *type = cdp->points[seq].type;
2296
2297
0
  if (san) {
2298
0
    san->data = cdp->points[seq].san.data;
2299
0
    san->size = cdp->points[seq].san.size;
2300
0
  }
2301
2302
0
  return 0;
2303
0
}
2304
2305
static int crl_dist_points_set(gnutls_x509_crl_dist_points_t cdp,
2306
             gnutls_x509_subject_alt_name_t type,
2307
             const gnutls_datum_t *san, unsigned int reasons)
2308
0
{
2309
0
  void *tmp;
2310
2311
0
  if (unlikely(INT_ADD_OVERFLOW(cdp->size, 1))) {
2312
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2313
0
  }
2314
2315
  /* new dist point */
2316
0
  tmp = _gnutls_reallocarray(cdp->points, cdp->size + 1,
2317
0
           sizeof(cdp->points[0]));
2318
0
  if (tmp == NULL) {
2319
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2320
0
  }
2321
0
  cdp->points = tmp;
2322
2323
0
  cdp->points[cdp->size].type = type;
2324
0
  cdp->points[cdp->size].san.data = san->data;
2325
0
  cdp->points[cdp->size].san.size = san->size;
2326
0
  cdp->points[cdp->size].reasons = reasons;
2327
2328
0
  cdp->size++;
2329
0
  return 0;
2330
0
}
2331
2332
/**
2333
 * gnutls_x509_crl_dist_points_set:
2334
 * @cdp: The CRL distribution points
2335
 * @type: The type of the name (of %gnutls_subject_alt_names_t)
2336
 * @san: The point name data
2337
 * @reasons: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
2338
 *
2339
 * This function will store the specified CRL distribution point value
2340
 * the @cdp type.
2341
 *
2342
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
2343
 *
2344
 * Since: 3.3.0
2345
 **/
2346
int gnutls_x509_crl_dist_points_set(gnutls_x509_crl_dist_points_t cdp,
2347
            gnutls_x509_subject_alt_name_t type,
2348
            const gnutls_datum_t *san,
2349
            unsigned int reasons)
2350
0
{
2351
0
  int ret;
2352
0
  gnutls_datum_t t_san;
2353
2354
0
  ret = _gnutls_set_datum(&t_san, san->data, san->size);
2355
0
  if (ret < 0)
2356
0
    return gnutls_assert_val(ret);
2357
2358
0
  ret = crl_dist_points_set(cdp, type, &t_san, reasons);
2359
0
  if (ret < 0) {
2360
0
    gnutls_free(t_san.data);
2361
0
    return gnutls_assert_val(ret);
2362
0
  }
2363
2364
0
  return 0;
2365
0
}
2366
2367
/**
2368
 * gnutls_x509_ext_import_crl_dist_points:
2369
 * @ext: the DER encoded extension data
2370
 * @cdp: A pointer to an initialized CRL distribution points.
2371
 * @flags: should be zero
2372
 *
2373
 * This function will extract the CRL distribution points extension (2.5.29.31) 
2374
 * and store it into the provided type.
2375
 *
2376
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2377
 *
2378
 * Since: 3.3.0
2379
 **/
2380
int gnutls_x509_ext_import_crl_dist_points(const gnutls_datum_t *ext,
2381
             gnutls_x509_crl_dist_points_t cdp,
2382
             unsigned int flags)
2383
0
{
2384
0
  int result;
2385
0
  asn1_node c2 = NULL;
2386
0
  char name[MAX_NAME_SIZE];
2387
0
  int len, ret;
2388
0
  uint8_t reasons[2];
2389
0
  unsigned i, type, rflags, j;
2390
0
  gnutls_datum_t san = { NULL, 0 };
2391
2392
0
  result = asn1_create_element(_gnutls_get_pkix(),
2393
0
             "PKIX1.CRLDistributionPoints", &c2);
2394
0
  if (result != ASN1_SUCCESS) {
2395
0
    gnutls_assert();
2396
0
    return _gnutls_asn2err(result);
2397
0
  }
2398
2399
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
2400
2401
0
  if (result != ASN1_SUCCESS) {
2402
0
    gnutls_assert();
2403
0
    ret = _gnutls_asn2err(result);
2404
0
    goto cleanup;
2405
0
  }
2406
2407
  /* Return the different names from the first CRLDistr. point.
2408
   * The whole thing is a mess.
2409
   */
2410
2411
0
  i = 0;
2412
0
  do {
2413
0
    snprintf(name, sizeof(name), "?%u.reasons", (unsigned)i + 1);
2414
2415
0
    len = sizeof(reasons);
2416
0
    result = asn1_read_value(c2, name, reasons, &len);
2417
2418
0
    if (result != ASN1_VALUE_NOT_FOUND &&
2419
0
        result != ASN1_ELEMENT_NOT_FOUND &&
2420
0
        result != ASN1_SUCCESS) {
2421
0
      gnutls_assert();
2422
0
      ret = _gnutls_asn2err(result);
2423
0
      break;
2424
0
    }
2425
2426
0
    if (result == ASN1_VALUE_NOT_FOUND ||
2427
0
        result == ASN1_ELEMENT_NOT_FOUND)
2428
0
      rflags = 0;
2429
0
    else
2430
0
      rflags = reasons[0] | (reasons[1] << 8);
2431
2432
0
    snprintf(name, sizeof(name), "?%u.distributionPoint.fullName",
2433
0
       (unsigned)i + 1);
2434
2435
0
    for (j = 0;; j++) {
2436
0
      san.data = NULL;
2437
0
      san.size = 0;
2438
2439
0
      ret = _gnutls_parse_general_name2(c2, name, j, &san,
2440
0
                &type, 0);
2441
0
      if (j > 0 &&
2442
0
          ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2443
0
        ret = 0;
2444
0
        break;
2445
0
      }
2446
0
      if (ret < 0)
2447
0
        break;
2448
2449
0
      ret = crl_dist_points_set(cdp, type, &san, rflags);
2450
0
      if (ret < 0)
2451
0
        break;
2452
0
      san.data = NULL; /* it is now in cdp */
2453
0
    }
2454
2455
0
    i++;
2456
0
  } while (ret >= 0);
2457
2458
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2459
0
    gnutls_assert();
2460
0
    gnutls_free(san.data);
2461
0
    goto cleanup;
2462
0
  }
2463
2464
0
  ret = 0;
2465
0
cleanup:
2466
0
  asn1_delete_structure(&c2);
2467
0
  return ret;
2468
0
}
2469
2470
/**
2471
 * gnutls_x509_ext_export_crl_dist_points:
2472
 * @cdp: A pointer to an initialized CRL distribution points.
2473
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
2474
 *
2475
 * This function will convert the provided policies, to a certificate policy
2476
 * DER encoded extension (2.5.29.31).
2477
 *
2478
 * The @ext data will be allocated using gnutls_malloc().
2479
 *
2480
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2481
 *
2482
 * Since: 3.3.0
2483
 **/
2484
int gnutls_x509_ext_export_crl_dist_points(gnutls_x509_crl_dist_points_t cdp,
2485
             gnutls_datum_t *ext)
2486
0
{
2487
0
  asn1_node c2 = NULL;
2488
0
  int result;
2489
0
  uint8_t reasons[2];
2490
0
  unsigned i;
2491
2492
0
  result = asn1_create_element(_gnutls_get_pkix(),
2493
0
             "PKIX1.CRLDistributionPoints", &c2);
2494
0
  if (result != ASN1_SUCCESS) {
2495
0
    gnutls_assert();
2496
0
    result = _gnutls_asn2err(result);
2497
0
    goto cleanup;
2498
0
  }
2499
2500
0
  for (i = 0; i < cdp->size; i++) {
2501
0
    if (i == 0 ||
2502
0
        cdp->points[i].reasons != cdp->points[i - 1].reasons) {
2503
0
      result = asn1_write_value(c2, "", "NEW", 1);
2504
0
      if (result != ASN1_SUCCESS) {
2505
0
        gnutls_assert();
2506
0
        result = _gnutls_asn2err(result);
2507
0
        goto cleanup;
2508
0
      }
2509
2510
0
      if (cdp->points[i].reasons) {
2511
0
        reasons[0] = cdp->points[i].reasons & 0xff;
2512
0
        reasons[1] = cdp->points[i].reasons >> 8;
2513
2514
0
        result = asn1_write_value(c2, "?LAST.reasons",
2515
0
                reasons, 2);
2516
0
      } else {
2517
0
        result = asn1_write_value(c2, "?LAST.reasons",
2518
0
                NULL, 0);
2519
0
      }
2520
2521
0
      if (result != ASN1_SUCCESS) {
2522
0
        gnutls_assert();
2523
0
        result = _gnutls_asn2err(result);
2524
0
        goto cleanup;
2525
0
      }
2526
2527
0
      result = asn1_write_value(c2, "?LAST.cRLIssuer", NULL,
2528
0
              0);
2529
0
      if (result != ASN1_SUCCESS) {
2530
0
        gnutls_assert();
2531
0
        result = _gnutls_asn2err(result);
2532
0
        goto cleanup;
2533
0
      }
2534
      /* When used as type CHOICE.
2535
       */
2536
0
      result = asn1_write_value(c2, "?LAST.distributionPoint",
2537
0
              "fullName", 1);
2538
0
      if (result != ASN1_SUCCESS) {
2539
0
        gnutls_assert();
2540
0
        result = _gnutls_asn2err(result);
2541
0
        goto cleanup;
2542
0
      }
2543
0
    }
2544
2545
0
    result = _gnutls_write_new_general_name(
2546
0
      c2, "?LAST.distributionPoint.fullName",
2547
0
      cdp->points[i].type, cdp->points[i].san.data,
2548
0
      cdp->points[i].san.size);
2549
0
    if (result < 0) {
2550
0
      gnutls_assert();
2551
0
      goto cleanup;
2552
0
    }
2553
0
  }
2554
2555
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
2556
0
  if (result < 0) {
2557
0
    gnutls_assert();
2558
0
    goto cleanup;
2559
0
  }
2560
2561
0
  result = 0;
2562
2563
0
cleanup:
2564
0
  asn1_delete_structure(&c2);
2565
2566
0
  return result;
2567
0
}
2568
2569
struct gnutls_x509_aia_st {
2570
  struct {
2571
    gnutls_datum_t oid;
2572
    unsigned int san_type;
2573
    gnutls_datum_t san;
2574
  } *aia;
2575
  unsigned int size;
2576
};
2577
2578
/**
2579
 * gnutls_x509_aia_init:
2580
 * @aia: The authority info access
2581
 *
2582
 * This function will initialize an authority info access type.
2583
 *
2584
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2585
 *
2586
 * Since: 3.3.0
2587
 **/
2588
int gnutls_x509_aia_init(gnutls_x509_aia_t *aia)
2589
0
{
2590
0
  *aia = gnutls_calloc(1, sizeof(struct gnutls_x509_aia_st));
2591
0
  if (*aia == NULL)
2592
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2593
2594
0
  return 0;
2595
0
}
2596
2597
/**
2598
 * gnutls_x509_aia_deinit:
2599
 * @aia: The authority info access
2600
 *
2601
 * This function will deinitialize an authority info access type.
2602
 *
2603
 * Since: 3.3.0
2604
 **/
2605
void gnutls_x509_aia_deinit(gnutls_x509_aia_t aia)
2606
0
{
2607
0
  unsigned i;
2608
2609
0
  for (i = 0; i < aia->size; i++) {
2610
0
    gnutls_free(aia->aia[i].san.data);
2611
0
    gnutls_free(aia->aia[i].oid.data);
2612
0
  }
2613
0
  gnutls_free(aia->aia);
2614
0
  gnutls_free(aia);
2615
0
}
2616
2617
/**
2618
 * gnutls_x509_aia_get:
2619
 * @aia: The authority info access
2620
 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
2621
 * @oid: the type of available data; to be treated as constant.
2622
 * @san_type: Will hold the type of the name of %gnutls_subject_alt_names_t (may be null).
2623
 * @san: the access location name; to be treated as constant (may be null).
2624
 *
2625
 * This function reads from the Authority Information Access type.
2626
 *
2627
 * The @seq input parameter is used to indicate which member of the
2628
 * sequence the caller is interested in.  The first member is 0, the
2629
 * second member 1 and so on.  When the @seq value is out of bounds,
2630
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2631
 *
2632
 * Typically @oid is %GNUTLS_OID_AD_CAISSUERS or %GNUTLS_OID_AD_OCSP.
2633
 *
2634
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2635
 *
2636
 * Since: 3.3.0
2637
 **/
2638
int gnutls_x509_aia_get(gnutls_x509_aia_t aia, unsigned int seq,
2639
      gnutls_datum_t *oid, unsigned *san_type,
2640
      gnutls_datum_t *san)
2641
0
{
2642
0
  if (seq >= aia->size)
2643
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2644
2645
0
  if (san_type)
2646
0
    *san_type = aia->aia[seq].san_type;
2647
0
  if (san) {
2648
0
    san->data = aia->aia[seq].san.data;
2649
0
    san->size = aia->aia[seq].san.size;
2650
0
  }
2651
2652
0
  if (oid) {
2653
0
    oid->data = aia->aia[seq].oid.data;
2654
0
    oid->size = aia->aia[seq].oid.size;
2655
0
  }
2656
2657
0
  return 0;
2658
0
}
2659
2660
int _gnutls_alt_name_process(gnutls_datum_t *out, unsigned type,
2661
           const gnutls_datum_t *san, unsigned raw)
2662
0
{
2663
0
  int ret;
2664
0
  if (type == GNUTLS_SAN_DNSNAME && !raw) {
2665
0
    ret = gnutls_idna_map((char *)san->data, san->size, out, 0);
2666
0
    if (ret < 0) {
2667
0
      return gnutls_assert_val(ret);
2668
0
    }
2669
0
  } else if (type == GNUTLS_SAN_RFC822NAME && !raw) {
2670
0
    ret = _gnutls_idna_email_map((char *)san->data, san->size, out);
2671
0
    if (ret < 0) {
2672
0
      return gnutls_assert_val(ret);
2673
0
    }
2674
0
  } else if (type == GNUTLS_SAN_URI && !raw) {
2675
0
    if (!_gnutls_str_is_print((char *)san->data, san->size)) {
2676
0
      _gnutls_debug_log("non-ASCII URIs are not supported\n");
2677
0
      return gnutls_assert_val(
2678
0
        GNUTLS_E_UNIMPLEMENTED_FEATURE);
2679
0
    } else {
2680
0
      ret = _gnutls_set_strdatum(out, san->data, san->size);
2681
0
      if (ret < 0)
2682
0
        return gnutls_assert_val(ret);
2683
0
    }
2684
0
  } else {
2685
0
    ret = _gnutls_set_strdatum(out, san->data, san->size);
2686
0
    if (ret < 0)
2687
0
      return gnutls_assert_val(ret);
2688
0
  }
2689
2690
0
  return 0;
2691
0
}
2692
2693
/**
2694
 * gnutls_x509_aia_set:
2695
 * @aia: The authority info access
2696
 * @oid: the type of data.
2697
 * @san_type: The type of the name (of %gnutls_subject_alt_names_t)
2698
 * @san: The alternative name data
2699
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
2700
 *
2701
 * This function will store the specified alternative name in
2702
 * the @aia type. 
2703
 *
2704
 * Typically the value for @oid should be %GNUTLS_OID_AD_OCSP, or
2705
 * %GNUTLS_OID_AD_CAISSUERS.
2706
 *
2707
 * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, and %GNUTLS_SAN_DNSNAME,
2708
 * are converted to ACE format when necessary.
2709
 *
2710
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
2711
 *
2712
 * Since: 3.3.0
2713
 **/
2714
int gnutls_x509_aia_set(gnutls_x509_aia_t aia, const char *oid,
2715
      unsigned san_type, const gnutls_datum_t *san)
2716
0
{
2717
0
  int ret;
2718
0
  void *tmp;
2719
0
  unsigned indx;
2720
2721
0
  if (unlikely(INT_ADD_OVERFLOW(aia->size, 1))) {
2722
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2723
0
  }
2724
2725
0
  tmp = _gnutls_reallocarray(aia->aia, aia->size + 1,
2726
0
           sizeof(aia->aia[0]));
2727
0
  if (tmp == NULL) {
2728
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2729
0
  }
2730
0
  aia->aia = tmp;
2731
0
  indx = aia->size;
2732
2733
0
  aia->aia[indx].san_type = san_type;
2734
0
  if (oid) {
2735
0
    aia->aia[indx].oid.data = (void *)gnutls_strdup(oid);
2736
0
    aia->aia[indx].oid.size = strlen(oid);
2737
0
  } else {
2738
0
    aia->aia[indx].oid.data = NULL;
2739
0
    aia->aia[indx].oid.size = 0;
2740
0
  }
2741
2742
0
  ret = _gnutls_alt_name_process(&aia->aia[indx].san, san_type, san, 0);
2743
0
  if (ret < 0)
2744
0
    return gnutls_assert_val(ret);
2745
2746
0
  aia->size++;
2747
2748
0
  return 0;
2749
0
}
2750
2751
static int parse_aia(asn1_node c2, gnutls_x509_aia_t aia)
2752
0
{
2753
0
  int len;
2754
0
  char nptr[MAX_NAME_SIZE];
2755
0
  int ret, result;
2756
0
  char tmpoid[MAX_OID_SIZE];
2757
0
  void *tmp;
2758
0
  unsigned i, indx;
2759
2760
0
  for (i = 1;; i++) {
2761
0
    snprintf(nptr, sizeof(nptr), "?%u.accessMethod", i);
2762
2763
0
    len = sizeof(tmpoid);
2764
0
    result = asn1_read_value(c2, nptr, tmpoid, &len);
2765
0
    if (result == ASN1_VALUE_NOT_FOUND ||
2766
0
        result == ASN1_ELEMENT_NOT_FOUND) {
2767
0
      ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2768
0
      break;
2769
0
    }
2770
2771
0
    if (result != ASN1_SUCCESS) {
2772
0
      gnutls_assert();
2773
0
      return _gnutls_asn2err(result);
2774
0
    }
2775
2776
0
    indx = aia->size;
2777
0
    if (unlikely(INT_ADD_OVERFLOW(aia->size, 1))) {
2778
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2779
0
    }
2780
0
    tmp = _gnutls_reallocarray(aia->aia, aia->size + 1,
2781
0
             sizeof(aia->aia[0]));
2782
0
    if (tmp == NULL) {
2783
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2784
0
    }
2785
0
    aia->aia = tmp;
2786
2787
0
    snprintf(nptr, sizeof(nptr), "?%u.accessLocation", i);
2788
2789
0
    ret = _gnutls_parse_general_name2(c2, nptr, -1,
2790
0
              &aia->aia[indx].san,
2791
0
              &aia->aia[indx].san_type, 0);
2792
0
    if (ret < 0)
2793
0
      break;
2794
2795
    /* we do the strdup after parsing to avoid a memory leak */
2796
0
    aia->aia[indx].oid.data = (void *)gnutls_strdup(tmpoid);
2797
0
    aia->aia[indx].oid.size = strlen(tmpoid);
2798
2799
0
    aia->size++;
2800
2801
0
    if (aia->aia[indx].oid.data == NULL) {
2802
0
      gnutls_assert();
2803
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2804
0
    }
2805
0
  }
2806
2807
0
  assert(ret < 0);
2808
0
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2809
0
    return ret;
2810
0
  }
2811
2812
0
  return 0;
2813
0
}
2814
2815
/**
2816
 * gnutls_x509_ext_import_aia:
2817
 * @ext: The DER-encoded extension data
2818
 * @aia: The authority info access
2819
 * @flags: should be zero
2820
 *
2821
 * This function extracts the Authority Information Access (AIA)
2822
 * extension from the provided DER-encoded data; see RFC 5280 section 4.2.2.1 
2823
 * for more information on the extension.  The
2824
 * AIA extension holds a sequence of AccessDescription (AD) data.
2825
 *
2826
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2827
 *
2828
 * Since: 3.3.0
2829
 **/
2830
int gnutls_x509_ext_import_aia(const gnutls_datum_t *ext, gnutls_x509_aia_t aia,
2831
             unsigned int flags)
2832
0
{
2833
0
  int ret;
2834
0
  asn1_node c2 = NULL;
2835
2836
0
  if (ext->size == 0 || ext->data == NULL) {
2837
0
    gnutls_assert();
2838
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2839
0
  }
2840
2841
0
  ret = asn1_create_element(_gnutls_get_pkix(),
2842
0
          "PKIX1.AuthorityInfoAccessSyntax", &c2);
2843
0
  if (ret != ASN1_SUCCESS) {
2844
0
    gnutls_assert();
2845
0
    return _gnutls_asn2err(ret);
2846
0
  }
2847
2848
0
  ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
2849
0
  if (ret != ASN1_SUCCESS) {
2850
0
    gnutls_assert();
2851
0
    ret = _gnutls_asn2err(ret);
2852
0
    goto cleanup;
2853
0
  }
2854
2855
0
  ret = parse_aia(c2, aia);
2856
0
  if (ret < 0) {
2857
0
    gnutls_assert();
2858
0
  }
2859
2860
0
cleanup:
2861
0
  asn1_delete_structure(&c2);
2862
2863
0
  return ret;
2864
0
}
2865
2866
/**
2867
 * gnutls_x509_ext_export_aia:
2868
 * @aia: The authority info access
2869
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
2870
 *
2871
 * This function will DER encode the Authority Information Access (AIA)
2872
 * extension; see RFC 5280 section 4.2.2.1 for more information on the
2873
 * extension.  
2874
 *
2875
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2876
 *   negative error value.
2877
 *
2878
 * Since: 3.3.0
2879
 **/
2880
int gnutls_x509_ext_export_aia(gnutls_x509_aia_t aia, gnutls_datum_t *ext)
2881
0
{
2882
0
  int ret, result;
2883
0
  asn1_node c2 = NULL;
2884
0
  unsigned int i;
2885
2886
0
  ret = asn1_create_element(_gnutls_get_pkix(),
2887
0
          "PKIX1.AuthorityInfoAccessSyntax", &c2);
2888
0
  if (ret != ASN1_SUCCESS) {
2889
0
    gnutls_assert();
2890
0
    return _gnutls_asn2err(ret);
2891
0
  }
2892
2893
  /* 1. create a new element.
2894
   */
2895
0
  for (i = 0; i < aia->size; i++) {
2896
0
    result = asn1_write_value(c2, "", "NEW", 1);
2897
0
    if (result != ASN1_SUCCESS) {
2898
0
      gnutls_assert();
2899
0
      ret = _gnutls_asn2err(result);
2900
0
      goto cleanup;
2901
0
    }
2902
2903
    /* 2. Add the OID.
2904
     */
2905
0
    result = asn1_write_value(c2, "?LAST.accessMethod",
2906
0
            aia->aia[i].oid.data, 1);
2907
0
    if (result != ASN1_SUCCESS) {
2908
0
      gnutls_assert();
2909
0
      ret = _gnutls_asn2err(result);
2910
0
      goto cleanup;
2911
0
    }
2912
2913
0
    ret = _gnutls_write_general_name(c2, "?LAST.accessLocation",
2914
0
             aia->aia[i].san_type,
2915
0
             aia->aia[i].san.data,
2916
0
             aia->aia[i].san.size);
2917
0
    if (ret < 0) {
2918
0
      gnutls_assert();
2919
0
      goto cleanup;
2920
0
    }
2921
0
  }
2922
2923
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
2924
0
  if (ret < 0) {
2925
0
    gnutls_assert();
2926
0
    goto cleanup;
2927
0
  }
2928
2929
0
cleanup:
2930
0
  asn1_delete_structure(&c2);
2931
2932
0
  return ret;
2933
0
}
2934
2935
struct gnutls_x509_key_purposes_st {
2936
  gnutls_datum_t oid[MAX_ENTRIES];
2937
  unsigned int size;
2938
};
2939
2940
/**
2941
 * gnutls_subject_alt_names_init:
2942
 * @p: The key purposes
2943
 *
2944
 * This function will initialize an alternative names type.
2945
 *
2946
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2947
 *
2948
 * Since: 3.3.0
2949
 **/
2950
int gnutls_x509_key_purpose_init(gnutls_x509_key_purposes_t *p)
2951
0
{
2952
0
  *p = gnutls_calloc(1, sizeof(struct gnutls_x509_key_purposes_st));
2953
0
  if (*p == NULL) {
2954
0
    gnutls_assert();
2955
0
    return GNUTLS_E_MEMORY_ERROR;
2956
0
  }
2957
2958
0
  return 0;
2959
0
}
2960
2961
static void key_purposes_deinit(gnutls_x509_key_purposes_t p)
2962
0
{
2963
0
  unsigned int i;
2964
2965
0
  for (i = 0; i < p->size; i++) {
2966
0
    gnutls_free(p->oid[i].data);
2967
0
  }
2968
0
}
2969
2970
/**
2971
 * gnutls_x509_key_purpose_deinit:
2972
 * @p: The key purposes
2973
 *
2974
 * This function will deinitialize a key purposes type.
2975
 *
2976
 * Since: 3.3.0
2977
 **/
2978
void gnutls_x509_key_purpose_deinit(gnutls_x509_key_purposes_t p)
2979
0
{
2980
0
  key_purposes_deinit(p);
2981
0
  gnutls_free(p);
2982
0
}
2983
2984
/**
2985
 * gnutls_x509_key_purpose_set:
2986
 * @p: The key purposes
2987
 * @oid: The object identifier of the key purpose
2988
 *
2989
 * This function will store the specified key purpose in the
2990
 * purposes.
2991
 *
2992
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
2993
 *
2994
 * Since: 3.3.0
2995
 **/
2996
int gnutls_x509_key_purpose_set(gnutls_x509_key_purposes_t p, const char *oid)
2997
0
{
2998
0
  if (p->size + 1 > MAX_ENTRIES)
2999
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3000
3001
0
  p->oid[p->size].data = (void *)gnutls_strdup(oid);
3002
0
  if (p->oid[p->size].data == NULL)
3003
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3004
3005
0
  p->oid[p->size].size = strlen(oid);
3006
0
  p->size++;
3007
3008
0
  return 0;
3009
0
}
3010
3011
/**
3012
 * gnutls_x509_key_purpose_get:
3013
 * @p: The key purposes
3014
 * @idx: The index of the key purpose to retrieve
3015
 * @oid: Will hold the object identifier of the key purpose (to be treated as constant)
3016
 *
3017
 * This function will retrieve the specified by the index key purpose in the
3018
 * purposes type. The object identifier will be a null terminated string.
3019
 *
3020
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
3021
 * if the index is out of bounds, otherwise a negative error value.
3022
 *
3023
 * Since: 3.3.0
3024
 **/
3025
int gnutls_x509_key_purpose_get(gnutls_x509_key_purposes_t p, unsigned idx,
3026
        gnutls_datum_t *oid)
3027
0
{
3028
0
  if (idx >= p->size)
3029
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3030
3031
0
  oid->data = p->oid[idx].data;
3032
0
  oid->size = p->oid[idx].size;
3033
3034
0
  return 0;
3035
0
}
3036
3037
/**
3038
 * gnutls_x509_ext_import_key_purposes:
3039
 * @ext: The DER-encoded extension data
3040
 * @p: The key purposes
3041
 * @flags: should be zero
3042
 *
3043
 * This function will extract the key purposes in the provided DER-encoded
3044
 * ExtKeyUsageSyntax PKIX extension, to a %gnutls_x509_key_purposes_t type. 
3045
 * The data must be initialized.
3046
 * 
3047
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3048
 *
3049
 * Since: 3.3.0
3050
 **/
3051
int gnutls_x509_ext_import_key_purposes(const gnutls_datum_t *ext,
3052
          gnutls_x509_key_purposes_t p,
3053
          unsigned int flags)
3054
0
{
3055
0
  char tmpstr[MAX_NAME_SIZE];
3056
0
  int result, ret;
3057
0
  asn1_node c2 = NULL;
3058
0
  gnutls_datum_t oid = { NULL, 0 };
3059
0
  unsigned i;
3060
3061
0
  result = asn1_create_element(_gnutls_get_pkix(),
3062
0
             "PKIX1.ExtKeyUsageSyntax", &c2);
3063
0
  if (result != ASN1_SUCCESS) {
3064
0
    gnutls_assert();
3065
0
    return _gnutls_asn2err(result);
3066
0
  }
3067
3068
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
3069
0
  if (result != ASN1_SUCCESS) {
3070
0
    gnutls_assert();
3071
0
    ret = _gnutls_asn2err(result);
3072
0
    goto cleanup;
3073
0
  }
3074
3075
0
  key_purposes_deinit(p);
3076
0
  i = 0;
3077
0
  p->size = 0;
3078
3079
0
  for (; i < MAX_ENTRIES; i++) {
3080
    /* create a string like "?1"
3081
     */
3082
0
    snprintf(tmpstr, sizeof(tmpstr), "?%u", i + 1);
3083
3084
0
    ret = _gnutls_x509_read_value(c2, tmpstr, &oid);
3085
0
    if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
3086
0
      break;
3087
0
    }
3088
3089
0
    if (ret < 0) {
3090
0
      gnutls_assert();
3091
0
      goto cleanup;
3092
0
    }
3093
3094
0
    p->oid[i].data = oid.data;
3095
0
    p->oid[i].size = oid.size;
3096
3097
0
    oid.data = NULL;
3098
0
    oid.size = 0;
3099
0
    p->size++;
3100
0
  }
3101
3102
0
  ret = 0;
3103
0
cleanup:
3104
0
  gnutls_free(oid.data);
3105
0
  asn1_delete_structure(&c2);
3106
3107
0
  return ret;
3108
0
}
3109
3110
/**
3111
 * gnutls_x509_ext_export_key_purposes:
3112
 * @p: The key purposes
3113
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
3114
 *
3115
 * This function will convert the key purposes type to a
3116
 * DER-encoded PKIX ExtKeyUsageSyntax (2.5.29.37) extension. The output data in 
3117
 * @ext will be allocated using gnutls_malloc().
3118
 *
3119
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3120
 *
3121
 * Since: 3.3.0
3122
 **/
3123
int gnutls_x509_ext_export_key_purposes(gnutls_x509_key_purposes_t p,
3124
          gnutls_datum_t *ext)
3125
0
{
3126
0
  int result, ret;
3127
0
  asn1_node c2 = NULL;
3128
0
  unsigned i;
3129
3130
0
  result = asn1_create_element(_gnutls_get_pkix(),
3131
0
             "PKIX1.ExtKeyUsageSyntax", &c2);
3132
0
  if (result != ASN1_SUCCESS) {
3133
0
    gnutls_assert();
3134
0
    return _gnutls_asn2err(result);
3135
0
  }
3136
3137
  /* generate the extension.
3138
   */
3139
0
  for (i = 0; i < p->size; i++) {
3140
    /* 1. create a new element.
3141
     */
3142
0
    result = asn1_write_value(c2, "", "NEW", 1);
3143
0
    if (result != ASN1_SUCCESS) {
3144
0
      gnutls_assert();
3145
0
      ret = _gnutls_asn2err(result);
3146
0
      goto cleanup;
3147
0
    }
3148
3149
    /* 2. Add the OID.
3150
     */
3151
0
    result = asn1_write_value(c2, "?LAST", p->oid[i].data, 1);
3152
0
    if (result != ASN1_SUCCESS) {
3153
0
      gnutls_assert();
3154
0
      ret = _gnutls_asn2err(result);
3155
0
      goto cleanup;
3156
0
    }
3157
0
  }
3158
3159
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
3160
0
  if (ret < 0) {
3161
0
    gnutls_assert();
3162
0
    goto cleanup;
3163
0
  }
3164
3165
0
  ret = 0;
3166
3167
0
cleanup:
3168
0
  asn1_delete_structure(&c2);
3169
0
  return ret;
3170
0
}
3171
3172
/**
3173
 * gnutls_ext_deinit:
3174
 * @ext: The extensions structure
3175
 *
3176
 * This function will deinitialize an extensions structure.
3177
 *
3178
 * Since: 3.3.8
3179
 **/
3180
void gnutls_x509_ext_deinit(gnutls_x509_ext_st *ext)
3181
0
{
3182
0
  gnutls_free(ext->oid);
3183
0
  gnutls_free(ext->data.data);
3184
0
}
3185
3186
int _gnutls_x509_decode_ext(const gnutls_datum_t *der, gnutls_x509_ext_st *out)
3187
0
{
3188
0
  asn1_node c2 = NULL;
3189
0
  char str_critical[10];
3190
0
  char oid[MAX_OID_SIZE];
3191
0
  int result, len, ret;
3192
3193
0
  memset(out, 0, sizeof(*out));
3194
3195
  /* decode der */
3196
0
  result =
3197
0
    asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extension", &c2);
3198
0
  if (result != ASN1_SUCCESS) {
3199
0
    gnutls_assert();
3200
0
    return _gnutls_asn2err(result);
3201
0
  }
3202
3203
0
  result = _asn1_strict_der_decode(&c2, der->data, der->size, NULL);
3204
0
  if (result != ASN1_SUCCESS) {
3205
0
    gnutls_assert();
3206
0
    ret = _gnutls_asn2err(result);
3207
0
    goto cleanup;
3208
0
  }
3209
3210
0
  len = sizeof(oid) - 1;
3211
0
  result = asn1_read_value(c2, "extnID", oid, &len);
3212
0
  if (result != ASN1_SUCCESS) {
3213
0
    gnutls_assert();
3214
0
    ret = _gnutls_asn2err(result);
3215
0
    goto cleanup;
3216
0
  }
3217
3218
0
  len = sizeof(str_critical) - 1;
3219
0
  result = asn1_read_value(c2, "critical", str_critical, &len);
3220
0
  if (result != ASN1_SUCCESS) {
3221
0
    gnutls_assert();
3222
0
    ret = _gnutls_asn2err(result);
3223
0
    goto cleanup;
3224
0
  }
3225
3226
0
  if (str_critical[0] == 'T')
3227
0
    out->critical = 1;
3228
0
  else
3229
0
    out->critical = 0;
3230
3231
0
  ret = _gnutls_x509_read_value(c2, "extnValue", &out->data);
3232
0
  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE ||
3233
0
      ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
3234
0
    out->data.data = NULL;
3235
0
    out->data.size = 0;
3236
0
  } else if (ret < 0) {
3237
0
    gnutls_assert();
3238
0
    goto fail;
3239
0
  }
3240
3241
0
  out->oid = gnutls_strdup(oid);
3242
0
  if (out->oid == NULL) {
3243
0
    ret = GNUTLS_E_MEMORY_ERROR;
3244
0
    goto fail;
3245
0
  }
3246
3247
0
  ret = 0;
3248
0
  goto cleanup;
3249
0
fail:
3250
0
  memset(out, 0, sizeof(*out));
3251
0
cleanup:
3252
0
  asn1_delete_structure(&c2);
3253
0
  return ret;
3254
0
}
3255
3256
/* flags can be zero or GNUTLS_EXT_FLAG_APPEND
3257
 */
3258
static int parse_tlsfeatures(asn1_node c2, gnutls_x509_tlsfeatures_t f,
3259
           unsigned flags)
3260
0
{
3261
0
  char nptr[MAX_NAME_SIZE];
3262
0
  int result;
3263
0
  unsigned i, indx, j;
3264
0
  unsigned int feature;
3265
3266
0
  if (!(flags & GNUTLS_EXT_FLAG_APPEND))
3267
0
    f->size = 0;
3268
3269
0
  for (i = 1;; i++) {
3270
0
    unsigned skip = 0;
3271
0
    snprintf(nptr, sizeof(nptr), "?%u", i);
3272
3273
0
    result = _gnutls_x509_read_uint(c2, nptr, &feature);
3274
3275
0
    if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
3276
0
        result == GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
3277
0
      break;
3278
0
    } else if (result != GNUTLS_E_SUCCESS) {
3279
0
      gnutls_assert();
3280
0
      return _gnutls_asn2err(result);
3281
0
    }
3282
3283
0
    if (feature > UINT16_MAX) {
3284
0
      gnutls_assert();
3285
0
      return GNUTLS_E_CERTIFICATE_ERROR;
3286
0
    }
3287
3288
    /* skip duplicates */
3289
0
    for (j = 0; j < f->size; j++) {
3290
0
      if (f->feature[j] == feature) {
3291
0
        skip = 1;
3292
0
        break;
3293
0
      }
3294
0
    }
3295
3296
0
    if (!skip) {
3297
0
      if (f->size >=
3298
0
          sizeof(f->feature) / sizeof(f->feature[0])) {
3299
0
        gnutls_assert();
3300
0
        return GNUTLS_E_INTERNAL_ERROR;
3301
0
      }
3302
3303
0
      indx = f->size;
3304
0
      f->feature[indx] = feature;
3305
0
      f->size++;
3306
0
    }
3307
0
  }
3308
3309
0
  return 0;
3310
0
}
3311
3312
/**
3313
 * gnutls_x509_ext_import_tlsfeatures:
3314
 * @ext: The DER-encoded extension data
3315
 * @f: The features structure
3316
 * @flags: zero or %GNUTLS_EXT_FLAG_APPEND
3317
 *
3318
 * This function will export the features in the provided DER-encoded
3319
 * TLS Features PKIX extension, to a %gnutls_x509_tlsfeatures_t type. @f
3320
 * must be initialized.
3321
 *
3322
 * When the @flags is set to %GNUTLS_EXT_FLAG_APPEND,
3323
 * then if the @features structure is empty this function will behave
3324
 * identically as if the flag was not set. Otherwise if there are elements 
3325
 * in the @features structure then they will be merged with.
3326
 *
3327
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3328
 *
3329
 * Since: 3.5.1
3330
 **/
3331
int gnutls_x509_ext_import_tlsfeatures(const gnutls_datum_t *ext,
3332
               gnutls_x509_tlsfeatures_t f,
3333
               unsigned int flags)
3334
0
{
3335
0
  int ret;
3336
0
  asn1_node c2 = NULL;
3337
3338
0
  if (ext->size == 0 || ext->data == NULL) {
3339
0
    gnutls_assert();
3340
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3341
0
  }
3342
3343
0
  ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.TlsFeatures", &c2);
3344
0
  if (ret != ASN1_SUCCESS) {
3345
0
    gnutls_assert();
3346
0
    return _gnutls_asn2err(ret);
3347
0
  }
3348
3349
0
  ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
3350
0
  if (ret != ASN1_SUCCESS) {
3351
0
    gnutls_assert();
3352
0
    ret = _gnutls_asn2err(ret);
3353
0
    goto cleanup;
3354
0
  }
3355
3356
0
  ret = parse_tlsfeatures(c2, f, flags);
3357
0
  if (ret < 0) {
3358
0
    gnutls_assert();
3359
0
  }
3360
3361
0
cleanup:
3362
0
  asn1_delete_structure(&c2);
3363
3364
0
  return ret;
3365
0
}
3366
3367
/**
3368
 * gnutls_x509_ext_export_tlsfeatures:
3369
 * @f: The features structure
3370
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
3371
 *
3372
 * This function will convert the provided TLS features structure structure to a
3373
 * DER-encoded TLS features PKIX extension. The output data in @ext will be allocated using
3374
 * gnutls_malloc().
3375
 *
3376
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3377
 *
3378
 * Since: 3.5.1
3379
 **/
3380
int gnutls_x509_ext_export_tlsfeatures(gnutls_x509_tlsfeatures_t f,
3381
               gnutls_datum_t *ext)
3382
0
{
3383
0
  if (f == NULL) {
3384
0
    gnutls_assert();
3385
0
    return GNUTLS_E_INVALID_REQUEST;
3386
0
  }
3387
3388
0
  asn1_node c2 = NULL;
3389
0
  int ret;
3390
0
  unsigned i;
3391
3392
0
  ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.TlsFeatures", &c2);
3393
0
  if (ret != ASN1_SUCCESS) {
3394
0
    gnutls_assert();
3395
0
    return _gnutls_asn2err(ret);
3396
0
  }
3397
3398
0
  for (i = 0; i < f->size; ++i) {
3399
0
    ret = asn1_write_value(c2, "", "NEW", 1);
3400
0
    if (ret != ASN1_SUCCESS) {
3401
0
      gnutls_assert();
3402
0
      ret = _gnutls_asn2err(ret);
3403
0
      goto cleanup;
3404
0
    }
3405
3406
0
    ret = _gnutls_x509_write_uint32(c2, "?LAST", f->feature[i]);
3407
0
    if (ret != GNUTLS_E_SUCCESS) {
3408
0
      gnutls_assert();
3409
0
      goto cleanup;
3410
0
    }
3411
0
  }
3412
3413
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
3414
0
  if (ret < 0) {
3415
0
    gnutls_assert();
3416
0
    goto cleanup;
3417
0
  }
3418
3419
0
  ret = 0;
3420
3421
0
cleanup:
3422
0
  asn1_delete_structure(&c2);
3423
0
  return ret;
3424
0
}
3425
3426
/**
3427
 * gnutls_x509_tlsfeatures_add:
3428
 * @f: The TLS features
3429
 * @feature: The feature to add
3430
 *
3431
 * This function will append a feature to the X.509 TLS features
3432
 * extension structure.
3433
 *
3434
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
3435
 *   otherwise a negative error value.
3436
 *
3437
 * Since: 3.5.1
3438
 **/
3439
int gnutls_x509_tlsfeatures_add(gnutls_x509_tlsfeatures_t f,
3440
        unsigned int feature)
3441
0
{
3442
0
  if (f == NULL) {
3443
0
    gnutls_assert();
3444
0
    return GNUTLS_E_INVALID_REQUEST;
3445
0
  }
3446
3447
0
  if (feature > UINT16_MAX)
3448
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3449
3450
0
  if (f->size >= sizeof(f->feature) / sizeof(f->feature[0]))
3451
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
3452
3453
0
  f->feature[f->size++] = feature;
3454
3455
0
  return 0;
3456
0
}
3457
3458
0
#define SCT_V1_LOGID_SIZE 32
3459
struct ct_sct_st {
3460
  int version;
3461
  uint8_t logid[SCT_V1_LOGID_SIZE];
3462
  uint64_t timestamp;
3463
  gnutls_sign_algorithm_t sigalg;
3464
  gnutls_datum_t signature;
3465
};
3466
3467
struct gnutls_x509_ct_scts_st {
3468
  struct ct_sct_st *scts;
3469
  size_t size;
3470
};
3471
3472
static void _gnutls_free_scts(struct gnutls_x509_ct_scts_st *scts)
3473
0
{
3474
0
  for (size_t i = 0; i < scts->size; i++)
3475
0
    _gnutls_free_datum(&scts->scts[i].signature);
3476
0
  gnutls_free(scts->scts);
3477
0
  scts->size = 0;
3478
0
}
3479
3480
/**
3481
 * gnutls_x509_ext_ct_scts_init:
3482
 * @scts: The SCT list
3483
 *
3484
 * This function will initialize a Certificate Transparency SCT list.
3485
 *
3486
 * Returns: %GNUTLS_E_SUCCESS (0) on success, otherwise a negative error value.
3487
 **/
3488
int gnutls_x509_ext_ct_scts_init(gnutls_x509_ct_scts_t *scts)
3489
0
{
3490
0
  *scts = gnutls_calloc(1, sizeof(struct gnutls_x509_ct_scts_st));
3491
0
  if (*scts == NULL)
3492
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3493
0
  return 0;
3494
0
}
3495
3496
/**
3497
 * gnutls_x509_ext_ct_scts_deinit:
3498
 * @scts: The SCT list
3499
 *
3500
 * This function will deinitialize a Certificate Transparency SCT list.
3501
 **/
3502
void gnutls_x509_ext_ct_scts_deinit(gnutls_x509_ct_scts_t scts)
3503
0
{
3504
0
  _gnutls_free_scts(scts);
3505
0
  gnutls_free(scts);
3506
0
}
3507
3508
struct sct_sign_algorithm_st {
3509
  uint8_t codepoint[2];
3510
  gnutls_sign_algorithm_t sign_algo;
3511
};
3512
3513
static const struct sct_sign_algorithm_st algos[] = {
3514
  { .codepoint = { 0x01, 0x01 }, .sign_algo = GNUTLS_SIGN_RSA_MD5 },
3515
  { .codepoint = { 0x02, 0x01 }, .sign_algo = GNUTLS_SIGN_RSA_SHA1 },
3516
  { .codepoint = { 0x03, 0x01 }, .sign_algo = GNUTLS_SIGN_RSA_SHA224 },
3517
  { .codepoint = { 0x04, 0x01 }, .sign_algo = GNUTLS_SIGN_RSA_SHA256 },
3518
  { .codepoint = { 0x05, 0x01 }, .sign_algo = GNUTLS_SIGN_RSA_SHA384 },
3519
  {
3520
    .codepoint = { 0x06, 0x01 },
3521
    .sign_algo = GNUTLS_SIGN_RSA_SHA512,
3522
  },
3523
  { .codepoint = { 0x02, 0x02 }, .sign_algo = GNUTLS_SIGN_DSA_SHA1 },
3524
  { .codepoint = { 0x03, 0x02 }, .sign_algo = GNUTLS_SIGN_DSA_SHA224 },
3525
  { .codepoint = { 0x04, 0x02 }, .sign_algo = GNUTLS_SIGN_DSA_SHA256 },
3526
  { .codepoint = { 0x05, 0x02 }, .sign_algo = GNUTLS_SIGN_DSA_SHA384 },
3527
  {
3528
    .codepoint = { 0x06, 0x02 },
3529
    .sign_algo = GNUTLS_SIGN_DSA_SHA512,
3530
  },
3531
  { .codepoint = { 0x02, 0x03 }, .sign_algo = GNUTLS_SIGN_ECDSA_SHA1 },
3532
  { .codepoint = { 0x03, 0x03 }, .sign_algo = GNUTLS_SIGN_ECDSA_SHA224 },
3533
  { .codepoint = { 0x04, 0x03 }, .sign_algo = GNUTLS_SIGN_ECDSA_SHA256 },
3534
  { .codepoint = { 0x05, 0x03 }, .sign_algo = GNUTLS_SIGN_ECDSA_SHA384 },
3535
  {
3536
    .codepoint = { 0x06, 0x03 },
3537
    .sign_algo = GNUTLS_SIGN_ECDSA_SHA512,
3538
  }
3539
};
3540
3541
static gnutls_sign_algorithm_t get_sigalg(uint8_t hash_algo, uint8_t sig_algo)
3542
0
{
3543
0
  const struct sct_sign_algorithm_st *algo;
3544
0
  size_t i, num_algos = sizeof(algos) / sizeof(algos[0]);
3545
3546
0
  if (hash_algo == 0 || sig_algo == 0)
3547
0
    return GNUTLS_SIGN_UNKNOWN;
3548
3549
0
  for (i = 0; i < num_algos; i++) {
3550
0
    algo = &algos[i];
3551
0
    if (algo->codepoint[0] == hash_algo &&
3552
0
        algo->codepoint[1] == sig_algo)
3553
0
      break;
3554
0
  }
3555
3556
0
  if (i == num_algos)
3557
0
    return GNUTLS_SIGN_UNKNOWN;
3558
3559
0
  return algo->sign_algo;
3560
0
}
3561
3562
static int write_sigalg(gnutls_sign_algorithm_t sigalg, uint8_t out[])
3563
0
{
3564
0
  const struct sct_sign_algorithm_st *algo;
3565
0
  size_t i, num_algos = sizeof(algos) / sizeof(algos[0]);
3566
3567
0
  for (i = 0; i < num_algos; i++) {
3568
0
    algo = &algos[i];
3569
0
    if (algo->sign_algo == sigalg)
3570
0
      break;
3571
0
  }
3572
3573
0
  if (i == num_algos)
3574
0
    return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
3575
3576
0
  out[0] = algo->codepoint[0];
3577
0
  out[1] = algo->codepoint[1];
3578
0
  return 0;
3579
0
}
3580
3581
static int _gnutls_parse_ct_sct(uint8_t *ptr, uint16_t length,
3582
        struct ct_sct_st *sct)
3583
0
{
3584
0
  uint16_t sig_length;
3585
0
  uint8_t hash_algo, sig_algo;
3586
3587
0
  sct->signature.size = 0;
3588
0
  sct->signature.data = NULL;
3589
3590
0
  DECR_LENGTH_RET(length, 1, GNUTLS_E_PREMATURE_TERMINATION);
3591
0
  sct->version = (int)*ptr;
3592
0
  ptr++;
3593
3594
  /* LogID
3595
   * In version 1, it has a fixed length of 32 bytes.
3596
   */
3597
0
  DECR_LENGTH_RET(length, SCT_V1_LOGID_SIZE,
3598
0
      GNUTLS_E_PREMATURE_TERMINATION);
3599
0
  memcpy(sct->logid, ptr, SCT_V1_LOGID_SIZE);
3600
0
  ptr += SCT_V1_LOGID_SIZE;
3601
3602
  /* Timestamp */
3603
0
  DECR_LENGTH_RET(length, sizeof(uint64_t),
3604
0
      GNUTLS_E_PREMATURE_TERMINATION);
3605
0
  sct->timestamp = (uint64_t)_gnutls_read_uint64(ptr);
3606
0
  ptr += sizeof(uint64_t);
3607
3608
  /*
3609
   * There are no extensions defined in SCT v1.
3610
   * Check that there are actually no extensions - the following two bytes should be zero.
3611
   */
3612
0
  DECR_LENGTH_RET(length, 2, GNUTLS_E_PREMATURE_TERMINATION);
3613
0
  if (*ptr != 0 || *(ptr + 1) != 0)
3614
0
    return gnutls_assert_val(GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
3615
0
  ptr += 2;
3616
3617
  /*
3618
   * Hash and signature algorithms, modeled after
3619
   * SignatureAndHashAlgorithm structure, as defined in
3620
   * RFC 5246, section 7.4.1.4.1.
3621
   * We take both values separately (hash and signature),
3622
   * and return them as a gnutls_sign_algorithm_t enum value.
3623
   */
3624
0
  DECR_LENGTH_RET(length, 2, GNUTLS_E_PREMATURE_TERMINATION);
3625
0
  hash_algo = *ptr++;
3626
0
  sig_algo = *ptr++;
3627
3628
0
  sct->sigalg = get_sigalg(hash_algo, sig_algo);
3629
0
  if (sct->sigalg == GNUTLS_SIGN_UNKNOWN)
3630
0
    return gnutls_assert_val(
3631
0
      GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
3632
3633
  /* Signature, length and content */
3634
0
  DECR_LENGTH_RET(length, sizeof(uint16_t),
3635
0
      GNUTLS_E_PREMATURE_TERMINATION);
3636
0
  sig_length = _gnutls_read_uint16(ptr);
3637
0
  ptr += sizeof(uint16_t);
3638
0
  if (sig_length == 0)
3639
0
    return gnutls_assert_val(GNUTLS_E_PREMATURE_TERMINATION);
3640
3641
  /* Remaining length should be sig_length at this point.
3642
   * If not, that means there is more data than what the length field said it was,
3643
   * and hence we must treat this as an error. */
3644
0
  if (length != sig_length)
3645
0
    return gnutls_assert_val(GNUTLS_E_ASN1_DER_OVERFLOW);
3646
3647
0
  if (_gnutls_set_datum(&sct->signature, ptr, sig_length) < 0)
3648
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3649
3650
0
  return 0;
3651
0
}
3652
3653
static int _gnutls_ct_sct_add(struct ct_sct_st *sct, struct ct_sct_st **scts,
3654
            size_t *size)
3655
0
{
3656
0
  struct ct_sct_st *new_scts;
3657
3658
0
  new_scts = _gnutls_reallocarray(*scts, *size + 1,
3659
0
          sizeof(struct ct_sct_st));
3660
0
  if (new_scts == NULL)
3661
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3662
3663
0
  memcpy(&new_scts[*size], sct, sizeof(struct ct_sct_st));
3664
0
  (*size)++;
3665
0
  *scts = new_scts;
3666
3667
0
  return 0;
3668
0
}
3669
3670
static int _gnutls_export_ct_v1_sct(gnutls_buffer_st *buf,
3671
            const struct ct_sct_st *sct)
3672
0
{
3673
0
  int ret;
3674
0
  uint8_t tstamp_out[8], sigalg[2];
3675
  /* There are no extensions defined for v1 */
3676
0
  const uint8_t extensions[2] = { 0x00, 0x00 };
3677
0
  size_t length_offset;
3678
3679
  /* Length field; filled later */
3680
0
  length_offset = buf->length;
3681
0
  if ((ret = _gnutls_buffer_append_prefix(buf, 16, 0)) < 0)
3682
0
    return gnutls_assert_val(ret);
3683
3684
  /* Version */
3685
0
  if ((ret = _gnutls_buffer_append_data(buf, &sct->version,
3686
0
                sizeof(uint8_t))) < 0)
3687
0
    return gnutls_assert_val(ret);
3688
3689
  /* Log ID - has a fixed 32-byte size in version 1 */
3690
0
  if ((ret = _gnutls_buffer_append_data(buf, sct->logid,
3691
0
                SCT_V1_LOGID_SIZE)) < 0)
3692
0
    return gnutls_assert_val(ret);
3693
3694
  /* Timestamp */
3695
0
  _gnutls_write_uint64(sct->timestamp, tstamp_out);
3696
0
  if ((ret = _gnutls_buffer_append_data(buf, tstamp_out,
3697
0
                sizeof(tstamp_out))) < 0)
3698
0
    return gnutls_assert_val(ret);
3699
3700
  /* Extensions */
3701
0
  if ((ret = _gnutls_buffer_append_data(buf, extensions,
3702
0
                sizeof(extensions))) < 0)
3703
0
    return gnutls_assert_val(ret);
3704
3705
  /* Hash and signature algorithms */
3706
0
  if ((ret = write_sigalg(sct->sigalg, sigalg)) < 0)
3707
0
    return gnutls_assert_val(ret);
3708
3709
0
  if ((ret = _gnutls_buffer_append_data(buf, sigalg, sizeof(sigalg))) < 0)
3710
0
    return gnutls_assert_val(ret);
3711
3712
  /* Signature */
3713
0
  if ((ret = _gnutls_buffer_append_data_prefix(
3714
0
         buf, 16, sct->signature.data, sct->signature.size)) < 0)
3715
0
    return gnutls_assert_val(ret);
3716
3717
  /* Fill the length */
3718
0
  _gnutls_write_uint16(buf->length - length_offset - 2,
3719
0
           buf->data + length_offset);
3720
3721
0
  return 0;
3722
0
}
3723
3724
/**
3725
 * gnutls_x509_ext_ct_import_scts:
3726
 * @ext: a DER-encoded extension
3727
 * @scts: The SCT list
3728
 * @flags: should be zero
3729
 *
3730
 * This function will read a SignedCertificateTimestampList structure
3731
 * from the DER data of the X.509 Certificate Transparency SCT extension
3732
 * (OID 1.3.6.1.4.1.11129.2.4.2).
3733
 *
3734
 * The list of SCTs (Signed Certificate Timestamps) is placed on @scts,
3735
 * which must be previously initialized with gnutls_x509_ext_ct_scts_init().
3736
 *
3737
 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error value.
3738
 **/
3739
int gnutls_x509_ext_ct_import_scts(const gnutls_datum_t *ext,
3740
           gnutls_x509_ct_scts_t scts,
3741
           unsigned int flags)
3742
0
{
3743
0
  int retval;
3744
0
  uint8_t *ptr;
3745
0
  uint16_t length, sct_length;
3746
0
  struct ct_sct_st sct;
3747
0
  gnutls_datum_t scts_content;
3748
3749
0
  if (flags != 0)
3750
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
3751
3752
0
  retval = _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING, ext->data,
3753
0
              ext->size, &scts_content, 0);
3754
0
  if (retval < 0)
3755
0
    return gnutls_assert_val(retval);
3756
3757
0
  if (scts_content.size < 2) {
3758
0
    gnutls_free(scts_content.data);
3759
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3760
0
  }
3761
3762
0
  length = _gnutls_read_uint16(scts_content.data);
3763
0
  if (length < 4 || length > scts_content.size) {
3764
0
    gnutls_free(scts_content.data);
3765
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3766
0
  }
3767
3768
0
  ptr = &scts_content.data[2];
3769
0
  while (length > 0) {
3770
0
    if (length < 2)
3771
0
      break;
3772
3773
0
    sct_length = _gnutls_read_uint16(ptr);
3774
0
    if (sct_length == 0 || sct_length > length)
3775
0
      break;
3776
3777
0
    ptr += sizeof(uint16_t);
3778
0
    length -= sizeof(uint16_t);
3779
3780
    /*
3781
     * _gnutls_parse_ct_sct() will try to read exactly sct_length bytes,
3782
     * returning an error if it can't
3783
     */
3784
0
    if (_gnutls_parse_ct_sct(ptr, sct_length, &sct) < 0)
3785
0
      break;
3786
0
    if (_gnutls_ct_sct_add(&sct, &scts->scts, &scts->size) < 0)
3787
0
      break;
3788
3789
0
    ptr += sct_length;
3790
0
    length -= sct_length;
3791
0
  }
3792
3793
0
  _gnutls_free_datum(&scts_content);
3794
3795
0
  if (length > 0) {
3796
0
    gnutls_assert();
3797
0
    _gnutls_free_scts(scts);
3798
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3799
0
  }
3800
3801
0
  return GNUTLS_E_SUCCESS;
3802
0
}
3803
3804
/**
3805
 * gnutls_x509_ext_ct_export_scts:
3806
 * @scts: An initialized SCT list
3807
 * @ext: The DER-encoded extension data; must be freed with gnutls_free()
3808
 *
3809
 * This function will convert the provided list of SCTs to a DER-encoded
3810
 * SignedCertificateTimestampList extension (1.3.6.1.4.1.11129.2.4.2).
3811
 * The output data in @ext will be allocated using gnutls_malloc().
3812
 *
3813
 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error value.
3814
 **/
3815
int gnutls_x509_ext_ct_export_scts(const gnutls_x509_ct_scts_t scts,
3816
           gnutls_datum_t *ext)
3817
0
{
3818
0
  int ret;
3819
0
  gnutls_buffer_st buf;
3820
3821
0
  _gnutls_buffer_init(&buf);
3822
3823
  /* Start with the length of the whole string; the actual
3824
   * length is filled later */
3825
0
  _gnutls_buffer_append_prefix(&buf, 16, 0);
3826
3827
0
  for (size_t i = 0; i < scts->size; i++) {
3828
0
    if ((ret = _gnutls_export_ct_v1_sct(&buf, &scts->scts[i])) <
3829
0
        0) {
3830
0
      gnutls_assert();
3831
0
      goto cleanup;
3832
0
    }
3833
0
  }
3834
3835
  /* Fill the length */
3836
0
  _gnutls_write_uint16(buf.length - 2, buf.data);
3837
3838
  /* DER-encode the whole thing as an opaque OCTET STRING, as the spec mandates */
3839
0
  ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING, buf.data,
3840
0
           buf.length, ext);
3841
0
  if (ret < 0) {
3842
0
    gnutls_assert();
3843
0
    goto cleanup;
3844
0
  }
3845
3846
0
  ret = GNUTLS_E_SUCCESS;
3847
3848
0
cleanup:
3849
0
  _gnutls_buffer_clear(&buf);
3850
0
  return ret;
3851
0
}
3852
3853
/**
3854
 * gnutls_x509_ct_sct_get_version:
3855
 * @scts: A list of SCTs
3856
 * @idx: The index of the target SCT in the list
3857
 * @version_out: The version of the target SCT.
3858
 *
3859
 * This function obtains the version of the SCT at the given position
3860
 * in the SCT list.
3861
 *
3862
 * The version of that SCT will be placed on @version_out.
3863
 *
3864
 * Return : %GNUTLS_E_SUCCESS (0) is returned on success,
3865
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if @idx exceeds the number of SCTs in the list
3866
 *   and %GNUTLS_E_INVALID_REQUEST if the SCT's version is different than 1, as that's currently
3867
 *   the only defined version.
3868
 **/
3869
int gnutls_x509_ct_sct_get_version(gnutls_x509_ct_scts_t scts, unsigned idx,
3870
           unsigned int *version_out)
3871
0
{
3872
0
  int version;
3873
3874
0
  if (idx >= scts->size)
3875
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3876
3877
  /*
3878
   * Currently, only version 1 SCTs are defined (RFC 6962).
3879
   * A version 1 SCT has actually the value 0 in the 'version' field.
3880
   */
3881
0
  version = scts->scts[idx].version;
3882
0
  if (version != 0 || version_out == NULL)
3883
0
    return GNUTLS_E_INVALID_REQUEST;
3884
3885
0
  *version_out = 1;
3886
0
  return GNUTLS_E_SUCCESS;
3887
0
}
3888
3889
/**
3890
 * gnutls_x509_ct_sct_get:
3891
 * @scts: A list of SCTs
3892
 * @idx: The index of the target SCT in the list
3893
 * @timestamp: The timestamp of the SCT
3894
 * @logid: The LogID field of the SCT; must be freed with gnutls_free()
3895
 * @sigalg: The signature algorithm
3896
 * @signature: The signature of the SCT; must be freed with gnutls_free()
3897
 *
3898
 * This function will return a specific SCT (Signed Certificate Timestamp)
3899
 * stored in the SCT list @scts.
3900
 *
3901
 * The datums holding the SCT's LogId and signature will be allocated
3902
 * using gnutls_malloc().
3903
 *
3904
 * Returns: %GNUTLS_E_SUCCESS (0) will be returned on success,
3905
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if @idx exceeds the number of SCTs in the list
3906
 * or a negative error value.
3907
 **/
3908
int gnutls_x509_ct_sct_get(const gnutls_x509_ct_scts_t scts, unsigned idx,
3909
         time_t *timestamp, gnutls_datum_t *logid,
3910
         gnutls_sign_algorithm_t *sigalg,
3911
         gnutls_datum_t *signature)
3912
0
{
3913
0
  int retval = 0;
3914
0
  struct ct_sct_st *sct;
3915
3916
0
  if (idx >= scts->size)
3917
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3918
3919
0
  sct = &scts->scts[idx];
3920
0
  if (sct->version != 0)
3921
0
    return GNUTLS_E_INVALID_REQUEST;
3922
3923
0
  if (signature) {
3924
0
    retval = _gnutls_set_datum(signature, sct->signature.data,
3925
0
             sct->signature.size);
3926
0
    if (retval < 0)
3927
0
      return retval;
3928
0
  }
3929
3930
0
  if (logid) {
3931
0
    retval =
3932
0
      _gnutls_set_datum(logid, sct->logid, SCT_V1_LOGID_SIZE);
3933
0
    if (retval < 0) {
3934
0
      _gnutls_free_datum(signature);
3935
0
      return retval;
3936
0
    }
3937
0
  }
3938
3939
0
  if (timestamp)
3940
0
    *timestamp = sct->timestamp / 1000;
3941
3942
0
  if (sigalg)
3943
0
    *sigalg = sct->sigalg;
3944
3945
0
  return GNUTLS_E_SUCCESS;
3946
0
}