Coverage Report

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