Coverage Report

Created: 2026-09-28 07:30

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