Coverage Report

Created: 2026-03-31 07:46

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