Coverage Report

Created: 2025-03-06 07:58

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